diff options
author | Nicolas Iooss <nicolas.iooss_linux@m4x.org> | 2015-07-17 19:23:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-07-17 19:39:53 -0400 |
commit | 8db1486065141e619e4855b84e350ef32064f7e1 (patch) | |
tree | 438cace62ece1251656b38fbf428cf5aa5184fb8 | |
parent | 7f9be77555bb2e52de84e9dddf7b4eb20cc6e171 (diff) |
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 a3fa71c40f18 ("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 5ce1aca81435
("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: Nicolas 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/linux/clkdev.h | 7 | ||||
-rw-r--r-- | include/linux/compat.h | 2 | ||||
-rw-r--r-- | include/linux/configfs.h | 3 | ||||
-rw-r--r-- | include/linux/cpu.h | 7 | ||||
-rw-r--r-- | include/linux/dcache.h | 3 | ||||
-rw-r--r-- | include/linux/device.h | 15 | ||||
-rw-r--r-- | include/linux/iommu.h | 2 | ||||
-rw-r--r-- | include/linux/kernel.h | 9 | ||||
-rw-r--r-- | include/linux/kobject.h | 5 | ||||
-rw-r--r-- | include/linux/mmiotrace.h | 2 | ||||
-rw-r--r-- | include/linux/printk.h | 6 | ||||
-rw-r--r-- | lib/kobject.c | 5 |
12 files changed, 36 insertions, 30 deletions
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h index a240b18e86fa..08bffcc466de 100644 --- a/include/linux/clkdev.h +++ b/include/linux/clkdev.h | |||
@@ -33,18 +33,19 @@ struct clk_lookup { | |||
33 | } | 33 | } |
34 | 34 | ||
35 | struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, | 35 | struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, |
36 | const char *dev_fmt, ...); | 36 | const char *dev_fmt, ...) __printf(3, 4); |
37 | 37 | ||
38 | void clkdev_add(struct clk_lookup *cl); | 38 | void clkdev_add(struct clk_lookup *cl); |
39 | void clkdev_drop(struct clk_lookup *cl); | 39 | void clkdev_drop(struct clk_lookup *cl); |
40 | 40 | ||
41 | struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id, | 41 | struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id, |
42 | const char *dev_fmt, ...); | 42 | const char *dev_fmt, ...) __printf(3, 4); |
43 | 43 | ||
44 | void clkdev_add_table(struct clk_lookup *, size_t); | 44 | void clkdev_add_table(struct clk_lookup *, size_t); |
45 | int clk_add_alias(const char *, const char *, const char *, struct device *); | 45 | int clk_add_alias(const char *, const char *, const char *, struct device *); |
46 | 46 | ||
47 | int clk_register_clkdev(struct clk *, const char *, const char *, ...); | 47 | int clk_register_clkdev(struct clk *, const char *, const char *, ...) |
48 | __printf(3, 4); | ||
48 | int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t); | 49 | int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t); |
49 | 50 | ||
50 | #ifdef CONFIG_COMMON_CLK | 51 | #ifdef CONFIG_COMMON_CLK |
diff --git a/include/linux/compat.h b/include/linux/compat.h index ab25814690bc..a76c9172b2eb 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
@@ -424,7 +424,7 @@ asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, | |||
424 | 424 | ||
425 | asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); | 425 | asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); |
426 | 426 | ||
427 | extern int compat_printk(const char *fmt, ...); | 427 | extern __printf(1, 2) int compat_printk(const char *fmt, ...); |
428 | extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat); | 428 | extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat); |
429 | extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set); | 429 | extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set); |
430 | 430 | ||
diff --git a/include/linux/configfs.h b/include/linux/configfs.h index c9e5c57e4edf..63a36e89d0eb 100644 --- a/include/linux/configfs.h +++ b/include/linux/configfs.h | |||
@@ -64,7 +64,8 @@ struct config_item { | |||
64 | struct dentry *ci_dentry; | 64 | struct dentry *ci_dentry; |
65 | }; | 65 | }; |
66 | 66 | ||
67 | extern int config_item_set_name(struct config_item *, const char *, ...); | 67 | extern __printf(2, 3) |
68 | int config_item_set_name(struct config_item *, const char *, ...); | ||
68 | 69 | ||
69 | static inline char *config_item_name(struct config_item * item) | 70 | static inline char *config_item_name(struct config_item * item) |
70 | { | 71 | { |
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index c0fb6b1b4712..23c30bdcca86 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h | |||
@@ -40,9 +40,10 @@ extern void cpu_remove_dev_attr(struct device_attribute *attr); | |||
40 | extern int cpu_add_dev_attr_group(struct attribute_group *attrs); | 40 | extern int cpu_add_dev_attr_group(struct attribute_group *attrs); |
41 | extern void cpu_remove_dev_attr_group(struct attribute_group *attrs); | 41 | extern void cpu_remove_dev_attr_group(struct attribute_group *attrs); |
42 | 42 | ||
43 | extern struct device *cpu_device_create(struct device *parent, void *drvdata, | 43 | extern __printf(4, 5) |
44 | const struct attribute_group **groups, | 44 | struct device *cpu_device_create(struct device *parent, void *drvdata, |
45 | const char *fmt, ...); | 45 | const struct attribute_group **groups, |
46 | const char *fmt, ...); | ||
46 | #ifdef CONFIG_HOTPLUG_CPU | 47 | #ifdef CONFIG_HOTPLUG_CPU |
47 | extern void unregister_cpu(struct cpu *cpu); | 48 | extern void unregister_cpu(struct cpu *cpu); |
48 | extern ssize_t arch_cpu_probe(const char *, size_t); | 49 | extern ssize_t arch_cpu_probe(const char *, size_t); |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index d2d50249b7b2..d67ae119cf4e 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -327,7 +327,8 @@ static inline unsigned d_count(const struct dentry *dentry) | |||
327 | /* | 327 | /* |
328 | * helper function for dentry_operations.d_dname() members | 328 | * helper function for dentry_operations.d_dname() members |
329 | */ | 329 | */ |
330 | extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); | 330 | extern __printf(4, 5) |
331 | char *dynamic_dname(struct dentry *, char *, int, const char *, ...); | ||
331 | extern char *simple_dname(struct dentry *, char *, int); | 332 | extern char *simple_dname(struct dentry *, char *, int); |
332 | 333 | ||
333 | extern char *__d_path(const struct path *, const struct path *, char *, int); | 334 | extern char *__d_path(const struct path *, const struct path *, char *, int); |
diff --git a/include/linux/device.h b/include/linux/device.h index 5a31bf3a4024..a2b4ea70a946 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -637,8 +637,9 @@ extern int devres_release_group(struct device *dev, void *id); | |||
637 | 637 | ||
638 | /* managed devm_k.alloc/kfree for device drivers */ | 638 | /* managed devm_k.alloc/kfree for device drivers */ |
639 | extern void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp); | 639 | extern void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp); |
640 | extern char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt, | 640 | extern __printf(3, 0) |
641 | va_list ap); | 641 | char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt, |
642 | va_list ap); | ||
642 | extern __printf(3, 4) | 643 | extern __printf(3, 4) |
643 | char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...); | 644 | char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...); |
644 | static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp) | 645 | static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp) |
@@ -1011,12 +1012,10 @@ extern int __must_check device_reprobe(struct device *dev); | |||
1011 | /* | 1012 | /* |
1012 | * Easy functions for dynamically creating devices on the fly | 1013 | * Easy functions for dynamically creating devices on the fly |
1013 | */ | 1014 | */ |
1014 | extern struct device *device_create_vargs(struct class *cls, | 1015 | extern __printf(5, 0) |
1015 | struct device *parent, | 1016 | struct device *device_create_vargs(struct class *cls, struct device *parent, |
1016 | dev_t devt, | 1017 | dev_t devt, void *drvdata, |
1017 | void *drvdata, | 1018 | const char *fmt, va_list vargs); |
1018 | const char *fmt, | ||
1019 | va_list vargs); | ||
1020 | extern __printf(5, 6) | 1019 | extern __printf(5, 6) |
1021 | struct device *device_create(struct class *cls, struct device *parent, | 1020 | struct device *device_create(struct class *cls, struct device *parent, |
1022 | dev_t devt, void *drvdata, | 1021 | dev_t devt, void *drvdata, |
diff --git a/include/linux/iommu.h b/include/linux/iommu.h index dc767f7c3704..f9c1b6d0f2e4 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h | |||
@@ -258,7 +258,7 @@ extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr, | |||
258 | void *data); | 258 | void *data); |
259 | struct device *iommu_device_create(struct device *parent, void *drvdata, | 259 | struct device *iommu_device_create(struct device *parent, void *drvdata, |
260 | const struct attribute_group **groups, | 260 | const struct attribute_group **groups, |
261 | const char *fmt, ...); | 261 | const char *fmt, ...) __printf(4, 5); |
262 | void iommu_device_destroy(struct device *dev); | 262 | void iommu_device_destroy(struct device *dev); |
263 | int iommu_device_link(struct device *dev, struct device *link); | 263 | int iommu_device_link(struct device *dev, struct device *link); |
264 | void iommu_device_unlink(struct device *dev, struct device *link); | 264 | void iommu_device_unlink(struct device *dev, struct device *link); |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 5f0be58640ea..5582410727cb 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -411,7 +411,8 @@ extern __printf(3, 0) | |||
411 | int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); | 411 | int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); |
412 | extern __printf(2, 3) | 412 | extern __printf(2, 3) |
413 | char *kasprintf(gfp_t gfp, const char *fmt, ...); | 413 | char *kasprintf(gfp_t gfp, const char *fmt, ...); |
414 | extern char *kvasprintf(gfp_t gfp, const char *fmt, va_list args); | 414 | extern __printf(2, 0) |
415 | char *kvasprintf(gfp_t gfp, const char *fmt, va_list args); | ||
415 | 416 | ||
416 | extern __scanf(2, 3) | 417 | extern __scanf(2, 3) |
417 | int sscanf(const char *, const char *, ...); | 418 | int sscanf(const char *, const char *, ...); |
@@ -679,10 +680,10 @@ do { \ | |||
679 | __ftrace_vprintk(_THIS_IP_, fmt, vargs); \ | 680 | __ftrace_vprintk(_THIS_IP_, fmt, vargs); \ |
680 | } while (0) | 681 | } while (0) |
681 | 682 | ||
682 | extern int | 683 | extern __printf(2, 0) int |
683 | __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap); | 684 | __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap); |
684 | 685 | ||
685 | extern int | 686 | extern __printf(2, 0) int |
686 | __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap); | 687 | __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap); |
687 | 688 | ||
688 | extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode); | 689 | extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode); |
@@ -702,7 +703,7 @@ int trace_printk(const char *fmt, ...) | |||
702 | { | 703 | { |
703 | return 0; | 704 | return 0; |
704 | } | 705 | } |
705 | static inline int | 706 | static __printf(1, 0) inline int |
706 | ftrace_vprintk(const char *fmt, va_list ap) | 707 | ftrace_vprintk(const char *fmt, va_list ap) |
707 | { | 708 | { |
708 | return 0; | 709 | return 0; |
diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 2d61b909f414..637f67002c5a 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h | |||
@@ -80,8 +80,9 @@ struct kobject { | |||
80 | 80 | ||
81 | extern __printf(2, 3) | 81 | extern __printf(2, 3) |
82 | int kobject_set_name(struct kobject *kobj, const char *name, ...); | 82 | int kobject_set_name(struct kobject *kobj, const char *name, ...); |
83 | extern int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, | 83 | extern __printf(2, 0) |
84 | va_list vargs); | 84 | int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, |
85 | va_list vargs); | ||
85 | 86 | ||
86 | static inline const char *kobject_name(const struct kobject *kobj) | 87 | static inline const char *kobject_name(const struct kobject *kobj) |
87 | { | 88 | { |
diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index c5d52780d6a0..3ba327af055c 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h | |||
@@ -106,6 +106,6 @@ extern void enable_mmiotrace(void); | |||
106 | extern void disable_mmiotrace(void); | 106 | extern void disable_mmiotrace(void); |
107 | extern void mmio_trace_rw(struct mmiotrace_rw *rw); | 107 | extern void mmio_trace_rw(struct mmiotrace_rw *rw); |
108 | extern void mmio_trace_mapping(struct mmiotrace_map *map); | 108 | extern void mmio_trace_mapping(struct mmiotrace_map *map); |
109 | extern int mmio_trace_printk(const char *fmt, va_list args); | 109 | extern __printf(1, 0) int mmio_trace_printk(const char *fmt, va_list args); |
110 | 110 | ||
111 | #endif /* _LINUX_MMIOTRACE_H */ | 111 | #endif /* _LINUX_MMIOTRACE_H */ |
diff --git a/include/linux/printk.h b/include/linux/printk.h index 58b1fec40d37..a6298b27ac99 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h | |||
@@ -122,7 +122,7 @@ static inline __printf(1, 2) __cold | |||
122 | void early_printk(const char *s, ...) { } | 122 | void early_printk(const char *s, ...) { } |
123 | #endif | 123 | #endif |
124 | 124 | ||
125 | typedef int(*printk_func_t)(const char *fmt, va_list args); | 125 | typedef __printf(1, 0) int (*printk_func_t)(const char *fmt, va_list args); |
126 | 126 | ||
127 | #ifdef CONFIG_PRINTK | 127 | #ifdef CONFIG_PRINTK |
128 | asmlinkage __printf(5, 0) | 128 | asmlinkage __printf(5, 0) |
@@ -166,7 +166,7 @@ char *log_buf_addr_get(void); | |||
166 | u32 log_buf_len_get(void); | 166 | u32 log_buf_len_get(void); |
167 | void log_buf_kexec_setup(void); | 167 | void log_buf_kexec_setup(void); |
168 | void __init setup_log_buf(int early); | 168 | void __init setup_log_buf(int early); |
169 | void dump_stack_set_arch_desc(const char *fmt, ...); | 169 | __printf(1, 2) void dump_stack_set_arch_desc(const char *fmt, ...); |
170 | void dump_stack_print_info(const char *log_lvl); | 170 | void dump_stack_print_info(const char *log_lvl); |
171 | void show_regs_print_info(const char *log_lvl); | 171 | void show_regs_print_info(const char *log_lvl); |
172 | #else | 172 | #else |
@@ -217,7 +217,7 @@ static inline void setup_log_buf(int early) | |||
217 | { | 217 | { |
218 | } | 218 | } |
219 | 219 | ||
220 | static inline void dump_stack_set_arch_desc(const char *fmt, ...) | 220 | static inline __printf(1, 2) void dump_stack_set_arch_desc(const char *fmt, ...) |
221 | { | 221 | { |
222 | } | 222 | } |
223 | 223 | ||
diff --git a/lib/kobject.c b/lib/kobject.c index 2e3bd01964a9..3e3a5c3cb330 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -337,8 +337,9 @@ error: | |||
337 | } | 337 | } |
338 | EXPORT_SYMBOL(kobject_init); | 338 | EXPORT_SYMBOL(kobject_init); |
339 | 339 | ||
340 | static int kobject_add_varg(struct kobject *kobj, struct kobject *parent, | 340 | static __printf(3, 0) int kobject_add_varg(struct kobject *kobj, |
341 | const char *fmt, va_list vargs) | 341 | struct kobject *parent, |
342 | const char *fmt, va_list vargs) | ||
342 | { | 343 | { |
343 | int retval; | 344 | int retval; |
344 | 345 | ||