Commit 8db14860 authored by Nicolas Iooss's avatar Nicolas Iooss Committed by Linus Torvalds

include, lib: add __printf attributes to several function prototypes

Using __printf attributes helps to detect several format string issues
at compile time (even though -Wformat-security is currently disabled in
Makefile).  For example it can detect when formatting a pointer as a
number, like the issue fixed in commit a3fa71c4 ("wl18xx: show
rx_frames_per_rates as an array as it really is"), or when the arguments
do not match the format string, c.f.  for example commit 5ce1aca8
("reiserfs: fix __RASSERT format string").

To prevent similar bugs in the future, add a __printf attribute to every
function prototype which needs one in include/linux/ and lib/.  These
functions were mostly found by using gcc's -Wsuggest-attribute=format
flag.
Signed-off-by: default avatarNicolas Iooss <nicolas.iooss_linux@m4x.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 7f9be775
...@@ -33,18 +33,19 @@ struct clk_lookup { ...@@ -33,18 +33,19 @@ struct clk_lookup {
} }
struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
const char *dev_fmt, ...); const char *dev_fmt, ...) __printf(3, 4);
void clkdev_add(struct clk_lookup *cl); void clkdev_add(struct clk_lookup *cl);
void clkdev_drop(struct clk_lookup *cl); void clkdev_drop(struct clk_lookup *cl);
struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id, struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id,
const char *dev_fmt, ...); const char *dev_fmt, ...) __printf(3, 4);
void clkdev_add_table(struct clk_lookup *, size_t); void clkdev_add_table(struct clk_lookup *, size_t);
int clk_add_alias(const char *, const char *, const char *, struct device *); int clk_add_alias(const char *, const char *, const char *, struct device *);
int clk_register_clkdev(struct clk *, const char *, const char *, ...); int clk_register_clkdev(struct clk *, const char *, const char *, ...)
__printf(3, 4);
int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t); int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
#ifdef CONFIG_COMMON_CLK #ifdef CONFIG_COMMON_CLK
......
...@@ -424,7 +424,7 @@ asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, ...@@ -424,7 +424,7 @@ asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
extern int compat_printk(const char *fmt, ...); extern __printf(1, 2) int compat_printk(const char *fmt, ...);
extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat); extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat);
extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set); extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set);
......
...@@ -64,7 +64,8 @@ struct config_item { ...@@ -64,7 +64,8 @@ struct config_item {
struct dentry *ci_dentry; struct dentry *ci_dentry;
}; };
extern int config_item_set_name(struct config_item *, const char *, ...); extern __printf(2, 3)
int config_item_set_name(struct config_item *, const char *, ...);
static inline char *config_item_name(struct config_item * item) static inline char *config_item_name(struct config_item * item)
{ {
......
...@@ -40,7 +40,8 @@ extern void cpu_remove_dev_attr(struct device_attribute *attr); ...@@ -40,7 +40,8 @@ extern void cpu_remove_dev_attr(struct device_attribute *attr);
extern int cpu_add_dev_attr_group(struct attribute_group *attrs); extern int cpu_add_dev_attr_group(struct attribute_group *attrs);
extern void cpu_remove_dev_attr_group(struct attribute_group *attrs); extern void cpu_remove_dev_attr_group(struct attribute_group *attrs);
extern struct device *cpu_device_create(struct device *parent, void *drvdata, extern __printf(4, 5)
struct device *cpu_device_create(struct device *parent, void *drvdata,
const struct attribute_group **groups, const struct attribute_group **groups,
const char *fmt, ...); const char *fmt, ...);
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
......
...@@ -327,7 +327,8 @@ static inline unsigned d_count(const struct dentry *dentry) ...@@ -327,7 +327,8 @@ static inline unsigned d_count(const struct dentry *dentry)
/* /*
* helper function for dentry_operations.d_dname() members * helper function for dentry_operations.d_dname() members
*/ */
extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); extern __printf(4, 5)
char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
extern char *simple_dname(struct dentry *, char *, int); extern char *simple_dname(struct dentry *, char *, int);
extern char *__d_path(const struct path *, const struct path *, char *, int); extern char *__d_path(const struct path *, const struct path *, char *, int);
......
...@@ -637,7 +637,8 @@ extern int devres_release_group(struct device *dev, void *id); ...@@ -637,7 +637,8 @@ extern int devres_release_group(struct device *dev, void *id);
/* managed devm_k.alloc/kfree for device drivers */ /* managed devm_k.alloc/kfree for device drivers */
extern void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp); extern void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp);
extern char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt, extern __printf(3, 0)
char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt,
va_list ap); va_list ap);
extern __printf(3, 4) extern __printf(3, 4)
char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...); char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...);
...@@ -1011,12 +1012,10 @@ extern int __must_check device_reprobe(struct device *dev); ...@@ -1011,12 +1012,10 @@ extern int __must_check device_reprobe(struct device *dev);
/* /*
* Easy functions for dynamically creating devices on the fly * Easy functions for dynamically creating devices on the fly
*/ */
extern struct device *device_create_vargs(struct class *cls, extern __printf(5, 0)
struct device *parent, struct device *device_create_vargs(struct class *cls, struct device *parent,
dev_t devt, dev_t devt, void *drvdata,
void *drvdata, const char *fmt, va_list vargs);
const char *fmt,
va_list vargs);
extern __printf(5, 6) extern __printf(5, 6)
struct device *device_create(struct class *cls, struct device *parent, struct device *device_create(struct class *cls, struct device *parent,
dev_t devt, void *drvdata, dev_t devt, void *drvdata,
......
...@@ -258,7 +258,7 @@ extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr, ...@@ -258,7 +258,7 @@ extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr,
void *data); void *data);
struct device *iommu_device_create(struct device *parent, void *drvdata, struct device *iommu_device_create(struct device *parent, void *drvdata,
const struct attribute_group **groups, const struct attribute_group **groups,
const char *fmt, ...); const char *fmt, ...) __printf(4, 5);
void iommu_device_destroy(struct device *dev); void iommu_device_destroy(struct device *dev);
int iommu_device_link(struct device *dev, struct device *link); int iommu_device_link(struct device *dev, struct device *link);
void iommu_device_unlink(struct device *dev, struct device *link); void iommu_device_unlink(struct device *dev, struct device *link);
......
...@@ -411,7 +411,8 @@ extern __printf(3, 0) ...@@ -411,7 +411,8 @@ extern __printf(3, 0)
int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
extern __printf(2, 3) extern __printf(2, 3)
char *kasprintf(gfp_t gfp, const char *fmt, ...); char *kasprintf(gfp_t gfp, const char *fmt, ...);
extern char *kvasprintf(gfp_t gfp, const char *fmt, va_list args); extern __printf(2, 0)
char *kvasprintf(gfp_t gfp, const char *fmt, va_list args);
extern __scanf(2, 3) extern __scanf(2, 3)
int sscanf(const char *, const char *, ...); int sscanf(const char *, const char *, ...);
...@@ -679,10 +680,10 @@ do { \ ...@@ -679,10 +680,10 @@ do { \
__ftrace_vprintk(_THIS_IP_, fmt, vargs); \ __ftrace_vprintk(_THIS_IP_, fmt, vargs); \
} while (0) } while (0)
extern int extern __printf(2, 0) int
__ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap); __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap);
extern int extern __printf(2, 0) int
__ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap); __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);
extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode); extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode);
...@@ -702,7 +703,7 @@ int trace_printk(const char *fmt, ...) ...@@ -702,7 +703,7 @@ int trace_printk(const char *fmt, ...)
{ {
return 0; return 0;
} }
static inline int static __printf(1, 0) inline int
ftrace_vprintk(const char *fmt, va_list ap) ftrace_vprintk(const char *fmt, va_list ap)
{ {
return 0; return 0;
......
...@@ -80,7 +80,8 @@ struct kobject { ...@@ -80,7 +80,8 @@ struct kobject {
extern __printf(2, 3) extern __printf(2, 3)
int kobject_set_name(struct kobject *kobj, const char *name, ...); int kobject_set_name(struct kobject *kobj, const char *name, ...);
extern int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, extern __printf(2, 0)
int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
va_list vargs); va_list vargs);
static inline const char *kobject_name(const struct kobject *kobj) static inline const char *kobject_name(const struct kobject *kobj)
......
...@@ -106,6 +106,6 @@ extern void enable_mmiotrace(void); ...@@ -106,6 +106,6 @@ extern void enable_mmiotrace(void);
extern void disable_mmiotrace(void); extern void disable_mmiotrace(void);
extern void mmio_trace_rw(struct mmiotrace_rw *rw); extern void mmio_trace_rw(struct mmiotrace_rw *rw);
extern void mmio_trace_mapping(struct mmiotrace_map *map); extern void mmio_trace_mapping(struct mmiotrace_map *map);
extern int mmio_trace_printk(const char *fmt, va_list args); extern __printf(1, 0) int mmio_trace_printk(const char *fmt, va_list args);
#endif /* _LINUX_MMIOTRACE_H */ #endif /* _LINUX_MMIOTRACE_H */
...@@ -122,7 +122,7 @@ static inline __printf(1, 2) __cold ...@@ -122,7 +122,7 @@ static inline __printf(1, 2) __cold
void early_printk(const char *s, ...) { } void early_printk(const char *s, ...) { }
#endif #endif
typedef int(*printk_func_t)(const char *fmt, va_list args); typedef __printf(1, 0) int (*printk_func_t)(const char *fmt, va_list args);
#ifdef CONFIG_PRINTK #ifdef CONFIG_PRINTK
asmlinkage __printf(5, 0) asmlinkage __printf(5, 0)
...@@ -166,7 +166,7 @@ char *log_buf_addr_get(void); ...@@ -166,7 +166,7 @@ char *log_buf_addr_get(void);
u32 log_buf_len_get(void); u32 log_buf_len_get(void);
void log_buf_kexec_setup(void); void log_buf_kexec_setup(void);
void __init setup_log_buf(int early); void __init setup_log_buf(int early);
void dump_stack_set_arch_desc(const char *fmt, ...); __printf(1, 2) void dump_stack_set_arch_desc(const char *fmt, ...);
void dump_stack_print_info(const char *log_lvl); void dump_stack_print_info(const char *log_lvl);
void show_regs_print_info(const char *log_lvl); void show_regs_print_info(const char *log_lvl);
#else #else
...@@ -217,7 +217,7 @@ static inline void setup_log_buf(int early) ...@@ -217,7 +217,7 @@ static inline void setup_log_buf(int early)
{ {
} }
static inline void dump_stack_set_arch_desc(const char *fmt, ...) static inline __printf(1, 2) void dump_stack_set_arch_desc(const char *fmt, ...)
{ {
} }
......
...@@ -337,7 +337,8 @@ void kobject_init(struct kobject *kobj, struct kobj_type *ktype) ...@@ -337,7 +337,8 @@ void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
} }
EXPORT_SYMBOL(kobject_init); EXPORT_SYMBOL(kobject_init);
static int kobject_add_varg(struct kobject *kobj, struct kobject *parent, static __printf(3, 0) int kobject_add_varg(struct kobject *kobj,
struct kobject *parent,
const char *fmt, va_list vargs) const char *fmt, va_list vargs)
{ {
int retval; int retval;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment