mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: ebiederm@xmission.com (Eric W. Biederman)
To: Andy Lutomirski <luto@amacapital.net>
Cc: Linux Containers <containers@lists.linux-foundation.org>,
	Josh Triplett <josh@joshtriplett.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Kees Cook <keescook@chromium.org>,
	Michael Kerrisk-manpages <mtk.manpages@gmail.com>,
	Linux API <linux-api@vger.kernel.org>,
	linux-man <linux-man@vger.kernel.org>,
	"linux-kernel\@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	LSM <linux-security-module@vger.kernel.org>,
	Casey Schaufler <casey@schaufler-ca.com>,
	"Serge E. Hallyn" <serge@hallyn.com>,
	Richard Weinberger <richard@nod.at>,
	Kenton Varda <kenton@sandstorm.io>,
	stable <stable@vger.kernel.org>
Subject: Re: [CFT][PATCH 1/3] userns: Avoid problems with negative groups
Date: Tue, 02 Dec 2014 16:48:53 -0600	[thread overview]
Message-ID: <87wq69pt0q.fsf@x220.int.ebiederm.org> (raw)
In-Reply-To: <CALCETrUJ9Qk553YSsYkjaeE-Qw0u_Pt1eoODUPX-udsO8kf14w@mail.gmail.com> (Andy Lutomirski's message of "Tue, 2 Dec 2014 14:09:13 -0800")

Andy Lutomirski <luto@amacapital.net> writes:

> On Tue, Dec 2, 2014 at 1:26 PM, Eric W. Biederman <ebiederm@xmission.com> wrote:
>> Andy Lutomirski <luto@amacapital.net> writes:
>>
>>> On Tue, Dec 2, 2014 at 12:25 PM, Eric W. Biederman
>>> <ebiederm@xmission.com> wrote:
>>>>
>>>> Classic unix permission checks have an interesting feature, the group
>>>> permissions for a file can be set to less than the other permissions
>>>> on a file.  Occassionally this is used deliberately to give a certain
>>>> group of users fewer permissions than the default.
>>>>
>>>> Overlooking negative groups has resulted in the permission checks for
>>>> setting up a group mapping in a user namespace to be too lax.  Tighten
>>>> the permission checks in new_idmap_permitted to ensure that mapping
>>>> uids and gids into user namespaces without privilege will not result
>>>> in new combinations of credentials being available to the users.
>>>>
>>>> When setting mappings without privilege only the creator of the user
>>>> namespace is interesting as all other users that have CAP_SETUID over
>>>> the user namespace will also have CAP_SETUID over the user namespaces
>>>> parent.  So the scope of the unprivileged check is reduced to just
>>>> the case where cred->euid is the namespace creator.
>>>>
>>>> For setting a uid mapping without privilege only euid is considered as
>>>> setresuid can set uid, suid and fsuid from euid without privielege
>>>> making any combination of uids possible with user namespaces already
>>>> possible without them.
>>>>
>>>> For now seeting a gid mapping without privilege is removed.  The only
>>>> possible set of credentials that would be safe without a gid mapping
>>>> (egid without any supplementary groups) just doesn't happen in practice
>>>> so would simply lead to unused untested code.
>>>>
>>>> setgroups is modified to fail not only when the group ids do not
>>>> map but also when there are no gid mappings at all, preventing
>>>> setgroups(0, NULL) from succeeding when gid mappings have not been
>>>> established.
>>>>
>>>> For a small class of applications this change breaks userspace
>>>> and removes useful functionality.  This small class of applications
>>>> includes tools/testing/selftests/mount/unprivileged-remount-test.c
>>>>
>>>> Most of the removed functionality will be added back with the
>>>> addition of a one way knob to disable setgroups.  Once setgroups
>>>> is disabled setting the gid_map becomes as safe as setting the uid_map.
>>>>
>>>> For more common applications that set the uid_map and the gid_map with
>>>> privilege this change will have no effect on them.
>>>>
>>>> This should fix CVE-2014-8989.
>>>>
>>>> Cc: stable@vger.kernel.org
>>>> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
>>>> ---
>>>
>>>>
>>>> +static inline bool gid_mapping_possible(const struct user_namespace *ns)
>>>> +{
>>>> +       return ns->gid_map.nr_extents != 0;
>>>> +}
>>>> +
>>>
>>> Can you rename this to userns_may_setgroups or something like that?
>>> To me, gid_mapping_possible sounds like you're allowed to map gids,
>>> which sounds like the opposite condition, and it doesn't explain what
>>> the point is.
>>
>> gid_mapping_established?
>>
>> What I mean to be testing if is if from_kgid and make_kgid will work
>> because the gid mappings have been set.
>
> But why do you care whether from_kgid and make_kgid will work?  If
> they fail, then they fail.  I think that the point is that you're
> checking whether allowing setgroups to drop groups is safe, and that's
> only barely the same condition.

For all of the system calls to set or change uids and gids except
setgroups it happens to fall out that if there are no mappings set the
system calls fail.  That is and was deliberate.  However setgroups is
weird because it allows the case of 0 mappings and to maintain the
constraint that it fails when there are no mapping set (just like
everything else) that requires an additional test.

>> The userns knob for setgroups is a different test and is added
>> in the next patch.  And yes we really need both or the knob can
>> start out as on, and we need to provent setgroups(0, NULL)
>> before the user namespace is unshared.
>
> Do you mean before it's mapped?

Right we need to prevent setgroups(0, NULL) before we set the gid
mapping.

>> Although come to think about it probably makes sense to roll those two
>> test into one function and call that inline function from the setgroups
>> implementation.
>
> That's what I think, too.
>
>>
>> Anyway I will think about it and see what I can do to make it easily
>> comprehensible.
>>
>>>> diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
>>>> index aa312b0dc3ec..51d65b444951 100644
>>>> --- a/kernel/user_namespace.c
>>>> +++ b/kernel/user_namespace.c
>>>> @@ -812,16 +812,19 @@ static bool new_idmap_permitted(const struct file *file,
>>>>                                 struct user_namespace *ns, int cap_setid,
>>>>                                 struct uid_gid_map *new_map)
>>>>  {
>>>> -       /* Allow mapping to your own filesystem ids */
>>>> -       if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1)) {
>>>> +       const struct cred *cred = file->f_cred;
>>>> +
>>>> +       /* Allow a mapping without capabilities when allowing the root
>>>> +        * of the user namespace capabilities restricted to that id
>>>> +        * will not change the set of credentials available to that
>>>> +        * user.
>>>> +        */
>>>> +       if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1) &&
>>>> +           uid_eq(ns->owner, cred->euid)) {
>>>
>>> What's uid_eq(ns->owner, cred->euid)) for?  This should already be covered by:
>>
>> This means that the only user we attempt to set up unprivileged mappings
>> for is the owner of the user namespace.  Anyone else should already
>> have capabilities in the parent user namespace or shouldn't be able to
>> set the mapping at all.
>>
>> In practice it is a clarification to make it easier to think about the code.
>
> But why?  I don't see why this check is necessary or why it's relevant
> to the current issue.

My goal in this check is to guarantee that any combination of uids and
gids in struct cred that you can obtain with mappings and a user
namespace you can also obtain without privilege without a user
namespace.

What limiting euid to ns->owner does is it guarantees that when a user
namespace is created without privilege root doesn't come along and set
the mapping using the unprivileged path.  That is confusing to think
about and it is not necessary to support.

With ns->owner == euid I have the guarantee especially with the gids
that they wind up paired with a uid in struct cred that came from the
same user.  Either that or someone set one of the mappings with
privilege.

With ns->owner == euid I can verify all of these things pretty
trivially.  Without that check I don't have a clue how to verify
the pairing between uids and gids in the unprivileged mapping.

Does that make things clearer?

>>>     if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
>>>         goto out;
>>>
>>> (except that I don't know why cap_valid(cap_setid) is checked -- this
>>> ought to be enforced for projid_map, too, right?)
>>
>> What to do with projid_map is entirely different discussion.  In
>> practice it is dead, and either XFS needs to be fixed to use it
>> or that code needs to be removed.  At the time I wrote it XFS
>> did not require any privileges to set project ids.
>>
>>>>                 u32 id = new_map->extent[0].lower_first;
>>>>                 if (cap_setid == CAP_SETUID) {
>>>>                         kuid_t uid = make_kuid(ns->parent, id);
>>>> -                       if (uid_eq(uid, file->f_cred->fsuid))
>>>> -                               return true;
>>>> -               } else if (cap_setid == CAP_SETGID) {
>>>> -                       kgid_t gid = make_kgid(ns->parent, id);
>>>> -                       if (gid_eq(gid, file->f_cred->fsgid))
>>>> +                       if (uid_eq(uid, cred->euid))
>>>
>>> Why'd you change this from fsuid to euid?
>>
>> Because strangely enough I can set euid to any other uid with
>> setresuid, but the same does not hold with fsuid.
>>
>> So strictly speaking fsuid was actually wrong before.  In practice
>> fsuid == euid so I don't think anyone will care.  But I want very much
>> to enforce the rule that user namespaces can't give you any credentials
>> you couldn't get otherwise.
>
> Fair enough.  Want to split that into a separate patch, then?

Strictly speaking it is part and parcel of the same thing but it
probably makes sense to split it out and emphasise and explain the
change.

Eric


  reply	other threads:[~2014-12-02 22:51 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-29 17:26 [PATCH v2] userns: Disallow setgroups unless the gid_map writer is privileged Andy Lutomirski
2014-12-02 12:09 ` Eric W. Biederman
2014-12-02 18:53   ` Andy Lutomirski
2014-12-02 19:45     ` Eric W. Biederman
2014-12-02 20:13       ` Andy Lutomirski
2014-12-02 20:25         ` [CFT][PATCH 1/3] userns: Avoid problems with negative groups Eric W. Biederman
2014-12-02 20:28           ` [CFT][PATCH 2/3] userns: Add a knob to disable setgroups on a per user namespace basis Eric W. Biederman
2014-12-02 20:30             ` [CFT][PATCH 3/3] userns: Unbreak the unprivileged remount tests Eric W. Biederman
2014-12-02 21:05             ` [CFT][PATCH 2/3] userns: Add a knob to disable setgroups on a per user namespace basis Andy Lutomirski
2014-12-02 21:45               ` Eric W. Biederman
2014-12-02 22:17                 ` Andy Lutomirski
2014-12-02 23:07                   ` Eric W. Biederman
2014-12-02 23:17                     ` Andy Lutomirski
2014-12-08 22:06                       ` [CFT][PATCH 1/7] userns: Document what the invariant required for safe unprivileged mappings Eric W. Biederman
2014-12-08 22:07                         ` [CFT][PATCH 2/7] userns: Don't allow setgroups until a gid mapping has been setablished Eric W. Biederman
2014-12-08 22:11                           ` Andy Lutomirski
     [not found]                             ` <87h9x5ok0h.fsf@x220.int.ebiederm.org>
2014-12-08 22:33                               ` Andy Lutomirski
2014-12-08 22:17                           ` Richard Weinberger
2014-12-08 22:25                             ` Andy Lutomirski
2014-12-08 22:27                               ` Richard Weinberger
     [not found]                                 ` <874mt5ojfh.fsf@x220.int.ebiederm.org>
2014-12-08 22:47                                   ` Andy Lutomirski
2014-12-08 22:07                         ` [CFT][PATCH 3/7] userns: Don't allow unprivileged creation of gid mappings Eric W. Biederman
2014-12-08 22:08                         ` [CFT][PATCH 4/7] userns: Check euid no fsuid when establishing an unprivileged uid mapping Eric W. Biederman
2014-12-08 22:12                           ` Andy Lutomirski
2014-12-08 22:10                         ` [CFT][PATCH 5/7] userns: Only allow the creator of the userns unprivileged mappings Eric W. Biederman
2014-12-08 22:15                           ` Andy Lutomirski
2014-12-08 22:11                         ` [CFT][PATCH 6/7] userns: Add a knob to disable setgroups on a per user namespace basis Eric W. Biederman
2014-12-08 22:21                           ` Andy Lutomirski
2014-12-08 22:44                             ` Eric W. Biederman
2014-12-08 22:48                               ` Andy Lutomirski
2014-12-08 23:30                                 ` Eric W. Biederman
2014-12-09 19:31                                   ` Eric W. Biederman
2014-12-09 20:36                                     ` [CFT][PATCH 1/8] userns: Document what the invariant required for safe unprivileged mappings Eric W. Biederman
2014-12-09 20:38                                       ` [CFT][PATCH 2/8] userns: Don't allow setgroups until a gid mapping has been setablished Eric W. Biederman
2014-12-09 22:49                                         ` Andy Lutomirski
2014-12-09 20:39                                       ` [CFT][PATCH 3/8] userns: Don't allow unprivileged creation of gid mappings Eric W. Biederman
2014-12-09 23:00                                         ` Andy Lutomirski
2014-12-09 20:39                                       ` [CFT][PATCH 4/8] userns: Check euid no fsuid when establishing an unprivileged uid mapping Eric W. Biederman
2014-12-09 20:41                                       ` [CFT][PATCH 5/8] userns: Only allow the creator of the userns unprivileged mappings Eric W. Biederman
2014-12-09 20:41                                       ` [CFT][PATCH 6/8] userns: Rename id_map_mutex to userns_state_mutex Eric W. Biederman
2014-12-09 22:49                                         ` Andy Lutomirski
2014-12-09 20:42                                       ` [CFT][PATCH 7/8] userns: Add a knob to disable setgroups on a per user namespace basis Eric W. Biederman
2014-12-09 22:28                                         ` Andy Lutomirski
     [not found]                                           ` <971ad3f6-90fd-4e3f-916c-8988af3c826d@email.android.com>
2014-12-10  0:21                                             ` Andy Lutomirski
     [not found]                                               ` <87wq5zf83t.fsf@x220.int.ebiederm.org>
     [not found]                                                 ` <87iohh3c9c.fsf@x220.int.ebiederm.org>
2014-12-12  1:30                                                   ` Andy Lutomirski
     [not found]                                                   ` <8761dh3b7k.fsf_-_@x220.int.ebiederm.org>
     [not found]                                                     ` <878uicy1r9.fsf_-_@x220.int.ebiederm.org>
2014-12-12 21:54                                                       ` [PATCH 1/2] proc.5: Document /proc/[pid]/setgroups Eric W. Biederman
2015-02-02 15:36                                                         ` Michael Kerrisk (man-pages)
2015-02-11  8:01                                                           ` Michael Kerrisk (man-pages)
2015-02-11 13:51                                                             ` Eric W. Biederman
2015-02-12 13:53                                                               ` Michael Kerrisk (man-pages)
2015-02-21  7:57                                                                 ` Michael Kerrisk (man-pages)
2015-03-03 11:39                                                                 ` Michael Kerrisk (man-pages)
2014-12-12 21:54                                                       ` [PATCH 2/2] user_namespaces.7: Update the documention to reflect the fixes for negative groups Eric W. Biederman
2015-02-02 15:37                                                         ` Michael Kerrisk (man-pages)
2015-02-11  8:02                                                           ` Michael Kerrisk (man-pages)
2015-02-11 14:01                                                             ` Eric W. Biederman
2015-02-12 10:11                                                               ` Michael Kerrisk (man-pages)
2015-02-02 21:31                                                         ` Alban Crequy
2015-03-04 14:00                                                           ` Michael Kerrisk (man-pages)
2014-12-09 20:43                                       ` [CFT][PATCH 8/8] userns: Allow setting gid_maps without privilege when setgroups is disabled Eric W. Biederman
2014-12-10 16:39                                       ` [CFT] Can I get some Tested-By's on this series? Eric W. Biederman
2014-12-10 22:48                                         ` Serge Hallyn
2014-12-10 22:50                                           ` Richard Weinberger
2014-12-10 23:19                                             ` Eric W. Biederman
2014-12-11 19:27                                               ` Richard Weinberger
2014-12-12  6:56                                               ` Chen, Hanxiao
2014-12-13 22:31                                           ` serge
     [not found]                                           ` <87lhmcy2et.fsf@x220.int.ebiederm.org>
     [not found]                                             ` <20141212220840.GF22091@castiana.ipv6.teksavvy.com>
     [not found]                                               ` <8761dgze56.fsf@x220.int.ebiederm.org>
2014-12-15 19:38                                                 ` Serge Hallyn
2014-12-15 20:11                                                   ` Eric W. Biederman
2014-12-15 20:49                                                     ` Serge Hallyn
2014-12-16  2:05                                         ` Andy Lutomirski
2014-12-16  9:23                                           ` Richard Weinberger
2014-12-08 22:14                         ` [CFT][PATCH 7/7] userns: Allow setting gid_maps without privilege when setgroups is disabled Eric W. Biederman
2014-12-08 22:26                           ` Andy Lutomirski
2014-12-02 20:58           ` [CFT][PATCH 1/3] userns: Avoid problems with negative groups Andy Lutomirski
2014-12-02 21:26             ` Eric W. Biederman
2014-12-02 22:09               ` Andy Lutomirski
2014-12-02 22:48                 ` Eric W. Biederman [this message]
2014-12-02 22:56                   ` Andy Lutomirski

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=87wq69pt0q.fsf@x220.int.ebiederm.org \
    --to=ebiederm@xmission.com \
    --cc=akpm@linux-foundation.org \
    --cc=casey@schaufler-ca.com \
    --cc=containers@lists.linux-foundation.org \
    --cc=josh@joshtriplett.org \
    --cc=keescook@chromium.org \
    --cc=kenton@sandstorm.io \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-man@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=mtk.manpages@gmail.com \
    --cc=richard@nod.at \
    --cc=serge@hallyn.com \
    --cc=stable@vger.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®