From 3d3a2b38b4c8c7ae5861c9341c999ab68829a9de Mon Sep 17 00:00:00 2001 From: lifubang Date: Thu, 3 Aug 2023 08:44:00 +0800 Subject: [PATCH 1/2] fix some file mode bits missing when doing mount syscall Signed-off-by: lifubang (cherry picked from commit 6092a4b42dc0ab0df9aa55dbdb4e6db6c490e14d) --- libcontainer/mount_linux.go | 18 ++++++++++++++++++ libcontainer/rootfs_linux.go | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/libcontainer/mount_linux.go b/libcontainer/mount_linux.go index 5f49de964..948b6c0b4 100644 --- a/libcontainer/mount_linux.go +++ b/libcontainer/mount_linux.go @@ -1,6 +1,7 @@ package libcontainer import ( + "io/fs" "strconv" "golang.org/x/sys/unix" @@ -81,3 +82,20 @@ func unmount(target string, flags int) error { } return nil } + +// syscallMode returns the syscall-specific mode bits from Go's portable mode bits. +// Copy from https://cs.opensource.google/go/go/+/refs/tags/go1.20.7:src/os/file_posix.go;l=61-75 +func syscallMode(i fs.FileMode) (o uint32) { + o |= uint32(i.Perm()) + if i&fs.ModeSetuid != 0 { + o |= unix.S_ISUID + } + if i&fs.ModeSetgid != 0 { + o |= unix.S_ISGID + } + if i&fs.ModeSticky != 0 { + o |= unix.S_ISVTX + } + // No mapping for Go's ModeTemporary (plan9 only). + return +} diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index 54520ad01..c701d6a2f 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -464,7 +464,7 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error { return err } } else { - dt := fmt.Sprintf("mode=%04o", stat.Mode()) + dt := fmt.Sprintf("mode=%04o", syscallMode(stat.Mode())) if m.Data != "" { dt = dt + "," + m.Data } From aaed58c87b4e0f0174c050803105f5a1139d2130 Mon Sep 17 00:00:00 2001 From: lifubang Date: Thu, 3 Aug 2023 08:46:37 +0800 Subject: [PATCH 2/2] add a test case about missing stricky bit Signed-off-by: lifubang (cherry picked from commit 83137c6884a4838ae03baa8b7f311729cc93c285) Signed-off-by: lifubang --- tests/integration/run.bats | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/integration/run.bats b/tests/integration/run.bats index d2eae2a08..e59ccb4a4 100644 --- a/tests/integration/run.bats +++ b/tests/integration/run.bats @@ -59,6 +59,22 @@ function teardown() { [ "$status" -ne 0 ] } +# https://github.com/opencontainers/runc/issues/3952 +@test "runc run with tmpfs" { + requires root + + chmod 'a=rwx,ug+s,+t' rootfs/tmp # set all bits + mode=$(stat -c %A rootfs/tmp) + + # shellcheck disable=SC2016 + update_config '.process.args = ["sh", "-c", "stat -c %A /tmp"]' + update_config '.mounts += [{"destination": "/tmp", "type": "tmpfs", "source": "tmpfs", "options":["noexec","nosuid","nodev","rprivate"]}]' + + runc run test_tmpfs + [ "$status" -eq 0 ] + [ "$output" = "$mode" ] +} + @test "runc run with tmpfs perms" { # shellcheck disable=SC2016 update_config '.process.args = ["sh", "-c", "stat -c %a /tmp/test"]'