From c94111b61988ad32d87f99d4421cbcde018c3fb4 Mon Sep 17 00:00:00 2001 From: Kevin Wallace Date: Sun, 1 Dec 2013 15:27:24 -0800 Subject: [PATCH] Allow non-privileged containers to create device nodes. Such nodes could already be created by importing a tarball to a container; now they can be created from within the container itself. This gives non-privileged containers the mknod kernel capability, and modifies their cgroup settings to allow creation of *any* node, not just whitelisted ones. Use of such nodes is still controlled by the existing cgroup whitelist. Docker-DCO-1.1-Signed-off-by: Kevin Wallace (github: kevinwallace) --- integration/container_test.go | 8 ++++---- pkg/cgroups/apply_raw.go | 4 ++++ runtime/execdriver/lxc/init.go | 1 - runtime/execdriver/lxc/lxc_template.go | 4 ++++ runtime/execdriver/native/template/default_template.go | 1 - 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/integration/container_test.go b/integration/container_test.go index d3d35734ed..c64f9e610b 100644 --- a/integration/container_test.go +++ b/integration/container_test.go @@ -1619,16 +1619,16 @@ func TestPrivilegedCanMount(t *testing.T) { } } -func TestPrivilegedCannotMknod(t *testing.T) { +func TestUnprivilegedCanMknod(t *testing.T) { eng := NewTestEngine(t) runtime := mkRuntimeFromEngine(eng, t) defer runtime.Nuke() - if output, _ := runContainer(eng, runtime, []string{"_", "sh", "-c", "mknod /tmp/sda b 8 0 || echo ok"}, t); output != "ok\n" { - t.Fatal("Could mknod into secure container") + if output, _ := runContainer(eng, runtime, []string{"_", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok"}, t); output != "ok\n" { + t.Fatal("Couldn't mknod into secure container") } } -func TestPrivilegedCannotMount(t *testing.T) { +func TestUnprivilegedCannotMount(t *testing.T) { eng := NewTestEngine(t) runtime := mkRuntimeFromEngine(eng, t) defer runtime.Nuke() diff --git a/pkg/cgroups/apply_raw.go b/pkg/cgroups/apply_raw.go index 5fe317937a..220f08f1dc 100644 --- a/pkg/cgroups/apply_raw.go +++ b/pkg/cgroups/apply_raw.go @@ -95,6 +95,10 @@ func (raw *rawCgroup) setupDevices(c *Cgroup, pid int) (err error) { } allow := []string{ + // allow mknod for any device + "c *:* m", + "b *:* m", + // /dev/null, zero, full "c 1:3 rwm", "c 1:5 rwm", diff --git a/runtime/execdriver/lxc/init.go b/runtime/execdriver/lxc/init.go index a64bca15b2..c1933a5e43 100644 --- a/runtime/execdriver/lxc/init.go +++ b/runtime/execdriver/lxc/init.go @@ -144,7 +144,6 @@ func setupCapabilities(args *execdriver.InitArgs) error { capability.CAP_SYS_RESOURCE, capability.CAP_SYS_TIME, capability.CAP_SYS_TTY_CONFIG, - capability.CAP_MKNOD, capability.CAP_AUDIT_WRITE, capability.CAP_AUDIT_CONTROL, capability.CAP_MAC_OVERRIDE, diff --git a/runtime/execdriver/lxc/lxc_template.go b/runtime/execdriver/lxc/lxc_template.go index e5248375a8..bad3249b31 100644 --- a/runtime/execdriver/lxc/lxc_template.go +++ b/runtime/execdriver/lxc/lxc_template.go @@ -44,6 +44,10 @@ lxc.cgroup.devices.allow = a # no implicit access to devices lxc.cgroup.devices.deny = a +# but allow mknod for any device +lxc.cgroup.devices.allow = c *:* m +lxc.cgroup.devices.allow = b *:* m + # /dev/null and zero lxc.cgroup.devices.allow = c 1:3 rwm lxc.cgroup.devices.allow = c 1:5 rwm diff --git a/runtime/execdriver/native/template/default_template.go b/runtime/execdriver/native/template/default_template.go index b9eb87713e..6828812336 100644 --- a/runtime/execdriver/native/template/default_template.go +++ b/runtime/execdriver/native/template/default_template.go @@ -18,7 +18,6 @@ func New() *libcontainer.Container { libcontainer.GetCapability("SYS_RESOURCE"), libcontainer.GetCapability("SYS_TIME"), libcontainer.GetCapability("SYS_TTY_CONFIG"), - libcontainer.GetCapability("MKNOD"), libcontainer.GetCapability("AUDIT_WRITE"), libcontainer.GetCapability("AUDIT_CONTROL"), libcontainer.GetCapability("MAC_OVERRIDE"),