From a2c9866e547b1733393c506a402041eaad39caac Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Mon, 4 Jan 2021 14:53:33 -0800 Subject: [PATCH 1/3] tests/int/mounts.bats: cleanup 1. Make sure that containers created are stopped and removed. This is done by using a predefined test_busybox container name, which is getting removed in teardown_busybox. 2. Fix space at EOL. Signed-off-by: Kir Kolyshkin --- tests/integration/mounts.bats | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/integration/mounts.bats b/tests/integration/mounts.bats index 9b6d31d88..4bc2e134b 100644 --- a/tests/integration/mounts.bats +++ b/tests/integration/mounts.bats @@ -9,14 +9,13 @@ function setup() { function teardown() { teardown_busybox - teardown_running_container test_bind_mount } @test "runc run [bind mount]" { update_config ' .mounts += [{"source": ".", "destination": "/tmp/bind", "options": ["bind"]}] | .process.args |= ["ls", "/tmp/bind/config.json"]' - runc run test_bind_mount + runc run test_busybox [ "$status" -eq 0 ] [[ "${lines[0]}" == *'/tmp/bind/config.json'* ]] } @@ -25,7 +24,7 @@ function teardown() { update_config ' .mounts += [{"source": "tmpfs", "destination": "/mnt", "type": "tmpfs", "options": ["ro", "nodev", "nosuid", "mode=755"]}] | .process.args |= ["grep", "^tmpfs /mnt", "/proc/mounts"]' - runc run test_ro_tmpfs_mount + runc run test_busybox [ "$status" -eq 0 ] [[ "${lines[0]}" == *'ro,'* ]] } From d64c3afe1bc821dc9504d63b7e7be8e65e210184 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Mon, 4 Jan 2021 19:14:13 -0800 Subject: [PATCH 2/3] tests/int/mount.bats: reformat Easier to read mounts. No functional change. Signed-off-by: Kir Kolyshkin --- tests/integration/mounts.bats | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/integration/mounts.bats b/tests/integration/mounts.bats index 4bc2e134b..4be19f50e 100644 --- a/tests/integration/mounts.bats +++ b/tests/integration/mounts.bats @@ -12,7 +12,11 @@ function teardown() { } @test "runc run [bind mount]" { - update_config ' .mounts += [{"source": ".", "destination": "/tmp/bind", "options": ["bind"]}] + update_config ' .mounts += [{ + source: ".", + destination: "/tmp/bind", + options: ["bind"] + }] | .process.args |= ["ls", "/tmp/bind/config.json"]' runc run test_busybox @@ -21,7 +25,12 @@ function teardown() { } @test "runc run [ro tmpfs mount]" { - update_config ' .mounts += [{"source": "tmpfs", "destination": "/mnt", "type": "tmpfs", "options": ["ro", "nodev", "nosuid", "mode=755"]}] + update_config ' .mounts += [{ + source: "tmpfs", + destination: "/mnt", + type: "tmpfs", + options: ["ro", "nodev", "nosuid", "mode=755"] + }] | .process.args |= ["grep", "^tmpfs /mnt", "/proc/mounts"]' runc run test_busybox From 637f82d6b8b45a99519b863f8cf7461760da7a97 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Mon, 4 Jan 2021 20:17:35 -0800 Subject: [PATCH 3/3] runc run: resolve tmpfs mount dest in container scope In case a tmpfs mount path contains absolute symlinks, runc errors out because those symlinks are resolved in the host (rather than container) filesystem scope. The fix is similar to that for bind mounts -- resolve the destination in container rootfs scope using securejoin, and use the resolved path. A simple integration test case is added to prevent future regressions. Fixes https://github.com/opencontainers/runc/issues/2683. Signed-off-by: Kir Kolyshkin --- libcontainer/rootfs_linux.go | 7 +++++++ tests/integration/mounts.bats | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index f9902e85b..2ad61df97 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -340,6 +340,13 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string, enableCgroupns b case "tmpfs": copyUp := m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP tmpDir := "" + // dest might be an absolute symlink, so it needs + // to be resolved under rootfs. + dest, err := securejoin.SecureJoin(rootfs, m.Destination) + if err != nil { + return err + } + m.Destination = dest stat, err := os.Stat(dest) if err != nil { if err := os.MkdirAll(dest, 0755); err != nil { diff --git a/tests/integration/mounts.bats b/tests/integration/mounts.bats index 4be19f50e..a4b9f296e 100644 --- a/tests/integration/mounts.bats +++ b/tests/integration/mounts.bats @@ -37,3 +37,19 @@ function teardown() { [ "$status" -eq 0 ] [[ "${lines[0]}" == *'ro,'* ]] } + +# https://github.com/opencontainers/runc/issues/2683 +@test "runc run [tmpfs mount with absolute symlink]" { + # in container, /conf -> /real/conf + mkdir -p rootfs/real/conf + ln -s /real/conf rootfs/conf + update_config ' .mounts += [{ + type: "tmpfs", + source: "tmpfs", + destination: "/conf/stack", + options: ["ro", "nodev", "nosuid"] + }] + | .process.args |= ["true"]' + runc run test_busybox + [ "$status" -eq 0 ] +}