Skip to content

Commit 5bf6a13

Browse files
Userns container in containers
Enables launching userns containers by catching EPERM errors for writing to devices cgroups, and for mknod invocations. Signed-off-by: Abin Shahab <ashahab@altiscale.com>
1 parent 2a6ae44 commit 5bf6a13

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

libcontainer/cgroups/fs/devices.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package fs
55
import (
66
"github.com/opencontainers/runc/libcontainer/cgroups"
77
"github.com/opencontainers/runc/libcontainer/configs"
8+
"os"
89
)
910

1011
type DevicesGroup struct {
@@ -28,23 +29,35 @@ func (s *DevicesGroup) Apply(d *data) error {
2829
func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) error {
2930
if !cgroup.AllowAllDevices {
3031
if err := writeFile(path, "devices.deny", "a"); err != nil {
32+
if os.IsPermission(err) {
33+
return nil
34+
}
3135
return err
3236
}
3337

3438
for _, dev := range cgroup.AllowedDevices {
3539
if err := writeFile(path, "devices.allow", dev.CgroupString()); err != nil {
40+
if os.IsPermission(err) {
41+
return nil
42+
}
3643
return err
3744
}
3845
}
3946
return nil
4047
}
4148

4249
if err := writeFile(path, "devices.allow", "a"); err != nil {
50+
if os.IsPermission(err) {
51+
return nil
52+
}
4353
return err
4454
}
4555

4656
for _, dev := range cgroup.DeniedDevices {
4757
if err := writeFile(path, "devices.deny", dev.CgroupString()); err != nil {
58+
if os.IsPermission(err) {
59+
return nil
60+
}
4861
return err
4962
}
5063
}

libcontainer/rootfs_linux.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,17 @@ func createDevices(config *configs.Config) error {
379379
return nil
380380
}
381381

382+
func bindMountDeviceNode(dest string, node *configs.Device) error {
383+
f, err := os.Create(dest)
384+
if err != nil && !os.IsExist(err) {
385+
return err
386+
}
387+
if f != nil {
388+
f.Close()
389+
}
390+
return syscall.Mount(node.Path, dest, "bind", syscall.MS_BIND, "")
391+
}
392+
382393
// Creates the device node in the rootfs of the container.
383394
func createDeviceNode(rootfs string, node *configs.Device, bind bool) error {
384395
dest := filepath.Join(rootfs, node.Path)
@@ -387,18 +398,13 @@ func createDeviceNode(rootfs string, node *configs.Device, bind bool) error {
387398
}
388399

389400
if bind {
390-
f, err := os.Create(dest)
391-
if err != nil && !os.IsExist(err) {
392-
return err
393-
}
394-
if f != nil {
395-
f.Close()
396-
}
397-
return syscall.Mount(node.Path, dest, "bind", syscall.MS_BIND, "")
401+
return bindMountDeviceNode(dest, node)
398402
}
399403
if err := mknodDevice(dest, node); err != nil {
400404
if os.IsExist(err) {
401405
return nil
406+
} else if os.IsPermission(err) {
407+
return bindMountDeviceNode(dest, node)
402408
}
403409
return err
404410
}
@@ -634,7 +640,6 @@ func remount(m *configs.Mount, rootfs string) error {
634640
if !strings.HasPrefix(dest, rootfs) {
635641
dest = filepath.Join(rootfs, dest)
636642
}
637-
638643
if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags|syscall.MS_REMOUNT), ""); err != nil {
639644
return err
640645
}

0 commit comments

Comments
 (0)