linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
To: kernel-hardening@lists.openwall.com
Cc: linux-kernel@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	Kees Cook <keescook@chromium.org>,
	Rasmus Villemoes <linux@rasmusvillemoes.dk>
Subject: [RFC 2/6] compiler.h: add __format_template
Date: Wed,  8 Nov 2017 23:30:16 +0100	[thread overview]
Message-ID: <20171108223020.24487-3-linux@rasmusvillemoes.dk> (raw)
In-Reply-To: <20171108223020.24487-1-linux@rasmusvillemoes.dk>

Most format strings in the kernel are explicit string literals at the
use site and can thus be checked by gcc and other static
checkers. There are cases, however, where the format string comes from
some struct member and is implicitly assumed to contain certain
specifiers.

A gcc plugin provides the attribute format_template for that case. One
attaches the attribute to the struct member in question, providing a
template consisting of the expected format specifiers. The plugin then
checks that all static initializations of that struct member is
consistent with the template; moreover, when the format string in a
printf-like function call comes from such an annotated struct member,
one cannot do static analysis of the actual runtime string, but one
can check that the template is consistent with the actual arguments.

Apply the attribute to a few struct members:

struct smp_hotplug_thread::thread_comm
struct usb_class_driver::name
struct applesmc_node_group::format
struct num_var_t::synth_fmt

Modifying kernel/softirq.c slightly, this is what one gets if one
violates the template:

kernel/softirq.c:751:1: error: initializer string 'ksoftirqd/%u+%d' contains extra format specifier '%d' compared to format template 'foobar/%u'

Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
 drivers/hwmon/applesmc.c            | 2 +-
 drivers/staging/speakup/spk_types.h | 2 +-
 include/linux/compiler.h            | 6 ++++++
 include/linux/smpboot.h             | 2 +-
 include/linux/usb.h                 | 2 +-
 5 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 5c677ba44014..9e6d23cba23e 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -110,7 +110,7 @@ struct applesmc_dev_attr {
 
 /* Dynamic device node group */
 struct applesmc_node_group {
-	char *format;				/* format string */
+	char *format __format_template("%d");	/* format string */
 	void *show;				/* show function */
 	void *store;				/* store function */
 	int option;				/* function argument */
diff --git a/drivers/staging/speakup/spk_types.h b/drivers/staging/speakup/spk_types.h
index c50de6035a9a..156000c0c4d3 100644
--- a/drivers/staging/speakup/spk_types.h
+++ b/drivers/staging/speakup/spk_types.h
@@ -108,7 +108,7 @@ struct st_var_header {
 };
 
 struct num_var_t {
-	char *synth_fmt;
+	char *synth_fmt __format_template("%d");
 	int default_val;
 	int low;
 	int high;
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 202710420d6d..478914ad280b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -625,4 +625,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
 	(_________p1); \
 })
 
+#ifdef HAVE_ATTRIBUTE_FORMAT_TEMPLATE
+#define __format_template(x) __attribute__((__format_template__(x)))
+#else
+#define __format_template(x)
+#endif
+
 #endif /* __LINUX_COMPILER_H */
diff --git a/include/linux/smpboot.h b/include/linux/smpboot.h
index c174844cf663..967285b9637d 100644
--- a/include/linux/smpboot.h
+++ b/include/linux/smpboot.h
@@ -42,7 +42,7 @@ struct smp_hotplug_thread {
 	void				(*unpark)(unsigned int cpu);
 	cpumask_var_t			cpumask;
 	bool				selfparking;
-	const char			*thread_comm;
+	const char			*thread_comm __format_template("foobar/%u");
 };
 
 int smpboot_register_percpu_thread_cpumask(struct smp_hotplug_thread *plug_thread,
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 9c63792a8134..8d48c0cd1c01 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1236,7 +1236,7 @@ extern struct bus_type usb_bus_type;
  * parameters used for them.
  */
 struct usb_class_driver {
-	char *name;
+	char *name __format_template("foobar_%d");
 	char *(*devnode)(struct device *dev, umode_t *mode);
 	const struct file_operations *fops;
 	int minor_base;
-- 
2.11.0

  parent reply	other threads:[~2017-11-08 22:31 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-08 22:30 [RFC 0/6] some compile- and run-time format checking Rasmus Villemoes
2017-11-08 22:30 ` [RFC 1/6] plugins: implement format_template attribute Rasmus Villemoes
2017-11-08 22:30 ` Rasmus Villemoes [this message]
2017-11-08 22:30 ` [RFC 3/6] compiler.h: add __attribute__((format_arg)) shorthand Rasmus Villemoes
2017-11-08 22:30 ` [RFC 4/6] lib/vsprintf.c: add fmtcheck utility Rasmus Villemoes
2017-11-09  1:08   ` Kees Cook
2017-11-08 22:30 ` [RFC 5/6] kernel.h: implement fmtmatch() wrapper around fmtcheck() Rasmus Villemoes
2017-11-08 22:30 ` [RFC 6/6] lib/test_printf.c: add a few fmtcheck() test cases Rasmus Villemoes
2017-11-09  1:11 ` [RFC 0/6] some compile- and run-time format checking Kees Cook
2017-11-09 14:08   ` Rasmus Villemoes
2018-10-26 23:24 ` [RFC PATCH 0/7] runtime format string checking Rasmus Villemoes
2018-10-26 23:24   ` [RFC PATCH 1/7] compiler_attributes.h: add __attribute__((format_arg)) shorthand Rasmus Villemoes
2018-10-27 12:06     ` Miguel Ojeda
2018-10-29 10:20       ` Rasmus Villemoes
2018-10-29 19:17         ` Miguel Ojeda
2018-11-02 10:36       ` Miguel Ojeda
2018-11-02 10:43         ` Rasmus Villemoes
2019-01-09 10:57           ` Miguel Ojeda
2018-10-26 23:24   ` [RFC PATCH 2/7] lib/vsprintf.c: add fmtcheck utility Rasmus Villemoes
2018-10-26 23:24   ` [RFC PATCH 3/7] kernel.h: implement fmtmatch() wrapper around fmtcheck() Rasmus Villemoes
2018-10-26 23:24   ` [RFC PATCH 4/7] lib/test_printf.c: add a few fmtcheck() test cases Rasmus Villemoes
2018-10-26 23:24   ` [RFC PATCH 5/7] kernel/kthread.c: do runtime check of format string in kthread_create_on_cpu() Rasmus Villemoes
2018-10-26 23:24   ` [RFC PATCH 6/7] nfs: use fmtcheck() in root_nfs_data Rasmus Villemoes
2018-10-26 23:24   ` [RFC PATCH 7/7] drivers: hwmon: add runtime format string checking Rasmus Villemoes
2018-10-27 17:44     ` Guenter Roeck
2018-10-30 20:58   ` [RFC PATCH 0/7] " Kees Cook
2018-11-01 22:06     ` Rasmus Villemoes
2018-11-01 22:57       ` Kees Cook
2018-11-02 20:09         ` Rasmus Villemoes
2018-11-02 20:46           ` Kees Cook
2018-11-05  9:33         ` Rasmus Villemoes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171108223020.24487-3-linux@rasmusvillemoes.dk \
    --to=linux@rasmusvillemoes.dk \
    --cc=akpm@linux-foundation.org \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).