Skip to content

Commit fa93c8b

Browse files
committed
tests: mounts: add some tests to check mount ordering
Our previous implementation of idmapped mounts and bind-mount sources would open all of the source paths before we did any mounts, meaning that mounts using sources from inside the container rootfs would not be correct. This has been fixed with the new on-demand system, and so add some regression tests. Signed-off-by: Aleksa Sarai <[email protected]>
1 parent 3b57e45 commit fa93c8b

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

tests/integration/mounts.bats

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,109 @@ function test_ro_cgroup_mount() {
2424
for line in "${lines[@]}"; do [[ "${line}" == *'ro,'* ]]; done
2525
}
2626

27+
# Parse an "optstring" of the form foo,bar into $is_foo and $is_bar variables.
28+
# Usage: parse_optstring foo,bar foo bar baz
29+
function parse_optstring() {
30+
optstring="$1"
31+
shift
32+
33+
for flag in "$@"; do
34+
is_set=
35+
if grep -wq "$flag" <<<"$optstring"; then
36+
is_set=1
37+
fi
38+
eval "is_$flag=$is_set"
39+
done
40+
}
41+
42+
function config_add_bind_mount() {
43+
src="$1"
44+
dst="$2"
45+
parse_optstring "${3:-}" rbind idmap
46+
47+
bindtype=bind
48+
if [ -n "$is_rbind" ]; then
49+
bindtype=rbind
50+
fi
51+
52+
mappings=""
53+
if [ -n "$is_idmap" ]; then
54+
mappings='
55+
"uidMappings": [{"containerID": 0, "hostID": 100000, "size": 65536}],
56+
"gidMappings": [{"containerID": 0, "hostID": 100000, "size": 65536}],
57+
'
58+
fi
59+
60+
update_config '.mounts += [{
61+
"source": "'"$src"'",
62+
"destination": "'"$dst"'",
63+
"type": "bind",
64+
'"$mappings"'
65+
"options": [ "'"$bindtype"'", "rprivate" ]
66+
}]'
67+
}
68+
69+
# This needs to be placed at the top of the bats file to work around
70+
# a shellcheck bug. See <https://github.com/koalaman/shellcheck/issues/2873>.
71+
function test_mount_order() {
72+
parse_optstring "${1:-}" userns idmap
73+
74+
if [ -n "$is_userns" ]; then
75+
requires root
76+
77+
update_config '.linux.namespaces += [{"type": "user"}]
78+
| .linux.uidMappings += [{"containerID": 0, "hostID": 100000, "size": 65536}]
79+
| .linux.gidMappings += [{"containerID": 0, "hostID": 100000, "size": 65536}]'
80+
remap_rootfs
81+
fi
82+
83+
ctr_src_opts="rbind"
84+
if [ -n "$is_idmap" ]; then
85+
requires root
86+
requires_kernel 5.12
87+
requires_idmap_fs .
88+
89+
ctr_src_opts+=",idmap"
90+
fi
91+
92+
mkdir -p rootfs/{mnt,final}
93+
# Create a set of directories we can create a mount tree with.
94+
for subdir in a/x b/y c/z; do
95+
dir="bind-src/$subdir"
96+
mkdir -p "$dir"
97+
echo "$subdir" >"$dir/file"
98+
# Add a symlink to make sure
99+
topdir="$(dirname "$subdir")"
100+
ln -s "$topdir" "bind-src/sym-$topdir"
101+
done
102+
# In userns tests, make sure that the source directory cannot be accessed,
103+
# to make sure we're exercising the bind-mount source fd logic.
104+
chmod o-rwx bind-src
105+
106+
rootfs="$(pwd)/rootfs"
107+
rm -rf rootfs/mnt
108+
mkdir rootfs/mnt
109+
110+
# Create a bind-mount tree.
111+
config_add_bind_mount "$PWD/bind-src/a" "/mnt"
112+
config_add_bind_mount "$PWD/bind-src/sym-b" "/mnt/x"
113+
config_add_bind_mount "$PWD/bind-src/c" "/mnt/x/y"
114+
config_add_bind_mount "$PWD/bind-src/sym-a" "/mnt/x/y/z"
115+
# Create a recursive bind-mount that uses part of the current tree in the
116+
# container.
117+
config_add_bind_mount "$rootfs/mnt/x" "$rootfs/mnt/x/y/z/x" "$ctr_src_opts"
118+
config_add_bind_mount "$rootfs/mnt/x/y" "$rootfs/mnt/x/y/z" "$ctr_src_opts"
119+
# Finally, bind-mount the whole thing on top of /final.
120+
config_add_bind_mount "$rootfs/mnt" "$rootfs/final" "$ctr_src_opts"
121+
122+
# Check that the entire tree was copied and the mounts were done in the
123+
# expected order.
124+
update_config '.process.args = ["cat", "/final/x/y/z/z/x/y/z/x/file"]'
125+
runc run test_busybox
126+
[ "$status" -eq 0 ]
127+
[[ "$output" == *"a/x"* ]] # the final "file" was from a/x.
128+
}
129+
27130
# https://github.com/opencontainers/runc/issues/3991
28131
@test "runc run [tmpcopyup]" {
29132
mkdir -p rootfs/dir1/dir2
@@ -108,3 +211,19 @@ function test_ro_cgroup_mount() {
108211
update_config '.linux.namespaces |= if index({"type": "cgroup"}) then . else . + [{"type": "cgroup"}] end'
109212
test_ro_cgroup_mount
110213
}
214+
215+
@test "runc run [mount order, container bind-mount source]" {
216+
test_mount_order
217+
}
218+
219+
@test "runc run [mount order, container bind-mount source] (userns)" {
220+
test_mount_order userns
221+
}
222+
223+
@test "runc run [mount order, container idmap source]" {
224+
test_mount_order idmap
225+
}
226+
227+
@test "runc run [mount order, container idmap source] (userns)" {
228+
test_mount_order userns,idmap
229+
}

0 commit comments

Comments
 (0)