Skip to content

Commit 913c9b1

Browse files
committed
Delay unshare of CLONE_NEWIPC for SELinux
We ensure that mqueue is owned by user namespace root by unsharing CLONE_NEWIPC after we become user namespace root. This allows us to apply the container SELinux label to mqueue. Signed-off-by: Mrunal Patel <[email protected]>
1 parent bb40664 commit 913c9b1

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

libcontainer/nsenter/nsexec.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -632,14 +632,24 @@ void nsexec(void)
632632
/*
633633
* Unshare all of the namespaces. Now, it should be noted that this
634634
* ordering might break in the future (especially with rootless
635-
* containers). But for now, it's not possible to split this into
636-
* CLONE_NEWUSER + [the rest] because of some RHEL SELinux issues.
635+
* containers).
636+
*
637+
* CLONE_NEWIPC needs special handling here when CLONE_NEWUSER is
638+
* also specified to ensure that the user namespace root owns
639+
* mqueue. For that case, we unshare CLONE_NEWIPC after
640+
* switching to root user in the user namespace, so we can apply
641+
* the SELinux label to mqueue.
637642
*
638643
* Note that we don't merge this with clone() because there were
639644
* some old kernel versions where clone(CLONE_PARENT | CLONE_NEWPID)
640645
* was broken, so we'll just do it the long way anyway.
641646
*/
642-
if (unshare(config.cloneflags) < 0)
647+
uint32_t apply_cloneflags = config.cloneflags;
648+
if ((config.cloneflags & CLONE_NEWUSER) && (config.cloneflags & CLONE_NEWIPC)) {
649+
apply_cloneflags &= ~CLONE_NEWIPC;
650+
}
651+
652+
if (unshare(apply_cloneflags) < 0)
643653
bail("failed to unshare namespaces");
644654

645655
/*
@@ -735,6 +745,12 @@ void nsexec(void)
735745
if (setgroups(0, NULL) < 0)
736746
bail("setgroups failed");
737747

748+
/* Unshare CLONE_NEWIPC after becoming root in user namespace */
749+
if ((config.cloneflags & CLONE_NEWUSER) && (config.cloneflags & CLONE_NEWIPC)) {
750+
if (unshare(CLONE_NEWIPC) < 0)
751+
bail("unshare ipc failed");
752+
}
753+
738754
s = SYNC_CHILD_READY;
739755
if (write(syncfd, &s, sizeof(s)) != sizeof(s))
740756
bail("failed to sync with patent: write(SYNC_CHILD_READY)");

0 commit comments

Comments
 (0)