From 33dd562e3acff71ee18a2543d14fcbecf9bf0e62 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Thu, 8 Mar 2018 12:24:39 -0800 Subject: [PATCH 1/2] daemon/oci_linux_test: add TestIpcPrivateVsReadonly The test case checks that in case of IpcMode: private and ReadonlyRootfs: true (as in "docker run --ipc private --read-only") the resulting /dev/shm mount is NOT made read-only. Signed-off-by: Kir Kolyshkin --- daemon/oci_linux_test.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/daemon/oci_linux_test.go b/daemon/oci_linux_test.go index 4af0ba96d0..f6bda79745 100644 --- a/daemon/oci_linux_test.go +++ b/daemon/oci_linux_test.go @@ -48,3 +48,41 @@ func TestTmpfsDevShmNoDupMount(t *testing.T) { err = setMounts(&d, &s, c, ms) assert.NoError(t, err) } + +// TestIpcPrivateVsReadonly checks that in case of IpcMode: private +// and ReadonlyRootfs: true (as in "docker run --ipc private --read-only") +// the resulting /dev/shm mount is NOT made read-only. +// https://github.com/moby/moby/issues/36503 +func TestIpcPrivateVsReadonly(t *testing.T) { + d := Daemon{ + // some empty structs to avoid getting a panic + // caused by a null pointer dereference + idMappings: &idtools.IDMappings{}, + configStore: &config.Config{}, + } + c := &container.Container{ + HostConfig: &containertypes.HostConfig{ + IpcMode: containertypes.IpcMode("private"), + ReadonlyRootfs: true, + }, + } + + // We can't call createSpec() so mimick the minimal part + // of its code flow, just enough to reproduce the issue. + ms, err := d.setupMounts(c) + assert.NoError(t, err) + + s := oci.DefaultSpec() + s.Root.Readonly = c.HostConfig.ReadonlyRootfs + + err = setMounts(&d, &s, c, ms) + assert.NoError(t, err) + + // Find the /dev/shm mount in ms, check it does not have ro + for _, m := range s.Mounts { + if m.Destination != "/dev/shm" { + continue + } + assert.Equal(t, false, inSlice(m.Options, "ro")) + } +} From cad74056c09f6276b0f4a996a1511553177cd3d7 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Wed, 7 Mar 2018 20:14:16 -0800 Subject: [PATCH 2/2] daemon/setMounts(): do not make /dev/shm ro It has been pointed out that if --read-only flag is given, /dev/shm also becomes read-only in case of --ipc private. This happens because in this case the mount comes from OCI spec (since commit 7120976d74195), and is a regression caused by that commit. The meaning of --read-only flag is to only have a "main" container filesystem read-only, not the auxiliary stuff (that includes /dev/shm, other mounts and volumes, --tmpfs, /proc, /dev and so on). So, let's make sure /dev/shm that comes from OCI spec is not made read-only. Fixes: 7120976d74195 ("Implement none, private, and shareable ipc modes") Signed-off-by: Kir Kolyshkin --- daemon/oci_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go index 15bcb705bf..8d5eebb885 100644 --- a/daemon/oci_linux.go +++ b/daemon/oci_linux.go @@ -667,7 +667,7 @@ func setMounts(daemon *Daemon, s *specs.Spec, c *container.Container, mounts []c if s.Root.Readonly { for i, m := range s.Mounts { switch m.Destination { - case "/proc", "/dev/pts", "/dev/mqueue", "/dev": + case "/proc", "/dev/pts", "/dev/shm", "/dev/mqueue", "/dev": continue } if _, ok := userMounts[m.Destination]; !ok {