From patchwork Wed Nov 8 22:30:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rasmus Villemoes X-Patchwork-Id: 10049577 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A80BD60381 for ; Wed, 8 Nov 2017 22:31:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9A3782999C for ; Wed, 8 Nov 2017 22:31:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8EFB12A41A; Wed, 8 Nov 2017 22:31:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id B6C662999C for ; Wed, 8 Nov 2017 22:31:28 +0000 (UTC) Received: (qmail 17559 invoked by uid 550); 8 Nov 2017 22:30:59 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 17460 invoked from network); 8 Nov 2017 22:30:56 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rasmusvillemoes.dk; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=i/LJkOe6dUqQv7LWOzn2Z5Ky+6HwXTjQZOOVbLLRiG0=; b=jVWAoNbXOo5KA5jzDqu52K+Ke7QxIcLi9Ch7td+IPuvL9byPwPvcvf77SWTXOyHt9d j8e4SEFlVhH2esYDpzHwx86B6hitVOvl8d/ErJK2tBBfOx0oYkxJ+MdNZuQnqiFcU84a p4gpHN2eLgum7/3/B0GuaauQZjXqSc26odyrw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=i/LJkOe6dUqQv7LWOzn2Z5Ky+6HwXTjQZOOVbLLRiG0=; b=HuGTTUe2/4jh7N23mmhqgIZ2kjFSjwwUaPOZdmZXIzydiaTcFMg38lr6Tz9P1ReJlV /iHr6kN5oTXe5Y+51xBLPkmfK8GSIaEXzouQQUb07tKXpTrzKQy8P3CnXS22oWlnrXBK uM9REwmG9hmdxM7z8Eai1d4Dzz0tV9kGGs9wazGVpNPIzRuvychJZFYkcmu8dvnKYPds /lSwKcdwDXCFC27HBiMea2VExiUwsZvw3vUuWXKvUMyVZLahWME5qiicy0VepErRzrMJ nV/VpjV2/Ax4CRlHR0tLLq+3RVInMqVoK5RAAcPw3pnLespOKVn4fcLSZ5eF+oA7eQup W4Ow== X-Gm-Message-State: AJaThX77gDybl+vKp0XmE4ZQ1wfqReo/xTrFpbHDfqdo99nuUUA+sC2t KnYjxoAzLKt52gz81SEsWGrpsqAy X-Google-Smtp-Source: ABhQp+TMrAfE3IfQeBGdkI8rTpmQkacAp5Xv5edUerAPwmv059spITArr3U1pXuB/bV+7rB7HstEaQ== X-Received: by 10.223.132.6 with SMTP id 6mr1657981wrf.93.1510180245358; Wed, 08 Nov 2017 14:30:45 -0800 (PST) From: Rasmus Villemoes To: kernel-hardening@lists.openwall.com Cc: linux-kernel@vger.kernel.org, Andrew Morton , Kees Cook , Rasmus Villemoes Date: Wed, 8 Nov 2017 23:30:16 +0100 Message-Id: <20171108223020.24487-3-linux@rasmusvillemoes.dk> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171108223020.24487-1-linux@rasmusvillemoes.dk> References: <20171108223020.24487-1-linux@rasmusvillemoes.dk> Subject: [kernel-hardening] [RFC 2/6] compiler.h: add __format_template X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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;