Skip to content

Commit 7df8b4a

Browse files
Userns container in containers
Added a check on devices for hosts that are themselves usernamespaced containers. It is not possible for a non-root host process to set the devices.allow and devices.deny, and therefore this patch skips that for host processes which have a non-root uid_map. Signed-off-by: Abin Shahab <ashahab@altiscale.com>
1 parent 2a6ae44 commit 7df8b4a

5 files changed

Lines changed: 20 additions & 6 deletions

File tree

libcontainer/cgroups/fs/devices.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ func (s *DevicesGroup) Apply(d *data) error {
2626
}
2727

2828
func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) error {
29+
if cgroup.IsHostUnprivileged {
30+
return nil
31+
}
2932
if !cgroup.AllowAllDevices {
3033
if err := writeFile(path, "devices.deny", "a"); err != nil {
3134
return err

libcontainer/configs/cgroup.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type Cgroup struct {
2424

2525
DeniedDevices []*Device `json:"denied_devices"`
2626

27+
IsHostUnprivileged bool `json:"isHostUnprivileged"`
2728
// Memory limit (in bytes)
2829
Memory int64 `json:"memory"`
2930

libcontainer/configs/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ type Syscall struct {
7272

7373
// Config defines configuration options for executing a process inside a contained environment.
7474
type Config struct {
75+
// Indicates if the host is unprivileged
76+
// Used by libcontainer to check whether to mknod and write to devices cgroup
77+
IsHostUnprivileged bool `json:"isHostUnprivileged"`
7578
// NoPivotRoot will use MS_MOVE and a chroot to jail the process into the container's rootfs
7679
// This is a common option when the container is running in ramdisk
7780
NoPivotRoot bool `json:"no_pivot_root"`

libcontainer/rootfs_linux.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,13 @@ func createDevices(config *configs.Config) error {
370370
for _, node := range config.Devices {
371371
// containers running in a user namespace are not allowed to mknod
372372
// devices so we can just bind mount it from the host.
373-
if err := createDeviceNode(config.Rootfs, node, config.Namespaces.Contains(configs.NEWUSER)); err != nil {
373+
isHostUserns := config.IsHostUnprivileged
374+
375+
isContainerUserns := config.Namespaces.Contains(configs.NEWUSER)
376+
if err := createDeviceNode(
377+
config.Rootfs,
378+
node,
379+
isContainerUserns || isHostUserns); err != nil {
374380
syscall.Umask(oldMask)
375381
return err
376382
}

spec.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,12 @@ func createLibcontainerConfig(cgroupName string, spec *specs.LinuxSpec, rspec *s
340340
rootfsPath = filepath.Join(cwd, rootfsPath)
341341
}
342342
config := &configs.Config{
343-
Rootfs: rootfsPath,
344-
Capabilities: spec.Linux.Capabilities,
345-
Readonlyfs: spec.Root.Readonly,
346-
Hostname: spec.Hostname,
343+
Rootfs: rootfsPath,
344+
Capabilities: spec.Linux.Capabilities,
345+
Readonlyfs: spec.Root.Readonly,
346+
Hostname: spec.Hostname,
347+
IsHostUnprivileged: rspec.Linux.IsHostUnprivileged,
347348
}
348-
349349
exists := false
350350
if config.RootPropagation, exists = mountPropagationMapping[rspec.Linux.RootfsPropagation]; !exists {
351351
return nil, fmt.Errorf("rootfsPropagation=%v is not supported", rspec.Linux.RootfsPropagation)
@@ -444,6 +444,7 @@ func createCgroupConfig(name string, spec *specs.LinuxRuntimeSpec, devices []*co
444444
AllowedDevices: append(devices, allowedDevices...),
445445
}
446446
r := spec.Linux.Resources
447+
c.IsHostUnprivileged = spec.Linux.IsHostUnprivileged
447448
c.Memory = r.Memory.Limit
448449
c.MemoryReservation = r.Memory.Reservation
449450
c.MemorySwap = r.Memory.Swap

0 commit comments

Comments
 (0)