Bug 1236256 - BUG: SELinux is checking for SYS_ADMIN when user namespace is created.
Summary: BUG: SELinux is checking for SYS_ADMIN when user namespace is created.
Keywords:
Status: CLOSED UPSTREAM
Alias: None
Product: Fedora
Classification: Fedora
Component: kernel
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Paul Moore
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-06-27 01:59 UTC by Daniel Walsh
Modified: 2016-06-02 19:50 UTC (History)
10 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2016-06-02 19:50:24 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Daniel Walsh 2015-06-27 01:59:26 UTC
google-chrome is blowing up on a non SUID application when run by staff_t.

I believe the clone call should not be checking sys_admin if the user specifies CLONE_NEWUSER, since this works with SELinux disabled, their must not be a check for DAC.

clone(child_stack=0x7fffb96e65b0, flags=CLONE_NEWUSER|CLONE_NEWPID|CLONE_NEWNET|SIGCHLD) = -1 EPERM (Operation not permitted)
rt_sigprocmask(SIG_SETMASK, [], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
tgkill(20009, 20009, SIGABRT)           = 0
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=20009, si_uid=3267} ---
+++ killed by SIGABRT (core dumped) +++
Aborted (core dumped)
[Exit 134 (SIGABRT)]


type=AVC msg=audit(06/26/2015 21:57:25.288:4293) : avc:  denied  { sys_admin } for  pid=20009 comm=chrome capability=sys_admin  scontext=staff_u:s
taff_r:staff_t:s0-s0:c0.c1023 tcontext=staff_u:staff_r:staff_t:s0-s0:c0.c1023 tclass=capability permissive=0

Comment 1 Paul Moore 2015-06-29 14:26:46 UTC
It looks like as part of fork.c:copy_process() in the kernel we explicitly call nsproxy.c:copy_namespaces() which does a ns_capable(CAP_SYS_ADMIN) call which eventually results in a SELinux capability:sys_admin check.

What is really interesting is that ns_capable() doesn't actually perform any DAC checks, it only performs a sanity check on the requested capability and then calls security_capable() to do the LSM/SELinux check:

bool ns_capable(struct user_namespace *ns, int cap)
{
        if (unlikely(!cap_valid(cap))) {
                pr_crit("capable() called with invalid cap=%u\n", cap);
                BUG();
        }

        if (security_capable(current_cred(), ns, cap) == 0) {
                current->flags |= PF_SUPERPRIV;
                return true;
        }
        return false;
}

Comment 2 Eric Paris 2015-06-29 14:30:23 UTC
But the selinux hook is supposed to call the capability check. (well, before the stacking, where the LSM calls the cap hook first)

Comment 3 Paul Moore 2015-06-29 14:41:34 UTC
Yeah ... yeah ... for some reason I've always had a mental block that the LSMs are responsible for the capable() calls.

Comment 4 Paul Moore 2015-06-29 14:42:03 UTC
Dan, what kernel are you using?

Comment 5 Daniel Walsh 2015-06-30 11:27:43 UTC
uname -r
4.1.0-1.fc23.x86_64

Comment 6 Stephen Smalley 2015-07-06 13:59:17 UTC
I believe this is the same issue we previously discussed by email.  cap_capable() implicitly grants all capabilities to the owner of the user namespace in the parent of the user namespace.  Therefore, an unprivileged process can create its own user namespace and can then create its own mount and other namespaces at will.  selinux_capable() does not presently take the namespace into account in any way.  As discussed by that earlier email thread, we could possibly have selinux_capable() mirror the logic in cap_capable() to determine whether the process is the owner of the user namespace in the parent of the user namespace, and if so, apply a different permission check in that situation if we truly want to distinguish them.  Whether or not that is a good idea is another matter; there have been a few vulnerabilities discovered since they opened up this can of worms via user namespaces...

Comment 7 Daniel Walsh 2016-03-10 19:15:01 UTC
I am back to using confined users again, and chrome is blowing up on me. :^(

Comment 8 Stephen Smalley 2016-03-10 20:08:01 UTC
Some distros at least are restricting creating user namespaces since they expose a much greater attack surface.
See http://thread.gmane.org/gmane.linux.kernel.containers/30076/focus=30088

Comment 9 Daniel Walsh 2016-03-10 20:21:18 UTC
I agree, we are blocking this on RHEL, but not Fedora.

Comment 10 Josh Boyer 2016-03-10 20:28:24 UTC
(In reply to Stephen Smalley from comment #8)
> Some distros at least are restricting creating user namespaces since they
> expose a much greater attack surface.
> See http://thread.gmane.org/gmane.linux.kernel.containers/30076/focus=30088

That doesn't actually solve the problem though, does it?  It seems to me that disallowing userns here would simply mask the issue, which is that SELinux and userns aren't getting along.

(Also, wouldn't disallowing Chrome to use userns decrease its security by disabling its ability to sandbox itself?)

Comment 11 Daniel Walsh 2016-03-10 20:37:47 UTC
I guess the question would be which brings the bigger security risk, enabling User Namespace from non privileged users or dropping usernamespace support from chrome-sandbox.  I believe chrome-sandbox falls back to different sandboxing, if User Namespace is not available.

Comment 12 Josh Boyer 2016-03-10 20:48:27 UTC
(In reply to Daniel Walsh from comment #11)
> I guess the question would be which brings the bigger security risk,
> enabling User Namespace from non privileged users or dropping usernamespace
> support from chrome-sandbox.  I believe chrome-sandbox falls back to
> different sandboxing, if User Namespace is not available.

Fair point.

As an aside, Fedora used to also block userns if one didn't have root privileges in the past.  However, the implementation used actually didn't cover all the ways users could create user namespaces and wound up providing no additional security.  I've been following the upstream discussions for a while now and I'd be amenable to using something that looked like it was headed upstream.  Unfortunately, nobody has seemed to come up with such a solution.  Even the solution Ubuntu is carrying is temporary according to the developers.

Comment 13 Paul Moore 2016-06-02 19:50:24 UTC
Marking this as CLOSED/UPSTREAM as I believe we have resolved this with the following commit (v4.7-rc1):

  commit 8e4ff6f228e4722cac74db716e308d1da33d744f
  Author: Stephen Smalley <sds.gov>
  Date:   Fri Apr 8 13:52:00 2016 -0400

    selinux: distinguish non-init user namespace capability checks
    
    Distinguish capability checks against a target associated
    with the init user namespace versus capability checks against
    a target associated with a non-init user namespace by defining
    and using separate security classes for the latter.
    
    This is needed to support e.g. Chrome usage of user namespaces
    for the Chrome sandbox without needing to allow Chrome to also
    exercise capabilities on targets in the init user namespace.
    
    Suggested-by: Dan Walsh <dwalsh>
    Signed-off-by: Stephen Smalley <sds.gov>
    Signed-off-by: Paul Moore <paul>


Note You need to log in before you can comment on or make changes to this bug.