All of lore.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@ZenIV.linux.org.uk>
To: Kees Cook <keescook@chromium.org>
Cc: linux-kernel@vger.kernel.org, joe@perches.com,
	George Spelvin <linux@horizon.com>,
	dan.carpenter@oracle.com, Jan Beulich <JBeulich@suse.com>,
	KOSAKI Motohiro <kosaki.motohiro@gmail.com>,
	Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>,
	akpm@linux-foundation.org
Subject: Re: [PATCH 0/2] vsprintf: ignore %n again
Date: Mon, 16 Sep 2013 16:55:04 +0100	[thread overview]
Message-ID: <20130916155504.GC13318@ZenIV.linux.org.uk> (raw)
In-Reply-To: <1379317437-28329-1-git-send-email-keescook@chromium.org>

On Mon, Sep 16, 2013 at 12:43:55AM -0700, Kees Cook wrote:
> Whether seq_printf should return void or error, %n still needs to be removed.
> As such, instead of changing the seq_file structure and adding instructions
> to all callers of seq_printf, just examine seq->count for the callers that
> care about how many characters were put into the buffer, as suggested by
> George Spelvin. First patch removes all %n usage in favor of checking
> seq->count before/after. Second patch makes %n ignore its argument.

This is completely pointless.  *ANY* untrusted format string kernel-side
is pretty much it.  Blocking %n is not "defense in depth", it's security
theater.  Again, if attacker can feed an arbitrary format string to
vsnprintf(), it's over - you've lost.  It's not just about information
leaks vs. ability to store a value of attacker's choosing at the address
of attacker's choosing as it was in userland.  Kernel-side an ability to
trigger read from an arbitrary address is much nastier than information
leak risk; consider iomem, for starters.

What we ought to do is prevention of _that_.  AFAICS, we have reasonably
few call chains that might transmit format string; most of the calls
are with plain and simple string literal.  I wonder if could get away
with reasonable amount of annotations to catch such crap...

Consider, e.g. introducing __vsnprint(), with vsnprintf(s, n, fmt, ...)
expanding to __vsnprintf(1, s, n, fmt, ...) if fmt is a string literal
and __vsnprintf(0, s, n, fmt, ...) otherwise.  Now,
int __sprintf(int safe, char *buf, const char *fmt, ...)
{
        va_list args;
        int i;

        va_start(args, fmt);
        i = __vsnprintf(safe, buf, INT_MAX, fmt, args);
        va_end(args);

        return i;
}
and #define for sprintf (expanding it to either __sprintf(1, ...)
or __sprintf(0, ...)).  That plus similar for snprintf and seq_printf
will already take care of most of the call chains leading to __vsnprintf() -
relatively few calls with have 0 passed to it.  Add WARN_ON(!safe) to
__vsnprintf and we probably won't drown in warnings.  Now, we can start
adding things like that to remaining call chains *and* do things like
replacing
                        snd_iprintf(buffer, fields[i].format,
                                *get_dummy_ll_ptr(dummy, fields[i].offset));
with
			/* fields[i].format is known to be a valid format */
                        __snd_iprintf(1, buffer, fields[i].format,
                                *get_dummy_ll_ptr(dummy, fields[i].offset));
to deal with the places where the origin of format string is provably safe,
but not a string literal (actually, s/1/__FORMAT_IS_SAFE/, to make it
greppable).

Comments?

  parent reply	other threads:[~2013-09-16 15:55 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-16  7:43 [PATCH 0/2] vsprintf: ignore %n again Kees Cook
2013-09-16  7:43 ` [PATCH 1/2] remove all uses of printf's %n Kees Cook
2013-09-16  8:09   ` Geert Uytterhoeven
2013-09-16 15:00     ` Kees Cook
2013-09-17 13:06       ` Tetsuo Handa
2013-09-17 14:34         ` Kees Cook
2013-09-17 20:57           ` George Spelvin
2013-09-19  8:56             ` Tetsuo Handa
2013-09-19 14:28               ` Kees Cook
2013-09-20  4:09                 ` Tetsuo Handa
2013-09-20  4:09                   ` Tetsuo Handa
2013-09-20  4:23                   ` Joe Perches
2013-09-20  4:23                     ` Joe Perches
2013-09-20  4:53                     ` Kees Cook
2013-09-20  4:53                       ` Kees Cook
2013-09-20  8:08                   ` Jiri Slaby
2013-09-20  8:08                     ` Jiri Slaby
2013-09-20 19:24                     ` Kees Cook
2013-09-20 19:24                       ` Kees Cook
2013-09-20 19:33                       ` Joe Perches
2013-09-20 19:33                         ` Joe Perches
2013-09-21  0:28                       ` Tetsuo Handa
2013-09-21  0:28                         ` Tetsuo Handa
2013-09-22  8:16                         ` Geert Uytterhoeven
2013-09-22  8:16                           ` Geert Uytterhoeven
2013-09-22  8:09                   ` George Spelvin
2013-09-22  8:09                     ` George Spelvin
2013-09-23 21:24                   ` Kees Cook
2013-09-23 21:24                     ` Kees Cook
2013-09-30  8:16                     ` Tetsuo Handa
2013-09-30  8:16                       ` Tetsuo Handa
2013-09-16 11:41   ` Tetsuo Handa
2013-09-16 14:59     ` Kees Cook
2013-09-16 15:09       ` Joe Perches
2013-09-16 15:25         ` Kees Cook
2013-09-16 15:44           ` Joe Perches
2013-09-16 17:21         ` George Spelvin
2013-09-16 18:03           ` Joe Perches
2013-09-16 16:07   ` George Spelvin
2013-09-16 16:13     ` Joe Perches
2013-09-16 16:39       ` George Spelvin
2013-09-16 17:53         ` Joe Perches
2013-09-16 19:15           ` George Spelvin
2013-09-16 19:25             ` Joe Perches
2013-09-16  7:43 ` [PATCH 2/2] vsprintf: ignore %n again Kees Cook
2013-09-16 15:55 ` Al Viro [this message]
2013-09-16 16:15   ` [PATCH 0/2] " Lars-Peter Clausen
2013-09-16 16:30   ` George Spelvin
2013-09-16 18:20   ` Kees Cook
2013-09-18 13:14     ` Tetsuo Handa
2013-09-18 14:11       ` Dan Carpenter
2013-09-18 14:28         ` Dan Carpenter
2013-09-18 15:22         ` George Spelvin
2013-09-18 14:32       ` Kees Cook
2013-09-19  2:11         ` Tetsuo Handa
2013-09-19  7:08           ` Tetsuo Handa
2013-09-18 14:47       ` Kees Cook

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=20130916155504.GC13318@ZenIV.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=JBeulich@suse.com \
    --cc=akpm@linux-foundation.org \
    --cc=dan.carpenter@oracle.com \
    --cc=joe@perches.com \
    --cc=keescook@chromium.org \
    --cc=kosaki.motohiro@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@horizon.com \
    --cc=penguin-kernel@i-love.sakura.ne.jp \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.