Skip to content

Commit b6876e9

Browse files
committed
tests: add test for 'weird' external namespace joining
Signed-off-by: Aleksa Sarai <[email protected]>
1 parent 64fc2e0 commit b6876e9

File tree

1 file changed

+60
-1
lines changed

1 file changed

+60
-1
lines changed

tests/integration/userns.bats

+60-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function teardown() {
2929
if [ -v to_umount_list ]; then
3030
while read -r mount_path; do
3131
umount -l "$mount_path" || :
32-
rm -f "$mount_path"
32+
rm -rf "$mount_path"
3333
done <"$to_umount_list"
3434
rm -f "$to_umount_list"
3535
unset to_umount_list
@@ -184,3 +184,62 @@ function teardown() {
184184
grep -E '^\s+0\s+'$EUID'\s+1$' <<<"$output"
185185
fi
186186
}
187+
188+
# <https://github.com/opencontainers/runc/issues/4390>
189+
@test "userns join external namespaces [wrong userns owner]" {
190+
requires root
191+
192+
# Create an external user namespace for us to join (we can't mount from
193+
# inside the user namespace so we need to background it to do the mount
194+
# from the host).
195+
userns_path="$(mktemp "$BATS_RUN_TMPDIR/userns.XXXXXX")"
196+
unshare -U -- sleep 3m &
197+
userns_pid="$!"
198+
# Synchronise with the container startup...
199+
cat "/proc/$userns_pid/uid_map" "/proc/$userns_pid/gid_map" >&2
200+
# Configure the mapping to match the rootfs mapping.
201+
echo "0 100000 65534" >"/proc/$userns_pid/uid_map"
202+
echo "0 200000 65534" >"/proc/$userns_pid/gid_map"
203+
# Stash the nsfsfd.
204+
mount --bind "/proc/$userns_pid/ns/user" "$userns_path"
205+
echo "$userns_path" >>"$to_umount_list"
206+
# Kill the helper.
207+
kill -9 "$userns_pid"
208+
209+
# Configure our container to attach to the external userns.
210+
update_config '.linux.namespaces |= map(if .type == "user" then (.path = "'"$userns_path"'") else . end)
211+
| del(.linux.uidMappings)
212+
| del(.linux.gidMappings)'
213+
214+
# Also create a network namespace that *is not owned* by the above userns.
215+
# NOTE: Having no permissions in a namespaces makes it necessary to modify
216+
# the config so that we don't get mount errors (for reference: no netns
217+
# permissions == no sysfs mounts, no pidns permissoins == no procfs mounts,
218+
# no utsns permissions == no sethostname(2), no ipc permissions == no
219+
# mqueue mounts, etc).
220+
netns_path="$(mktemp "$BATS_RUN_TMPDIR/netns.XXXXXX")"
221+
unshare -i -- mount --bind "/proc/self/ns/net" "$netns_path"
222+
echo "$netns_path" >>"$to_umount_list"
223+
# Configure our container to attach to the external netns.
224+
update_config '.linux.namespaces |= map(if .type == "network" then (.path = "'"$netns_path"'") else . end)'
225+
226+
# Convert sysfs mounts to a bind-mount from the host, to avoid the
227+
# permission issues due to the netns setup we have.
228+
update_config '.mounts |= map((select(.type == "sysfs") | { "source": "/sys", "destination": .destination, "type": "bind", "options": ["rbind"] }) // .)'
229+
230+
# Create a detached container to verify the namespaces are correct.
231+
update_config '.process.args = ["sleep", "infinity"]'
232+
runc --debug run -d --console-socket "$CONSOLE_SOCKET" ctr
233+
[ "$status" -eq 0 ]
234+
235+
userns_id="user:[$(stat -c "%i" "$userns_path")]"
236+
netns_id="net:[$(stat -c "%i" "$netns_path")]"
237+
238+
runc exec ctr readlink /proc/self/ns/user
239+
[ "$status" -eq 0 ]
240+
[[ "$output" == "$userns_id" ]]
241+
242+
runc exec ctr readlink /proc/self/ns/net
243+
[ "$status" -eq 0 ]
244+
[[ "$output" == "$netns_id" ]]
245+
}

0 commit comments

Comments
 (0)