From: Djalal Harouni <tixxdz@opendz.org>
To: Ryan Mallon <rmallon@gmail.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>,
Joe Perches <joe@perches.com>,
Andrew Morton <akpm@linux-foundation.org>,
eldad@fogrefinery.com, Jiri Kosina <jkosina@suse.cz>,
jgunthorpe@obsidianresearch.com,
Dan Rosenberg <dan.j.rosenberg@gmail.com>,
Kees Cook <keescook@chromium.org>,
Alexander Viro <viro@zeniv.linux.org.uk>,
George Spelvin <linux@horizon.com>,
"kernel-hardening@lists.openwall.com"
<kernel-hardening@lists.openwall.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: [kernel-hardening] Re: [PATCH v3a] vsprintf: Check real user/group id for %pK
Date: Mon, 14 Oct 2013 11:17:06 +0100 [thread overview]
Message-ID: <20131014101706.GA5605@dztty> (raw)
In-Reply-To: <52576E32.1050700@gmail.com>
On Fri, Oct 11, 2013 at 02:19:14PM +1100, Ryan Mallon wrote:
> On 11/10/13 13:20, Eric W. Biederman wrote:
> > Joe Perches <joe@perches.com> writes:
> >
> >> Some setuid binaries will allow reading of files which have read
> >> permission by the real user id. This is problematic with files which
> >> use %pK because the file access permission is checked at open() time,
> >> but the kptr_restrict setting is checked at read() time. If a setuid
> >> binary opens a %pK file as an unprivileged user, and then elevates
> >> permissions before reading the file, then kernel pointer values may be
> >> leaked.
> >>
> >> This happens for example with the setuid pppd application on Ubuntu
> >> 12.04:
> >>
> >> $ head -1 /proc/kallsyms
> >> 00000000 T startup_32
> >>
> >> $ pppd file /proc/kallsyms
> >> pppd: In file /proc/kallsyms: unrecognized option 'c1000000'
> >>
> >> This will only leak the pointer value from the first line, but other
> >> setuid binaries may leak more information.
> >>
> >> Fix this by adding a check that in addition to the current process
> >> having CAP_SYSLOG, that effective user and group ids are equal to the
> >> real ids. If a setuid binary reads the contents of a file which uses
> >> %pK then the pointer values will be printed as NULL if the real user
> >> is unprivileged.
> >>
> >> Update the sysctl documentation to reflect the changes, and also
> >> correct the documentation to state the kptr_restrict=0 is the default.
> >
> > Sigh. This is all wrong. The only correct thing to test is
> > file->f_cred. Aka the capabilities of the program that opened the
> > file.
> >
> > Which means that the interface to %pK in the case of kptr_restrict is
> > broken as it has no way to be passed the information it needs to make
> > a sensible decision.
>
> Would it make sense to add a struct file * to struct seq_file and set
> that in seq_open? Then the capability check can be done against seq->file.
For the "add a struct file * to struct seq_file" and set it during
seq_open(), It was proposed by Linus, but Al Viro didn't like it:
https://lkml.org/lkml/2013/9/25/765
I'm not sure if this will work for you: you can make seq_file->private
cache some data, by calling single_open()... at ->open(), later check it
during read()...
As noted by Eric, I'll also go for the capability check at ->open(), if it
does not break some userspace. BTW the CAP_SYSLOG check should do the job
Checks during read() are not sufficient, since the design allows passing
file descriptors and dup() stdin/stdout of suid-execve.
IMO: unprivileged code should not get that file descriptor, so ->open()
should fail.
If this will break userspace then allow open() and cache result for read()
Can you emulate the behaviour of kptr_restrict=1 ? If so:
1) perform check during open() and cache data
2) during read() check kptr_restrict==1
check the cached value and if opener had CAP_SYSLOG if so:
print something like this: 00000000 T startup_32
All this without modifying vsprintf, I mean just do the checks outside
vsprintf() inside your ->read()
Just my 2 cents
Please cc:me, Thanks
--
Djalal Harouni
http://opendz.org
WARNING: multiple messages have this Message-ID (diff)
From: Djalal Harouni <tixxdz@opendz.org>
To: Ryan Mallon <rmallon@gmail.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>,
Joe Perches <joe@perches.com>,
Andrew Morton <akpm@linux-foundation.org>,
eldad@fogrefinery.com, Jiri Kosina <jkosina@suse.cz>,
jgunthorpe@obsidianresearch.com,
Dan Rosenberg <dan.j.rosenberg@gmail.com>,
Kees Cook <keescook@chromium.org>,
Alexander Viro <viro@zeniv.linux.org.uk>,
George Spelvin <linux@horizon.com>,
"kernel-hardening@lists.openwall.com"
<kernel-hardening@lists.openwall.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v3a] vsprintf: Check real user/group id for %pK
Date: Mon, 14 Oct 2013 11:17:06 +0100 [thread overview]
Message-ID: <20131014101706.GA5605@dztty> (raw)
In-Reply-To: <52576E32.1050700@gmail.com>
On Fri, Oct 11, 2013 at 02:19:14PM +1100, Ryan Mallon wrote:
> On 11/10/13 13:20, Eric W. Biederman wrote:
> > Joe Perches <joe@perches.com> writes:
> >
> >> Some setuid binaries will allow reading of files which have read
> >> permission by the real user id. This is problematic with files which
> >> use %pK because the file access permission is checked at open() time,
> >> but the kptr_restrict setting is checked at read() time. If a setuid
> >> binary opens a %pK file as an unprivileged user, and then elevates
> >> permissions before reading the file, then kernel pointer values may be
> >> leaked.
> >>
> >> This happens for example with the setuid pppd application on Ubuntu
> >> 12.04:
> >>
> >> $ head -1 /proc/kallsyms
> >> 00000000 T startup_32
> >>
> >> $ pppd file /proc/kallsyms
> >> pppd: In file /proc/kallsyms: unrecognized option 'c1000000'
> >>
> >> This will only leak the pointer value from the first line, but other
> >> setuid binaries may leak more information.
> >>
> >> Fix this by adding a check that in addition to the current process
> >> having CAP_SYSLOG, that effective user and group ids are equal to the
> >> real ids. If a setuid binary reads the contents of a file which uses
> >> %pK then the pointer values will be printed as NULL if the real user
> >> is unprivileged.
> >>
> >> Update the sysctl documentation to reflect the changes, and also
> >> correct the documentation to state the kptr_restrict=0 is the default.
> >
> > Sigh. This is all wrong. The only correct thing to test is
> > file->f_cred. Aka the capabilities of the program that opened the
> > file.
> >
> > Which means that the interface to %pK in the case of kptr_restrict is
> > broken as it has no way to be passed the information it needs to make
> > a sensible decision.
>
> Would it make sense to add a struct file * to struct seq_file and set
> that in seq_open? Then the capability check can be done against seq->file.
For the "add a struct file * to struct seq_file" and set it during
seq_open(), It was proposed by Linus, but Al Viro didn't like it:
https://lkml.org/lkml/2013/9/25/765
I'm not sure if this will work for you: you can make seq_file->private
cache some data, by calling single_open()... at ->open(), later check it
during read()...
As noted by Eric, I'll also go for the capability check at ->open(), if it
does not break some userspace. BTW the CAP_SYSLOG check should do the job
Checks during read() are not sufficient, since the design allows passing
file descriptors and dup() stdin/stdout of suid-execve.
IMO: unprivileged code should not get that file descriptor, so ->open()
should fail.
If this will break userspace then allow open() and cache result for read()
Can you emulate the behaviour of kptr_restrict=1 ? If so:
1) perform check during open() and cache data
2) during read() check kptr_restrict==1
check the cached value and if opener had CAP_SYSLOG if so:
print something like this: 00000000 T startup_32
All this without modifying vsprintf, I mean just do the checks outside
vsprintf() inside your ->read()
Just my 2 cents
Please cc:me, Thanks
--
Djalal Harouni
http://opendz.org
next prev parent reply other threads:[~2013-10-14 10:17 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-09 21:52 [kernel-hardening] [PATCH v3] vsprintf: Check real user/group id for %pK Ryan Mallon
2013-10-09 21:52 ` Ryan Mallon
2013-10-09 22:00 ` [kernel-hardening] " Joe Perches
2013-10-09 22:00 ` Joe Perches
2013-10-09 22:04 ` [kernel-hardening] " Ryan Mallon
2013-10-09 22:04 ` Ryan Mallon
2013-10-09 22:14 ` [kernel-hardening] " Joe Perches
2013-10-09 22:14 ` Joe Perches
2013-10-09 22:25 ` [kernel-hardening] " Ryan Mallon
2013-10-09 22:25 ` Ryan Mallon
2013-10-09 22:33 ` [kernel-hardening] " Joe Perches
2013-10-09 22:33 ` Joe Perches
2013-10-09 22:42 ` [kernel-hardening] " Ryan Mallon
2013-10-09 22:42 ` Ryan Mallon
2013-10-09 23:09 ` [kernel-hardening] [PATCH v3a] " Joe Perches
2013-10-09 23:09 ` Joe Perches
2013-10-09 23:18 ` [kernel-hardening] " Ryan Mallon
2013-10-09 23:18 ` Ryan Mallon
2013-10-09 23:21 ` [kernel-hardening] " Joe Perches
2013-10-09 23:21 ` Joe Perches
2013-10-11 2:20 ` [kernel-hardening] " Eric W. Biederman
2013-10-11 2:20 ` Eric W. Biederman
2013-10-11 3:19 ` [kernel-hardening] " Ryan Mallon
2013-10-11 3:19 ` Ryan Mallon
2013-10-11 3:34 ` [kernel-hardening] " Eric W. Biederman
2013-10-11 3:34 ` Eric W. Biederman
2013-10-14 10:17 ` Djalal Harouni [this message]
2013-10-14 10:17 ` Djalal Harouni
2013-10-14 12:21 ` [kernel-hardening] " Djalal Harouni
2013-10-14 12:21 ` Djalal Harouni
2013-10-14 20:41 ` [kernel-hardening] " Ryan Mallon
2013-10-14 20:41 ` Ryan Mallon
2013-10-11 4:42 ` [kernel-hardening] " George Spelvin
2013-10-11 4:42 ` George Spelvin
2013-10-11 5:19 ` [kernel-hardening] " Ryan Mallon
2013-10-11 5:19 ` Ryan Mallon
2013-10-11 5:29 ` [kernel-hardening] " Joe Perches
2013-10-11 5:29 ` Joe Perches
2013-10-11 22:04 ` [kernel-hardening] " Ryan Mallon
2013-10-11 22:04 ` Ryan Mallon
2013-10-11 22:37 ` [kernel-hardening] " Eric W. Biederman
2013-10-11 22:37 ` Eric W. Biederman
2013-10-14 9:18 ` [kernel-hardening] " Ryan Mallon
2013-10-14 9:18 ` Ryan Mallon
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=20131014101706.GA5605@dztty \
--to=tixxdz@opendz.org \
--cc=akpm@linux-foundation.org \
--cc=dan.j.rosenberg@gmail.com \
--cc=ebiederm@xmission.com \
--cc=eldad@fogrefinery.com \
--cc=jgunthorpe@obsidianresearch.com \
--cc=jkosina@suse.cz \
--cc=joe@perches.com \
--cc=keescook@chromium.org \
--cc=kernel-hardening@lists.openwall.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@horizon.com \
--cc=rmallon@gmail.com \
--cc=viro@zeniv.linux.org.uk \
/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.