aboutsummaryrefslogtreecommitdiff
path: root/progs/quicktest.sh
diff options
context:
space:
mode:
Diffstat (limited to 'progs/quicktest.sh')
-rwxr-xr-xprogs/quicktest.sh149
1 files changed, 129 insertions, 20 deletions
diff --git a/progs/quicktest.sh b/progs/quicktest.sh
index e8b2c8e..6aa2598 100755
--- a/progs/quicktest.sh
+++ b/progs/quicktest.sh
@@ -44,9 +44,15 @@ pass_capsh () {
pass_capsh --print
+# Validate that PATH expansion works
+PATH=$(/bin/pwd)/junk:$(/bin/pwd) capsh == == == --modes
+if [ $? -ne 0 ]; then
+ echo "Failed to execute capsh consecutively for capability manipulation"
+ exit 1
+fi
# Make a local non-setuid-0 version of capsh and call it privileged
-cp ./capsh ./privileged && chmod -s ./privileged
+cp ./tcapsh-static ./privileged && /bin/chmod -s ./privileged
if [ $? -ne 0 ]; then
echo "Failed to copy capsh for capability manipulation"
exit 1
@@ -64,21 +70,37 @@ if [ $? -ne 0 ]; then
exit 1
fi
+# validate libcap modes:
+pass_capsh --inh=cap_chown --mode=PURE1E --print --inmode=PURE1E
+pass_capsh --mode=NOPRIV --print --inmode=NOPRIV
+pass_capsh --mode=PURE1E --print --mode=NOPRIV --inmode=NOPRIV
+fail_capsh --mode=NOPRIV --print --mode=PURE1E
+fail_capsh --user=nobody --mode=NOPRIV --print -- ./privileged
+
+# simple IAB setting (no ambient) in pure1e mode.
+pass_capsh --mode=PURE1E --iab='!%cap_chown,cap_sys_admin'
+
# Explore keep_caps support
pass_capsh --keep=0 --keep=1 --keep=0 --keep=1 --print
-rm -f tcapsh
-cp capsh tcapsh
-chown root.root tcapsh
-chmod u+s tcapsh
-ls -l tcapsh
+/bin/rm -f tcapsh
+/bin/cp tcapsh-static tcapsh
+/bin/chown root.root tcapsh
+/bin/chmod u+s tcapsh
+/bin/ls -l tcapsh
-# leverage keep caps maintain capabilities accross a change of uid
+# leverage keep caps to maintain capabilities accross a change of euid
# from setuid root to capable luser (as per wireshark/dumpcap 0.99.7)
-pass_capsh --uid=500 -- -c "./tcapsh --keep=1 --caps=\"cap_net_raw,cap_net_admin=ip\" --uid=500 --caps=\"cap_net_raw,cap_net_admin=pie\" --print"
+# This test is subtle. It is testing that a change to self, dropping
+# euid=0 back to that of the luser keeps capabilities.
+pass_capsh --uid=1 -- -c "./tcapsh --keep=1 --caps=\"cap_net_raw,cap_net_admin=ip\" --print --uid=1 --print --caps=\"cap_net_raw,cap_net_admin=pie\" --print"
+
+# this test is a change of user to a new user, note we need to raise
+# the cap_setuid capability (libcap has a function for that) in this case.
+pass_capsh --uid=1 -- -c "./tcapsh --caps=\"cap_net_raw,cap_net_admin=ip cap_setuid=p\" --print --cap-uid=2 --print --caps=\"cap_net_raw,cap_net_admin=pie\" --print"
# This fails, on 2.6.24, but shouldn't
-pass_capsh --uid=500 -- -c "./tcapsh --keep=1 --caps=\"cap_net_raw,cap_net_admin=ip\" --uid=500 --forkfor=10 --caps= --print --killit=9 --print"
+pass_capsh --uid=1 -- -c "./tcapsh --keep=1 --caps=\"cap_net_raw,cap_net_admin=ip\" --uid=1 --forkfor=10 --caps= --print --killit=9 --print"
# only continue with these if --secbits is supported
./capsh --secbits=0x2f > /dev/null 2>&1
@@ -98,7 +120,7 @@ fail_capsh --secbits=32 --keep=1 --keep=0 --print
pass_capsh --secbits=10 --keep=0 --keep=1 --print
fail_capsh --secbits=47 -- -c "./tcapsh --uid=$nouid"
-rm -f tcapsh
+/bin/rm -f tcapsh
# Suppress uid=0 privilege
fail_capsh --secbits=47 --print -- -c "./capsh --uid=$nouid"
@@ -115,12 +137,10 @@ fail_capsh --drop=cap_setuid --secbits=0x2f --print -- -c "./privileged --uid=$n
# Note, the bounding set (edited with --drop) only limits p
# capabilities, not i's.
pass_capsh --secbits=47 --inh=cap_setuid,cap_setgid --drop=cap_setuid \
- --uid=500 --print -- -c "./privileged --uid=$nouid"
-
-rm -f ./privileged
+ --uid=1 --print -- -c "./privileged --uid=$nouid"
# test that we do not support capabilities on setuid shell-scripts
-cat > hack.sh <<EOF
+/bin/cat > hack.sh <<EOF
#!/bin/bash
/usr/bin/id
mypid=\$\$
@@ -134,20 +154,109 @@ else
fi
exit 0
EOF
-chmod +xs hack.sh
-./capsh --uid=500 --inh=none --print -- ./hack.sh
+/bin/chmod +xs hack.sh
+./capsh --uid=1 --inh=none --print -- ./hack.sh
status=$?
-rm -f ./hack.sh
+/bin/rm -f ./hack.sh
if [ $status -ne 0 ]; then
echo "shell scripts can have capabilities (bug)"
exit 1
fi
-# Max lockdown
+# Max lockdown (ie., pure capability model as POSIX.1e intended).
+secbits=0x2f
+if ./capsh --has-ambient ; then
+ secbits="0xef --noamb"
+fi
pass_capsh --keep=1 --uid=$nouid --caps=cap_setpcap=ep \
- --drop=all --secbits=0x2f --caps= --print
+ --drop=all --secbits=$secbits --caps= --print
# Verify we can chroot
pass_capsh --chroot=$(/bin/pwd)
-pass_capsh --chroot=$(/bin/pwd) ==
+pass_capsh -- -c "./tcapsh-static --chroot=$(/bin/pwd) =="
fail_capsh --chroot=$(/bin/pwd) -- -c "echo oops"
+
+./capsh --has-ambient
+if [ $? -eq 0 ]; then
+ echo "test ambient capabilities"
+
+ # Ambient capabilities (any file can inherit capabilities)
+ pass_capsh --noamb
+
+ # test that shell scripts can inherit through ambient capabilities
+ /bin/cat > hack.sh <<EOF
+#!/bin/bash
+/usr/bin/id
+mypid=\$\$
+caps=\$(./getpcaps \$mypid 2>&1 | /usr/bin/cut -d: -f2)
+if [ "\$caps" != " = cap_setuid+i" ]; then
+ echo "Shell script got [\$caps]"
+ exit 0
+fi
+ls -l \$0
+echo "no capabilities [\$caps] for this shell script"
+exit 1
+EOF
+ /bin/chmod +x hack.sh
+ pass_capsh --keep=1 --uid=$nouid --inh=cap_setuid --addamb=cap_setuid -- ./hack.sh
+
+ /bin/rm -f hack.sh
+
+ # Next force the privileged binary to have an empty capability set.
+ # This is sort of the opposite of privileged - it should ensure that
+ # the file can never aquire privilege by the ambient method.
+ ./setcap = ./privileged
+ fail_capsh --keep=1 --uid=$nouid --inh=cap_setuid --addamb=cap_setuid -- -c "./privileged --print --uid=1"
+
+ # finally remove the capability from the privileged binary and try again.
+ ./setcap -r ./privileged
+ pass_capsh --keep=1 --uid=$nouid --inh=cap_setuid --addamb=cap_setuid -- -c "./privileged --print --uid=1"
+
+ # validate IAB setting with an ambient capability
+ pass_capsh --iab='!%cap_chown,^cap_setpcap,cap_sys_admin'
+ fail_capsh --mode=PURE1E --iab='!%cap_chown,^cap_sys_admin'
+fi
+/bin/rm -f ./privileged
+
+echo "testing namespaced file caps"
+
+# nsprivileged capsh will have an ns rootid value (this is
+# the same setup as an earlier test but with a ns file cap).
+rm -f nsprivileged
+cp ./tcapsh-static ./nsprivileged && /bin/chmod -s ./nsprivileged
+./setcap -n 1 all=ep ./nsprivileged
+if [ $? -eq 0 ]; then
+ ./getcap -n ./nsprivileged | fgrep "[rootid=1]"
+ if [ $? -ne 0 ]; then
+ echo "FAILED setting ns rootid on file"
+ exit 1
+ fi
+ # since this is a ns file cap and not a regular one, it should not
+ # lead to a privilege escalation outside of the namespace it
+ # refers to. We suppress uid=0 privilege and confirm this
+ # nsprivileged binary does not have the power to change uid.
+ fail_capsh --secbits=$secbits --print -- -c "./nsprivileged --uid=$nouid"
+else
+ echo "ns file caps not supported - skipping test"
+fi
+rm -f nsprivileged
+
+# If the build tree compiled the Go cap package.
+if [ -f ../go/compare-cap ]; then
+ cp ../go/compare-cap .
+ LD_LIBRARY_PATH=../libcap ./compare-cap
+ if [ $? -ne 0 ]; then
+ echo "FAILED to execute go binary"
+ exit 1
+ fi
+ LD_LIBRARY_PATH=../libcap ./compare-cap 2>&1 | grep "skipping file cap tests"
+ if [ $? -eq 0 ]; then
+ echo "FAILED not engaging file cap tests"
+ fi
+ echo "PASSED"
+else
+ echo "no Go support compiled, so skipping Go tests"
+fi
+rm -f compare-cap
+
+echo "ALL TESTS PASSED!"