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
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; }
But the selinux hook is supposed to call the capability check. (well, before the stacking, where the LSM calls the cap hook first)
Yeah ... yeah ... for some reason I've always had a mental block that the LSMs are responsible for the capable() calls.
Dan, what kernel are you using?
uname -r 4.1.0-1.fc23.x86_64
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...
I am back to using confined users again, and chrome is blowing up on me. :^(
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
I agree, we are blocking this on RHEL, but not Fedora.
(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?)
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.
(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.
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>