From: Al Viro <viro@ZenIV.linux.org.uk>
To: Kees Cook <keescook@chromium.org>
Cc: Laura Abbott <labbott@redhat.com>,
kernel-hardening@lists.openwall.com,
LKML <linux-kernel@vger.kernel.org>,
Mark Rutland <mark.rutland@arm.com>, X86 ML <x86@kernel.org>
Subject: [kernel-hardening] Re: [RFC PATCH 2/2] x86: Allow paranoid __{get,put}_user
Date: Sat, 4 Nov 2017 00:44:51 +0000 [thread overview]
Message-ID: <20171104004451.GP21978@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20171104002430.GN21978@ZenIV.linux.org.uk>
On Sat, Nov 04, 2017 at 12:24:30AM +0000, Al Viro wrote:
> On Fri, Nov 03, 2017 at 05:14:05PM -0700, Kees Cook wrote:
> > > x86 turns out to be easier since the safe and unsafe paths are mostly
> > > disjoint so we don't have to worry about gcc optimizing out access_ok.
> > > I tweaked the Kconfig to someting a bit more generic.
> > >
> > > The size increase was ~8K in text with a config I tested.
> >
> > Specifically, this feature would have caught the waitid() bug in 4.13
> > immediately.
>
> You mean, as soon as waitid() was given a kernel address. At which point
> you'd get a shiny way to generate a BUG(), and if something like that
> happened under a mutex - it's even more fun...
>
> > > +config PARANOID_UACCESS
> > > + bool "Use paranoid uaccess primitives"
> > > + depends on ARCH_HAS_PARANOID_UACCESS
> > > + help
> > > + Forces access_ok() checks in __get_user(), __put_user(), and other
> > > + low-level uaccess primitives which usually do not have checks. This
> > > + can limit the effect of missing access_ok() checks in higher-level
> > > + primitives, with a runtime performance overhead in some cases and a
> > > + small code size overhead.
>
> IMO that's the wrong way to go - what we need is to reduce the amount of
> __get_user()/__put_user(), rather than "instrumenting" them that way.
FWIW, unsafe variants ought to be encapsulated in as few places as possible.
And that includes both unsafe_... and __... stuff. waitid() had been a dumb
fuckup (by me) and it should've been done as
static int waitid_put_siginfo(struct siginfo __user *si, struct waitid_info *info,
int signo)
{
if (!si)
return 0;
if (!access_ok(VERIFY_WRITE, si, sizeof(struct siginfo)))
return -EFAULT;
user_access_begin();
unsafe_put_user(signo, &si->si_signo, Efault);
unsafe_put_user(0, &si->si_errno, Efault);
unsafe_put_user(info->cause, &si->si_code, Efault);
unsafe_put_user(info->pid, &si->si_pid, Efault);
unsafe_put_user(info->uid, &si->si_uid, Efault);
unsafe_put_user(info->status, &si->si_status, Efault);
user_access_end();
return 0;
Efault:
user_access_end();
return -EFAULT;
}
instead, rather than mixing it with the rest. Basically, any unsafe... or __...
should be
* used as little as possible
* accompanied by access_ok() in the same function
* not mixed with other stuff within the same function
We are obviously not there yet, but __get_user()/__put_user() *are* getting killed
off.
WARNING: multiple messages have this Message-ID (diff)
From: Al Viro <viro@ZenIV.linux.org.uk>
To: Kees Cook <keescook@chromium.org>
Cc: Laura Abbott <labbott@redhat.com>,
kernel-hardening@lists.openwall.com,
LKML <linux-kernel@vger.kernel.org>,
Mark Rutland <mark.rutland@arm.com>, X86 ML <x86@kernel.org>
Subject: Re: [RFC PATCH 2/2] x86: Allow paranoid __{get,put}_user
Date: Sat, 4 Nov 2017 00:44:51 +0000 [thread overview]
Message-ID: <20171104004451.GP21978@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20171104002430.GN21978@ZenIV.linux.org.uk>
On Sat, Nov 04, 2017 at 12:24:30AM +0000, Al Viro wrote:
> On Fri, Nov 03, 2017 at 05:14:05PM -0700, Kees Cook wrote:
> > > x86 turns out to be easier since the safe and unsafe paths are mostly
> > > disjoint so we don't have to worry about gcc optimizing out access_ok.
> > > I tweaked the Kconfig to someting a bit more generic.
> > >
> > > The size increase was ~8K in text with a config I tested.
> >
> > Specifically, this feature would have caught the waitid() bug in 4.13
> > immediately.
>
> You mean, as soon as waitid() was given a kernel address. At which point
> you'd get a shiny way to generate a BUG(), and if something like that
> happened under a mutex - it's even more fun...
>
> > > +config PARANOID_UACCESS
> > > + bool "Use paranoid uaccess primitives"
> > > + depends on ARCH_HAS_PARANOID_UACCESS
> > > + help
> > > + Forces access_ok() checks in __get_user(), __put_user(), and other
> > > + low-level uaccess primitives which usually do not have checks. This
> > > + can limit the effect of missing access_ok() checks in higher-level
> > > + primitives, with a runtime performance overhead in some cases and a
> > > + small code size overhead.
>
> IMO that's the wrong way to go - what we need is to reduce the amount of
> __get_user()/__put_user(), rather than "instrumenting" them that way.
FWIW, unsafe variants ought to be encapsulated in as few places as possible.
And that includes both unsafe_... and __... stuff. waitid() had been a dumb
fuckup (by me) and it should've been done as
static int waitid_put_siginfo(struct siginfo __user *si, struct waitid_info *info,
int signo)
{
if (!si)
return 0;
if (!access_ok(VERIFY_WRITE, si, sizeof(struct siginfo)))
return -EFAULT;
user_access_begin();
unsafe_put_user(signo, &si->si_signo, Efault);
unsafe_put_user(0, &si->si_errno, Efault);
unsafe_put_user(info->cause, &si->si_code, Efault);
unsafe_put_user(info->pid, &si->si_pid, Efault);
unsafe_put_user(info->uid, &si->si_uid, Efault);
unsafe_put_user(info->status, &si->si_status, Efault);
user_access_end();
return 0;
Efault:
user_access_end();
return -EFAULT;
}
instead, rather than mixing it with the rest. Basically, any unsafe... or __...
should be
* used as little as possible
* accompanied by access_ok() in the same function
* not mixed with other stuff within the same function
We are obviously not there yet, but __get_user()/__put_user() *are* getting killed
off.
next prev parent reply other threads:[~2017-11-04 0:44 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-26 9:09 [kernel-hardening] [RFC PATCH 0/2] arm64: optional paranoid __{get,put}_user checks Mark Rutland
2017-10-26 9:09 ` Mark Rutland
2017-10-26 9:09 ` Mark Rutland
2017-10-26 9:09 ` [kernel-hardening] [RFC PATCH 1/2] arm64: write __range_ok() in C Mark Rutland
2017-10-26 9:09 ` Mark Rutland
2017-10-26 9:09 ` Mark Rutland
2017-11-16 15:28 ` [kernel-hardening] " Will Deacon
2017-11-16 15:28 ` Will Deacon
2017-11-16 15:28 ` Will Deacon
2017-11-20 12:22 ` [kernel-hardening] " Mark Rutland
2017-11-20 12:22 ` Mark Rutland
2017-11-20 12:22 ` Mark Rutland
2017-10-26 9:09 ` [kernel-hardening] [RFC PATCH 2/2] arm64: allow paranoid __{get,put}user Mark Rutland
2017-10-26 9:09 ` Mark Rutland
2017-10-26 9:09 ` Mark Rutland
2017-10-27 15:41 ` [kernel-hardening] Re: [RFC PATCH 0/2] arm64: optional paranoid __{get,put}_user checks Will Deacon
2017-10-27 15:41 ` Will Deacon
2017-10-27 15:41 ` Will Deacon
2017-10-27 20:44 ` [kernel-hardening] " Mark Rutland
2017-10-27 20:44 ` Mark Rutland
2017-10-27 20:44 ` Mark Rutland
2017-10-28 8:47 ` [kernel-hardening] " Russell King - ARM Linux
2017-10-28 8:47 ` Russell King - ARM Linux
2017-10-28 8:47 ` Russell King - ARM Linux
2017-10-31 23:56 ` [kernel-hardening] " Laura Abbott
2017-10-31 23:56 ` Laura Abbott
2017-10-31 23:56 ` Laura Abbott
2017-11-01 12:05 ` [kernel-hardening] " Mark Rutland
2017-11-01 12:05 ` Mark Rutland
2017-11-01 12:05 ` Mark Rutland
2017-11-01 21:13 ` [kernel-hardening] " Laura Abbott
2017-11-01 21:13 ` Laura Abbott
2017-11-01 21:13 ` Laura Abbott
2017-11-01 22:28 ` [kernel-hardening] " Kees Cook
2017-11-01 22:28 ` Kees Cook
2017-11-01 22:28 ` Kees Cook
2017-11-01 23:05 ` [kernel-hardening] " Laura Abbott
2017-11-01 23:05 ` Laura Abbott
2017-11-01 23:05 ` Laura Abbott
2017-11-01 23:29 ` [kernel-hardening] " Kees Cook
2017-11-01 23:29 ` Kees Cook
2017-11-01 23:29 ` Kees Cook
2017-11-02 1:25 ` [kernel-hardening] " Laura Abbott
2017-11-02 1:25 ` Laura Abbott
2017-11-02 1:25 ` Laura Abbott
2017-11-03 23:04 ` [kernel-hardening] [RFC PATCH 1/2] x86: Avoid multiple evaluations in __{get,put}_user_size Laura Abbott
2017-11-03 23:04 ` Laura Abbott
2017-11-03 23:04 ` [kernel-hardening] [RFC PATCH 2/2] x86: Allow paranoid __{get,put}_user Laura Abbott
2017-11-03 23:04 ` Laura Abbott
2017-11-04 0:14 ` [kernel-hardening] " Kees Cook
2017-11-04 0:14 ` Kees Cook
2017-11-04 0:24 ` [kernel-hardening] " Al Viro
2017-11-04 0:24 ` Al Viro
2017-11-04 0:44 ` Al Viro [this message]
2017-11-04 0:44 ` Al Viro
2017-11-04 1:39 ` [kernel-hardening] " Kees Cook
2017-11-04 1:39 ` Kees Cook
2017-11-04 1:41 ` [kernel-hardening] " Kees Cook
2017-11-04 1:41 ` Kees Cook
2017-11-04 1:58 ` [kernel-hardening] " Mark Rutland
2017-11-04 1:58 ` Mark Rutland
2017-11-06 20:38 ` [kernel-hardening] " Laura Abbott
2017-11-06 20:38 ` Laura Abbott
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=20171104004451.GP21978@ZenIV.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=keescook@chromium.org \
--cc=kernel-hardening@lists.openwall.com \
--cc=labbott@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=x86@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 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.