Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libcontainer: remove all mount logic from nsexec #3985

Merged
merged 8 commits into from
Dec 18, 2023
Prev Previous commit
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 <cyphar@cyphar.com>
  • Loading branch information
cyphar committed Dec 14, 2023
commit fa93c8b05b323187d0c5e3bdb3622c23c3abcfff
119 changes: 119 additions & 0 deletions tests/integration/mounts.bats
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,109 @@ function test_ro_cgroup_mount() {
for line in "${lines[@]}"; do [[ "${line}" == *'ro,'* ]]; done
}

# Parse an "optstring" of the form foo,bar into $is_foo and $is_bar variables.
# Usage: parse_optstring foo,bar foo bar baz
function parse_optstring() {
optstring="$1"
shift

for flag in "$@"; do
is_set=
if grep -wq "$flag" <<<"$optstring"; then
is_set=1
fi
eval "is_$flag=$is_set"
done
}

function config_add_bind_mount() {
src="$1"
dst="$2"
parse_optstring "${3:-}" rbind idmap

bindtype=bind
if [ -n "$is_rbind" ]; then
bindtype=rbind
fi

mappings=""
if [ -n "$is_idmap" ]; then
mappings='
"uidMappings": [{"containerID": 0, "hostID": 100000, "size": 65536}],
"gidMappings": [{"containerID": 0, "hostID": 100000, "size": 65536}],
'
fi

update_config '.mounts += [{
"source": "'"$src"'",
"destination": "'"$dst"'",
"type": "bind",
'"$mappings"'
"options": [ "'"$bindtype"'", "rprivate" ]
}]'
}

# This needs to be placed at the top of the bats file to work around
# a shellcheck bug. See <https://github.com/koalaman/shellcheck/issues/2873>.
function test_mount_order() {
parse_optstring "${1:-}" userns idmap

if [ -n "$is_userns" ]; then
requires root

update_config '.linux.namespaces += [{"type": "user"}]
| .linux.uidMappings += [{"containerID": 0, "hostID": 100000, "size": 65536}]
| .linux.gidMappings += [{"containerID": 0, "hostID": 100000, "size": 65536}]'
remap_rootfs
fi

ctr_src_opts="rbind"
if [ -n "$is_idmap" ]; then
requires root
requires_kernel 5.12
requires_idmap_fs .

ctr_src_opts+=",idmap"
fi

mkdir -p rootfs/{mnt,final}
# Create a set of directories we can create a mount tree with.
for subdir in a/x b/y c/z; do
dir="bind-src/$subdir"
mkdir -p "$dir"
echo "$subdir" >"$dir/file"
# Add a symlink to make sure
topdir="$(dirname "$subdir")"
ln -s "$topdir" "bind-src/sym-$topdir"
done
# In userns tests, make sure that the source directory cannot be accessed,
# to make sure we're exercising the bind-mount source fd logic.
chmod o-rwx bind-src

rootfs="$(pwd)/rootfs"
rm -rf rootfs/mnt
mkdir rootfs/mnt

# Create a bind-mount tree.
config_add_bind_mount "$PWD/bind-src/a" "/mnt"
config_add_bind_mount "$PWD/bind-src/sym-b" "/mnt/x"
config_add_bind_mount "$PWD/bind-src/c" "/mnt/x/y"
config_add_bind_mount "$PWD/bind-src/sym-a" "/mnt/x/y/z"
# Create a recursive bind-mount that uses part of the current tree in the
# container.
config_add_bind_mount "$rootfs/mnt/x" "$rootfs/mnt/x/y/z/x" "$ctr_src_opts"
config_add_bind_mount "$rootfs/mnt/x/y" "$rootfs/mnt/x/y/z" "$ctr_src_opts"
# Finally, bind-mount the whole thing on top of /final.
config_add_bind_mount "$rootfs/mnt" "$rootfs/final" "$ctr_src_opts"

# Check that the entire tree was copied and the mounts were done in the
# expected order.
update_config '.process.args = ["cat", "/final/x/y/z/z/x/y/z/x/file"]'
runc run test_busybox
[ "$status" -eq 0 ]
[[ "$output" == *"a/x"* ]] # the final "file" was from a/x.
}

# https://github.com/opencontainers/runc/issues/3991
@test "runc run [tmpcopyup]" {
mkdir -p rootfs/dir1/dir2
Expand Down Expand Up @@ -108,3 +211,19 @@ function test_ro_cgroup_mount() {
update_config '.linux.namespaces |= if index({"type": "cgroup"}) then . else . + [{"type": "cgroup"}] end'
test_ro_cgroup_mount
}

@test "runc run [mount order, container bind-mount source]" {
test_mount_order
}

@test "runc run [mount order, container bind-mount source] (userns)" {
test_mount_order userns
}

@test "runc run [mount order, container idmap source]" {
test_mount_order idmap
}

@test "runc run [mount order, container idmap source] (userns)" {
test_mount_order userns,idmap
}
Loading