Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions libcontainer/rootfs_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,18 @@ func (m *mountEntry) createOpenMountpoint(rootfs string) (Err error) {
_ = dstFile.Close()
}
}()
if err == nil && m.Device == "tmpfs" {
// If the original target exists, copy the mode for the tmpfs mount.
stat, err := dstFile.Stat()
if err != nil {
return fmt.Errorf("check tmpfs source mode: %w", err)
}
dt := fmt.Sprintf("mode=%04o", syscallMode(stat.Mode()))
if m.Data != "" {
dt = dt + "," + m.Data
}
m.Data = dt
}
if err != nil {
if !errors.Is(err, unix.ENOENT) {
return fmt.Errorf("lookup mountpoint target: %w", err)
Expand Down Expand Up @@ -553,19 +565,6 @@ func (m *mountEntry) createOpenMountpoint(rootfs string) (Err error) {
}
}

if m.Device == "tmpfs" {
// If the original target exists, copy the mode for the tmpfs mount.
stat, err := dstFile.Stat()
if err != nil {
return fmt.Errorf("check tmpfs source mode: %w", err)
}
dt := fmt.Sprintf("mode=%04o", syscallMode(stat.Mode()))
if m.Data != "" {
dt = dt + "," + m.Data
}
m.Data = dt
}

dstFullPath, err := procfs.ProcSelfFdReadlink(dstFile)
if err != nil {
return fmt.Errorf("get mount destination real path: %w", err)
Expand Down
81 changes: 81 additions & 0 deletions tests/integration/mounts.bats
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,87 @@ function test_mount_order() {
[[ "$(stat -c %a rootfs/setgid/a/b/c)" == 2755 ]]
}

# https://github.com/opencontainers/runc/issues/4971
@test "runc run [tmpfs mount mode= inherit]" {
mkdir rootfs/tmpfs
chmod "=0710" rootfs/tmpfs

update_config '.mounts += [{
type: "tmpfs",
source: "tmpfs",
destination: "/tmpfs",
options: ["rw", "nodev", "nosuid"]
}]'
update_config '.process.args = ["stat", "-c", "%a", "/tmpfs"]'

runc run test_busybox
[ "$status" -eq 0 ]
[[ "$output" == "710" ]]

update_config '.process.args = ["cat", "/proc/self/mounts"]'
runc run test_busybox
[ "$status" -eq 0 ]
grep -Ex "tmpfs /tmpfs tmpfs [^ ]*\bmode=710\b[^ ]* .*" <<<"$output"
}

# https://github.com/opencontainers/runc/issues/4971
@test "runc run [tmpfs mount explicit mode=]" {
mkdir rootfs/tmpfs
chmod "=0710" rootfs/tmpfs

update_config '.mounts += [{
type: "tmpfs",
source: "tmpfs",
destination: "/tmpfs",
options: ["rw", "nodev", "nosuid", "mode=1500"]
}]'
update_config '.process.args = ["stat", "-c", "%a", "/tmpfs"]'

# Explicitly setting mode= overrides whatever mode we would've inherited.
runc run test_busybox
[ "$status" -eq 0 ]
[[ "$output" == "1500" ]]

update_config '.process.args = ["cat", "/proc/self/mounts"]'
runc run test_busybox
[ "$status" -eq 0 ]
grep -Ex "tmpfs /tmpfs tmpfs [^ ]*\bmode=1500\b[^ ]* .*" <<<"$output"

# Verify that the actual directory was not chmod-ed.
[[ "$(stat -c %a rootfs/tmpfs)" == 710 ]]
}

# https://github.com/opencontainers/runc/issues/4971
@test "runc run [tmpfs mount mode=1777 default]" {
update_config '.mounts += [{
type: "tmpfs",
source: "tmpfs",
destination: "/non-existent/foo/bar/baz",
options: ["rw", "nodev", "nosuid"]
}]'
update_config '.process.args = ["stat", "-c", "%a", "/non-existent/foo/bar/baz"]'

rm -rf rootfs/non-existent
runc run test_busybox
[ "$status" -eq 0 ]
[[ "$output" == "1777" ]]

update_config '.process.args = ["cat", "/proc/self/mounts"]'

rm -rf rootfs/non-existent
runc run test_busybox
[ "$status" -eq 0 ]
# We don't explicitly set a mode= in this case, it is just the tmpfs default.
grep -Ex "tmpfs /non-existent/foo/bar/baz tmpfs .*" <<<"$output"
run ! grep -Ex "tmpfs /non-existent/foo/bar/baz tmpfs [^ ]*\bmode=[0-7]+\b[^ ]* .*" <<<"$output"

# Verify that the actual modes are *not* 1777.
[[ "$(stat -c %a rootfs/non-existent)" == 755 ]]
[[ "$(stat -c %a rootfs/non-existent/foo)" == 755 ]]
[[ "$(stat -c %a rootfs/non-existent/foo/bar)" == 755 ]]
[[ "$(stat -c %a rootfs/non-existent/foo/bar/baz)" == 755 ]]
}

@test "runc run [ro /sys/fs/cgroup mounts]" {
# Without cgroup namespace.
update_config '.linux.namespaces -= [{"type": "cgroup"}]'
Expand Down