Skip to content

Commit 7fd08d2

Browse files
committed
runc: port upstream patch for tmpfs mount mode
Signed-off-by: Vighnesh Maheshwari <[email protected]>
1 parent bbb967a commit 7fd08d2

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
From e855129df22621a08a5436a5cb6e9bfff9a9ad0f Mon Sep 17 00:00:00 2001
2+
From: Aleksa Sarai <[email protected]>
3+
Date: Fri, 7 Nov 2025 14:52:09 +1100
4+
Subject: [PATCH] rootfs: only set mode= for tmpfs mount if target already
5+
existed
6+
7+
This was always the intended behaviour but commit 72fbb34f5006 ("rootfs:
8+
switch to fd-based handling of mountpoint targets") regressed it when
9+
adding a mechanism to create a file handle to the target if it didn't
10+
already exist (causing the later stat to always succeed).
11+
12+
A lot of people depend on this functionality, so add some tests to make
13+
sure we don't break it in the future.
14+
15+
Fixes: 72fbb34f5006 ("rootfs: switch to fd-based handling of mountpoint targets")
16+
Signed-off-by: Aleksa Sarai <[email protected]>
17+
(cherry picked from commit 8d0921c4c76cdd527c86251c728e46f071c96337)
18+
Signed-off-by: Aleksa Sarai <[email protected]>
19+
---
20+
libcontainer/rootfs_linux.go | 25 ++++++++--------
21+
tests/integration/mounts.bats | 54 +++++++++++++++++++++++++++++++++++
22+
2 files changed, 66 insertions(+), 13 deletions(-)
23+
24+
diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go
25+
index 204e6a80fc1..ab5a260dae8 100644
26+
--- a/libcontainer/rootfs_linux.go
27+
+++ b/libcontainer/rootfs_linux.go
28+
@@ -511,6 +511,18 @@ func (m *mountEntry) createOpenMountpoint(rootfs string) (Err error) {
29+
_ = dstFile.Close()
30+
}
31+
}()
32+
+ if err == nil && m.Device == "tmpfs" {
33+
+ // If the original target exists, copy the mode for the tmpfs mount.
34+
+ stat, err := dstFile.Stat()
35+
+ if err != nil {
36+
+ return fmt.Errorf("check tmpfs source mode: %w", err)
37+
+ }
38+
+ dt := fmt.Sprintf("mode=%04o", syscallMode(stat.Mode()))
39+
+ if m.Data != "" {
40+
+ dt = dt + "," + m.Data
41+
+ }
42+
+ m.Data = dt
43+
+ }
44+
if err != nil {
45+
if !errors.Is(err, unix.ENOENT) {
46+
return fmt.Errorf("lookup mountpoint target: %w", err)
47+
@@ -551,19 +563,6 @@ func (m *mountEntry) createOpenMountpoint(rootfs string) (Err error) {
48+
}
49+
}
50+
51+
- if m.Device == "tmpfs" {
52+
- // If the original target exists, copy the mode for the tmpfs mount.
53+
- stat, err := dstFile.Stat()
54+
- if err != nil {
55+
- return fmt.Errorf("check tmpfs source mode: %w", err)
56+
- }
57+
- dt := fmt.Sprintf("mode=%04o", syscallMode(stat.Mode()))
58+
- if m.Data != "" {
59+
- dt = dt + "," + m.Data
60+
- }
61+
- m.Data = dt
62+
- }
63+
-
64+
dstFullPath, err := procfs.ProcSelfFdReadlink(dstFile)
65+
if err != nil {
66+
return fmt.Errorf("get mount destination real path: %w", err)
67+
diff --git a/tests/integration/mounts.bats b/tests/integration/mounts.bats
68+
index 11fb2cfc63e..2da17df2706 100644
69+
--- a/tests/integration/mounts.bats
70+
+++ b/tests/integration/mounts.bats
71+
@@ -234,6 +234,60 @@ function test_mount_order() {
72+
[[ "$(stat -c %a rootfs/setgid/a/b/c)" == 2755 ]]
73+
}
74+
75+
+# https://github.com/opencontainers/runc/issues/4971
76+
+@test "runc run [tmpfs mount mode= inherit]" {
77+
+ mkdir rootfs/tmpfs
78+
+ chmod "=0710" rootfs/tmpfs
79+
+
80+
+ update_config '.mounts += [{
81+
+ type: "tmpfs",
82+
+ source: "tmpfs",
83+
+ destination: "/tmpfs",
84+
+ options: ["rw", "nodev", "nosuid"]
85+
+ }]'
86+
+ update_config '.process.args = ["stat", "-c", "%a", "/tmpfs"]'
87+
+
88+
+ runc run test_busybox
89+
+ [ "$status" -eq 0 ]
90+
+ [[ "$output" == "710" ]]
91+
+
92+
+ update_config '.process.args = ["cat", "/proc/self/mounts"]'
93+
+ runc run test_busybox
94+
+ [ "$status" -eq 0 ]
95+
+ grep -Ex "tmpfs /tmpfs tmpfs [^ ]*\bmode=710\b[^ ]* .*" <<<"$output"
96+
+}
97+
+
98+
+# https://github.com/opencontainers/runc/issues/4971
99+
+@test "runc run [tmpfs mount mode=1777 default]" {
100+
+ update_config '.mounts += [{
101+
+ type: "tmpfs",
102+
+ source: "tmpfs",
103+
+ destination: "/non-existent/foo/bar/baz",
104+
+ options: ["rw", "nodev", "nosuid"]
105+
+ }]'
106+
+ update_config '.process.args = ["stat", "-c", "%a", "/non-existent/foo/bar/baz"]'
107+
+
108+
+ rm -rf rootfs/non-existent
109+
+ runc run test_busybox
110+
+ [ "$status" -eq 0 ]
111+
+ [[ "$output" == "1777" ]]
112+
+
113+
+ update_config '.process.args = ["cat", "/proc/self/mounts"]'
114+
+
115+
+ rm -rf rootfs/non-existent
116+
+ runc run test_busybox
117+
+ [ "$status" -eq 0 ]
118+
+ # We don't explicitly set a mode= in this case, it is just the tmpfs default.
119+
+ grep -Ex "tmpfs /non-existent/foo/bar/baz tmpfs .*" <<<"$output"
120+
+ run ! grep -Ex "tmpfs /non-existent/foo/bar/baz tmpfs [^ ]*\bmode=[0-7]+\b[^ ]* .*" <<<"$output"
121+
+
122+
+ # Verify that the actual modes are *not* 1777.
123+
+ [[ "$(stat -c %a rootfs/non-existent)" == 755 ]]
124+
+ [[ "$(stat -c %a rootfs/non-existent/foo)" == 755 ]]
125+
+ [[ "$(stat -c %a rootfs/non-existent/foo/bar)" == 755 ]]
126+
+ [[ "$(stat -c %a rootfs/non-existent/foo/bar/baz)" == 755 ]]
127+
+}
128+
+
129+
@test "runc run [ro /sys/fs/cgroup mounts]" {
130+
# Without cgroup namespace.
131+
update_config '.linux.namespaces -= [{"type": "cgroup"}]'

packages/runc/runc.spec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Source2: gpgkey-B64E4955B29FA3D463F2A9062897FAD2B7E9446F.asc
2020
# Kir Kolyshkin
2121
Source3: gpgkey-C2428CD75720FACDCF76B6EA17DE5ECB75A1100E.asc
2222

23+
Patch1001: 1001-rootfs-only-set-mode-for-tmpfs-mount.patch
24+
2325
BuildRequires: git
2426
BuildRequires: %{_cross_os}glibc-devel
2527
BuildRequires: %{_cross_os}libseccomp-devel

0 commit comments

Comments
 (0)