Skip to content

Commit 2cd9c31

Browse files
committed
nsenter: guarantee correct user namespace ordering
Depending on your SELinux setup, the order in which you join namespaces can be important. In general, user namespaces should *always* be joined and unshared first because then the other namespaces are correctly pinned and you have the right priviliges within them. This also is very useful for rootless containers, as well as older kernels that had essentially broken unshare(2) and clone(2) implementations. This also includes huge refactorings in how we spawn processes for complicated reasons that I don't want to get into because it will make me spiral into a cloud of rage. The reasoning is in the giant comment in clone_parent. Have fun. In addition, because we now create multiple children with CLONE_PARENT, we cannot wait for them to SIGCHLD us in the case of a death. Thus, we have to resort to having a child kindly send us their exit code before they die. Hopefully this all works okay, but at this point there's not much more than we can do. Signed-off-by: Aleksa Sarai <[email protected]>
1 parent ed053a7 commit 2cd9c31

File tree

3 files changed

+501
-241
lines changed

3 files changed

+501
-241
lines changed

libcontainer/container_linux.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1224,12 +1224,13 @@ func (c *linuxContainer) currentState() (*State, error) {
12241224
func (c *linuxContainer) orderNamespacePaths(namespaces map[configs.NamespaceType]string) ([]string, error) {
12251225
paths := []string{}
12261226
order := []configs.NamespaceType{
1227+
// The user namespace *must* be done first.
1228+
configs.NEWUSER,
12271229
configs.NEWIPC,
12281230
configs.NEWUTS,
12291231
configs.NEWNET,
12301232
configs.NEWPID,
12311233
configs.NEWNS,
1232-
configs.NEWUSER,
12331234
}
12341235

12351236
// Remove namespaces that we don't need to join.

libcontainer/nsenter/namespace.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#ifndef NSENTER_NAMESPACE_H
2+
#define NSENTER_NAMESPACE_H
3+
4+
#ifndef _GNU_SOURCE
5+
# define _GNU_SOURCE
6+
#endif
7+
#include <sched.h>
8+
9+
/* All of these are taken from include/uapi/linux/sched.h */
10+
#ifndef CLONE_NEWNS
11+
# define CLONE_NEWNS 0x00020000 /* New mount namespace group */
12+
#endif
13+
#ifndef CLONE_NEWCGROUP
14+
# define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace */
15+
#endif
16+
#ifndef CLONE_NEWUTS
17+
# define CLONE_NEWUTS 0x04000000 /* New utsname namespace */
18+
#endif
19+
#ifndef CLONE_NEWIPC
20+
# define CLONE_NEWIPC 0x08000000 /* New ipc namespace */
21+
#endif
22+
#ifndef CLONE_NEWUSER
23+
# define CLONE_NEWUSER 0x10000000 /* New user namespace */
24+
#endif
25+
#ifndef CLONE_NEWPID
26+
# define CLONE_NEWPID 0x20000000 /* New pid namespace */
27+
#endif
28+
#ifndef CLONE_NEWNET
29+
# define CLONE_NEWNET 0x40000000 /* New network namespace */
30+
#endif
31+
32+
#endif /* NSENTER_NAMESPACE_H */

0 commit comments

Comments
 (0)