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

Implement change proposed in "All MRs that add unit tests conflict with each other" #602

Merged
merged 3 commits into from
Oct 2, 2023
Merged
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
122 changes: 66 additions & 56 deletions tests/test-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,37 @@ srcd=$(cd $(dirname "$0") && pwd)

bn=$(basename "$0")

echo "1..59"
test_count=0
ok () {
test_count=$((test_count + 1))
echo ok $test_count "$@"
}
ok_skip () {
ok "# SKIP" "$@"
}
done_testing () {
echo "1..$test_count"
}

# Test help
${BWRAP} --help > help.txt
assert_file_has_content help.txt "usage: ${BWRAP}"
echo "ok - Help works"
ok "Help works"

for ALT in "" "--unshare-user-try" "--unshare-pid" "--unshare-user-try --unshare-pid"; do
# Test fuse fs as bind source
if [ "x$FUSE_DIR" != "x" ]; then
$RUN $ALT --proc /proc --dev /dev --bind $FUSE_DIR /tmp/foo true
echo "ok - can bind-mount a FUSE directory with $ALT"
ok "can bind-mount a FUSE directory with $ALT"
else
echo "ok # SKIP no FUSE support"
ok_skip "no FUSE support"
fi
# no --dev => no devpts => no map_root workaround
$RUN $ALT --proc /proc true
echo "ok - can mount /proc with $ALT"
ok "can mount /proc with $ALT"
# No network
$RUN $ALT --unshare-net --proc /proc --dev /dev true
echo "ok - can unshare network, create new /dev with $ALT"
ok "can unshare network, create new /dev with $ALT"
# Unreadable file
echo -n "expect EPERM: " >&2

Expand All @@ -49,31 +59,31 @@ for ALT in "" "--unshare-user-try" "--unshare-pid" "--unshare-user-try --unshare
assert_not_reached Could read /etc/shadow
fi

echo "ok - cannot read /etc/shadow with $ALT"
ok "cannot read /etc/shadow with $ALT"
# Unreadable dir
if [ "x$UNREADABLE" != "x" ]; then
echo -n "expect EPERM: " >&2
if $RUN $ALT --unshare-net --proc /proc --dev /dev --bind $UNREADABLE /tmp/foo cat /tmp/foo; then
assert_not_reached Could read $UNREADABLE
fi
echo "ok - cannot read $UNREADABLE with $ALT"
ok "cannot read $UNREADABLE with $ALT"
else
echo "ok # SKIP not sure what unreadable file to use"
ok_skip "not sure what unreadable file to use"
fi

# bind dest in symlink (https://github.com/projectatomic/bubblewrap/pull/119)
$RUN $ALT --dir /tmp/dir --symlink dir /tmp/link --bind /etc /tmp/link true
echo "ok - can bind a destination over a symlink"
ok "can bind a destination over a symlink"
done

# Test devices
$RUN --unshare-pid --dev /dev ls -al /dev/{stdin,stdout,stderr,null,random,urandom,fd,core} >/dev/null
echo "ok - all expected devices were created"
ok "all expected devices were created"

# Test --as-pid-1
$RUN --unshare-pid --as-pid-1 --bind / / bash -c 'echo $$' > as_pid_1.txt
assert_file_has_content as_pid_1.txt "1"
echo "ok - can run as pid 1"
ok "can run as pid 1"

# Test --info-fd and --json-status-fd
if $RUN --unshare-all --info-fd 42 --json-status-fd 43 -- bash -c 'exit 42' 42>info.json 43>json-status.json 2>err.txt; then
Expand All @@ -82,7 +92,7 @@ fi
assert_file_has_content info.json '"child-pid": [0-9]'
assert_file_has_content json-status.json '"child-pid": [0-9]'
assert_file_has_content_literal json-status.json '"exit-code": 42'
echo "ok info and json-status fd"
ok "info and json-status fd"

DATA=$($RUN --proc /proc --unshare-all --info-fd 42 --json-status-fd 43 -- bash -c 'stat -L --format "%n %i" /proc/self/ns/*' 42>info.json 43>json-status.json 2>err.txt)

Expand All @@ -93,37 +103,37 @@ for NS in "ipc" "mnt" "net" "pid" "uts"; do
assert_file_has_content json-status.json "$want"
done

echo "ok namespace id info in info and json-status fd"
ok "namespace id info in info and json-status fd"

if ! command -v strace >/dev/null || ! strace -h | grep -v -e default | grep -e fault >/dev/null; then
echo "ok - # SKIP no strace fault injection"
ok_skip "no strace fault injection"
else
! strace -o /dev/null -f -e trace=prctl -e fault=prctl:when=39 $RUN --die-with-parent --json-status-fd 42 true 42>json-status.json
assert_not_file_has_content json-status.json '"exit-code": [0-9]'
echo "ok pre-exec failure doesn't include exit-code in json-status"
ok "pre-exec failure doesn't include exit-code in json-status"
fi

notanexecutable=/
$RUN --json-status-fd 42 $notanexecutable 42>json-status.json || true
assert_not_file_has_content json-status.json '"exit-code": [0-9]'
echo "ok exec failure doesn't include exit-code in json-status"
ok "exec failure doesn't include exit-code in json-status"

# These tests require --unshare-user
if test -n "${bwrap_is_suid:-}"; then
echo "ok - # SKIP no --cap-add support"
echo "ok - # SKIP no --cap-add support"
echo "ok - # SKIP no --disable-userns"
ok_skip "no --cap-add support"
ok_skip "no --cap-add support"
ok_skip "no --disable-userns"
else
BWRAP_RECURSE="$BWRAP --unshare-user --uid 0 --gid 0 --cap-add ALL --bind / / --bind /proc /proc"

# $BWRAP May be inaccessible due to the user namespace so use /proc/self/exe
$BWRAP_RECURSE -- /proc/self/exe --unshare-all --bind / / --bind /proc /proc echo hello > recursive_proc.txt
assert_file_has_content recursive_proc.txt "hello"
echo "ok - can mount /proc recursively"
ok "can mount /proc recursively"

$BWRAP_RECURSE -- /proc/self/exe --unshare-all ${BWRAP_RO_HOST_ARGS} findmnt > recursive-newroot.txt
assert_file_has_content recursive-newroot.txt "/usr"
echo "ok - can pivot to new rootfs recursively"
ok "can pivot to new rootfs recursively"

$BWRAP --dev-bind / / -- true
! $BWRAP --assert-userns-disabled --dev-bind / / -- true
Expand All @@ -141,15 +151,15 @@ else
$BWRAP_RECURSE --unshare-user --disable-userns --dev-bind / / -- sh -c "echo 100 > /proc/sys/user/max_user_namespaces || true; ! $BWRAP --unshare-user --dev-bind / / -- true"
$BWRAP_RECURSE --unshare-user --disable-userns --dev-bind / / -- sh -c "! $BWRAP --unshare-user --dev-bind / / --assert-userns-disabled -- true"

echo "ok - can disable nested userns"
ok "can disable nested userns"
fi

# Test error prefixing
if $RUN --unshare-pid --bind /source-enoent /dest true 2>err.txt; then
assert_not_reached "bound nonexistent source"
fi
assert_file_has_content err.txt "^bwrap: Can't find source path.*source-enoent"
echo "ok error prefxing"
ok "error prefixing"

if ! ${is_uidzero}; then
# When invoked as non-root, check that by default we have no caps left
Expand All @@ -160,7 +170,7 @@ if ! ${is_uidzero}; then
test "$e" = 0
assert_not_file_has_content caps.test ': =.*cap'
done
echo "ok - we have no caps as uid != 0"
ok "we have no caps as uid != 0"
else
capsh --print | sed -e 's/no-new-privs=0/no-new-privs=1/' > caps.expected

Expand All @@ -184,7 +194,7 @@ else
assert_file_has_content caps.test '^Current: =eip.*cap_fowner.*-eip$'
assert_not_file_has_content caps.test '^Current: =.*cap_net_bind_service.*-eip$'
fi
echo "ok - we have the expected caps as uid 0"
ok "we have the expected caps as uid 0"
fi

# Test --die-with-parent
Expand Down Expand Up @@ -212,7 +222,7 @@ for die_with_parent_argv in "--die-with-parent" "--die-with-parent --unshare-pid
# We have to loop here, because bwrap doesn't wait for the lock if
# another process is holding it. If we're unlucky, lockf-n.py will
# be holding it.
/bin/bash -c "while true; do $RUN ${die_with_parent_argv} --lock-file $(pwd)/lock sleep 1h; done" &
bash -c "while true; do $RUN ${die_with_parent_argv} --lock-file $(pwd)/lock sleep 1h; done" &
childshellpid=$!

# Wait for lock to be taken (yes hacky)
Expand All @@ -231,50 +241,50 @@ for die_with_parent_argv in "--die-with-parent" "--die-with-parent --unshare-pid
kill -9 ${childshellpid}
# Lock file should be unlocked
./lockf-n.py ./lock wait
echo "ok die with parent ${die_with_parent_argv}"
ok "die with parent ${die_with_parent_argv}"
done

printf '%s--dir\0/tmp/hello/world\0' '' > test.args
printf '%s--dir\0/tmp/hello/world2\0' '' > test.args2
printf '%s--dir\0/tmp/hello/world3\0' '' > test.args3
$RUN --args 3 --args 4 --args 5 /bin/sh -c 'test -d /tmp/hello/world && test -d /tmp/hello/world2 && test -d /tmp/hello/world3' 3<test.args 4<test.args2 5<test.args3
echo "ok - we can parse arguments from a fd"
ok "we can parse arguments from a fd"

mkdir bin
echo "#!/bin/sh" > bin/--inadvisable-executable-name--
echo "echo hello" >> bin/--inadvisable-executable-name--
chmod +x bin/--inadvisable-executable-name--
PATH="${srcd}:$PATH" $RUN -- sh -c "echo hello" > stdout
assert_file_has_content stdout hello
echo "ok - we can run with --"
ok "we can run with --"
PATH="$(pwd)/bin:$PATH" $RUN -- --inadvisable-executable-name-- > stdout
assert_file_has_content stdout hello
echo "ok - we can run an inadvisable executable name with --"
ok "we can run an inadvisable executable name with --"
if $RUN -- --dev-bind /dev /dev sh -c 'echo should not have run'; then
assert_not_reached "'--dev-bind' should have been interpreted as a (silly) executable name"
fi
echo "ok - options like --dev-bind are defanged by --"
ok "options like --dev-bind are defanged by --"

if command -v mktemp > /dev/null; then
tempfile="$(mktemp /tmp/bwrap-test-XXXXXXXX)"
echo "hello" > "$tempfile"
$BWRAP --bind / / cat "$tempfile" > stdout
assert_file_has_content stdout hello
echo "ok - bind-mount of / exposes real /tmp"
ok "bind-mount of / exposes real /tmp"
$BWRAP --bind / / --bind /tmp /tmp cat "$tempfile" > stdout
assert_file_has_content stdout hello
echo "ok - bind-mount of /tmp exposes real /tmp"
ok "bind-mount of /tmp exposes real /tmp"
if [ -d /mnt ] && [ ! -L /mnt ]; then
$BWRAP --bind / / --bind /tmp /mnt cat "/mnt/${tempfile#/tmp/}" > stdout
assert_file_has_content stdout hello
echo "ok - bind-mount of /tmp onto /mnt exposes real /tmp"
ok "bind-mount of /tmp onto /mnt exposes real /tmp"
else
echo "ok - # SKIP /mnt does not exist or is a symlink"
ok_skip "/mnt does not exist or is a symlink"
fi
else
echo "ok - # SKIP mktemp not found"
echo "ok - # SKIP mktemp not found"
echo "ok - # SKIP mktemp not found"
ok_skip "mktemp not found"
ok_skip "mktemp not found"
ok_skip "mktemp not found"
fi

if $RUN test -d /tmp/oldroot; then
Expand All @@ -293,7 +303,7 @@ fi
if $BWRAP --bind / / --bind "$(pwd)" /tmp test -d /tmp/newroot; then
assert_not_reached "/tmp/newroot should not be visible"
fi
echo "ok - we can mount another directory onto /tmp"
ok "we can mount another directory onto /tmp"

echo "hello" > input.$$
$RUN --bind "$(pwd)" /tmp/here cat /tmp/here/input.$$ > stdout
Expand All @@ -304,7 +314,7 @@ fi
if $RUN --bind "$(pwd)" /tmp/here test -d /tmp/newroot; then
assert_not_reached "/tmp/newroot should not be visible"
fi
echo "ok - we can mount another directory inside /tmp"
ok "we can mount another directory inside /tmp"

touch some-file
mkdir -p some-dir
Expand All @@ -318,14 +328,14 @@ command stat -c '%a' new-dir-mountpoint > new-dir-permissions
assert_file_has_content new-dir-permissions 755
command stat -c '%a' new-file-mountpoint > new-file-permissions
assert_file_has_content new-file-permissions 444
echo "ok - Files and directories created as mount points have expected permissions"
ok "Files and directories created as mount points have expected permissions"


if [ -S /dev/log ]; then
$RUN --bind / / --bind "$(realpath /dev/log)" "$(realpath /dev/log)" true
echo "ok - Can bind-mount a socket (/dev/log) onto a socket"
ok "Can bind-mount a socket (/dev/log) onto a socket"
else
echo "ok # SKIP - /dev/log is not a socket, cannot test bubblewrap#409"
ok_skip "- /dev/log is not a socket, cannot test bubblewrap#409"
fi

mkdir -p dir-already-existed
Expand All @@ -352,7 +362,7 @@ command stat -c '%a' dir-already-existed2 > dir-permissions
assert_file_has_content dir-permissions '^754$'
command stat -c '%a' dir-chmod > dir-permissions
assert_file_has_content dir-permissions '^1755$'
echo "ok - Directories created explicitly have expected permissions"
ok "Directories created explicitly have expected permissions"

rm -fr parent
rm -fr parent-of-1777
Expand Down Expand Up @@ -410,7 +420,7 @@ command stat -c '%a' parent-of-0000 > dir-permissions
assert_file_has_content dir-permissions '^700$'
chmod -R 0700 parent*
rm -fr parent*
echo "ok - Directories created as parents have expected permissions"
ok "Directories created as parents have expected permissions"

$RUN \
--perms 01777 --tmpfs "$(pwd -P)" \
Expand All @@ -423,14 +433,14 @@ $RUN \
--tmpfs "$(pwd -P)" \
stat -c '%a' "$(pwd -P)" > dir-permissions
assert_file_has_content dir-permissions '^755$'
echo "ok - tmpfs has expected permissions"
ok "tmpfs has expected permissions"

# 1048576 = 1 MiB
if test -n "${bwrap_is_suid:-}"; then
if $RUN --size 1048576 --tmpfs "$(pwd -P)" true; then
assert_not_reached "Should not allow --size --tmpfs when setuid"
fi
echo "ok - --size --tmpfs is not allowed when setuid"
ok "--size --tmpfs is not allowed when setuid"
elif df --output=size --block-size=1K "$(pwd -P)" >/dev/null 2>/dev/null; then
$RUN \
--size 1048576 --tmpfs "$(pwd -P)" \
Expand All @@ -452,12 +462,12 @@ elif df --output=size --block-size=1K "$(pwd -P)" >/dev/null 2>/dev/null; then
--perms 01777 --size 1048576 --tmpfs "$(pwd -P)" \
df --output=size --block-size=1K "$(pwd -P)" > dir-size
assert_file_has_content dir-size '^ *1024$'
echo "ok - tmpfs has expected size"
ok "tmpfs has expected size"
else
$RUN --size 1048576 --tmpfs "$(pwd -P)" true
$RUN --perms 01777 --size 1048576 --tmpfs "$(pwd -P)" true
$RUN --size 1048576 --perms 01777 --tmpfs "$(pwd -P)" true
echo "ok # SKIP df is too old, cannot test --size --tmpfs fully"
ok_skip "df is too old, cannot test --size --tmpfs fully"
fi

$RUN \
Expand All @@ -484,7 +494,7 @@ $RUN \
--perms 0640 --ro-bind-data 0 /tmp/file \
stat -c '%a' /tmp/file < /dev/null > file-permissions
assert_file_has_content file-permissions '^640$'
echo "ok - files have expected permissions"
ok "files have expected permissions"

if $RUN --size 0 --tmpfs /tmp/a true; then
assert_not_reached Zero tmpfs size allowed
Expand All @@ -509,15 +519,15 @@ fi
if $RUN --size 9223372036854775809 --tmpfs /tmp/a true; then
assert_not_reached Too-large tmpfs size allowed
fi
echo "ok - bogus tmpfs size not allowed"
ok "bogus tmpfs size not allowed"

if $RUN --perms 0640 --perms 0640 --tmpfs /tmp/a true; then
assert_not_reached Multiple perms options allowed
fi
if $RUN --size 1048576 --size 1048576 --tmpfs /tmp/a true; then
assert_not_reached Multiple perms options allowed
fi
echo "ok - --perms and --size only allowed once"
ok "--perms and --size only allowed once"


FOO= BAR=baz $RUN --setenv FOO bar sh -c 'echo "$FOO$BAR"' > stdout
Expand All @@ -530,14 +540,14 @@ assert_files_equal stdout reference
FOO=wrong BAR=wrong $RUN --clearenv /usr/bin/env > stdout
echo "PWD=$(pwd -P)" > reference
assert_files_equal stdout reference
echo "ok - environment manipulation"
ok "environment manipulation"

$RUN sh -c 'echo $0' > stdout
assert_file_has_content stdout sh
$RUN --argv0 sh sh -c 'echo $0' > stdout
assert_file_has_content stdout sh
$RUN --argv0 right sh -c 'echo $0' > stdout
assert_file_has_content stdout right
echo "ok - argv0 manipulation"
ok "argv0 manipulation"

echo "ok - End of test"
done_testing
Loading