linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: kernel-hardening@lists.openwall.com,
	LKML <linux-kernel@vger.kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [RFC 4/6] lib/vsprintf.c: add fmtcheck utility
Date: Wed, 8 Nov 2017 17:08:22 -0800	[thread overview]
Message-ID: <CAGXu5jJF6LjH8tuMNGNtb=mqwRio-xmNt9xL0-+18dQzQQZdXA@mail.gmail.com> (raw)
In-Reply-To: <20171108223020.24487-5-linux@rasmusvillemoes.dk>

On Wed, Nov 8, 2017 at 2:30 PM, Rasmus Villemoes
<linux@rasmusvillemoes.dk> wrote:
> We have a few places in the kernel where a *printf function is used with
> a non-constant format string, making the ordinary static type checking
> done by gcc et al. impossible. Some things can still be caught at build
> time with appropriate instrumentation (I'm sure one can do much better
> than the format_template plugin), but that still leaves a number of
> places unchecked. So this patch adds a function for doing run-time
> verification of a given format string against a template.
>
> The fmtcheck() function takes two format string arguments and checks
> whether they contain the same printf specifiers. If they do, the
> first (the string-to-be-checked) string is returned. If not, the
> second (the template) is returned. Regardless of which string is
> returned at run-time, the __format_arg attribute allows the compiler to
> do type-checking if the fmtcheck() function is used inside a *printf
> call, e.g.
>
>   sprintf(buf, fmtcheck(what->ever, "%d %lx", 0), i, m)

Cool, I like this. I wonder if there are any "hot paths" that would
actually make this runtime checking expensive? Seems like anything
that hot shouldn't be using sprintf anyway...

>
> We actually make fmtcheck() a macro that tries very hard to ensure the
> template argument is a string literal - partly to help avoid mixing up
> the two "const char*" arguments, partly because much of the point of
> this sanity checking vanishes if the template is not a literal (e.g.,
> the __format_arg annotation becomes useless).

I wonder how much work it would be to instrument vsnprintf() to warn
about all non-const format strings that are being processed so we
could find all the places where fmtcheck() (and the struct annotation)
are needed.

> We don't treat "%*.*s" and "%d %d %s" as equivalent, despite them
> taking the same vararg types, since they're morally very distinct. In
> fact, at least for now, we don't even treat "%d" and "%u" as
> equivalent. We can relax that, possibly via FMTCHECK_* flags, but let's
> first see which users there might be and what they'd want.
>
> If either string contains a %p, we really should check the following
> alphanumerics to see which (if any) extension is used and check that
> they match as well. For now, just complain loudly, partly because I'm
> lazy, partly because I don't know any in-tree code that might use
> fmtcheck() with a %p in the template, and I can't really imagine
> anyone would use a %pXX extension in a non-constant format string.

Yeah, seems reasonable for the first pass at this.

> I don't know if WARN is too violent; maybe just pr_warn would be ok.

I think WARN gets noticed much more by build and runtime testing
tools, so I think that's the right thing to do here. A mismatch really
should be noticed.

-Kees

-- 
Kees Cook
Pixel Security

  reply	other threads:[~2017-11-09  1:08 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 ` [RFC 2/6] compiler.h: add __format_template Rasmus Villemoes
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 [this message]
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='CAGXu5jJF6LjH8tuMNGNtb=mqwRio-xmNt9xL0-+18dQzQQZdXA@mail.gmail.com' \
    --to=keescook@chromium.org \
    --cc=akpm@linux-foundation.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@rasmusvillemoes.dk \
    /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).