Home | History | Annotate | Download | only in progs
      1 #!/bin/bash
      2 #
      3 # Run through a series of tests to try out the various capability
      4 # manipulations posible through exec.
      5 #
      6 # [Run this as root in a root-enabled process tree.]
      7 
      8 try_capsh () {
      9     echo "TEST: ./capsh $*"
     10     ./capsh "$@"
     11     if [ $? -ne 0 ]; then
     12 	echo FAILED
     13 	return 1
     14     else
     15 	echo PASSED
     16 	return 0
     17     fi
     18 }
     19 
     20 fail_capsh () {
     21     echo -n "EXPECT FAILURE: "
     22     try_capsh "$@"
     23     if [ $? -eq 1 ]; then
     24 	echo "[WHICH MEANS A PASS!]"
     25 	return 0
     26     else
     27 	echo "Undesired result - aborting"
     28 	echo "PROBLEM TEST: $*"
     29 	exit 1
     30     fi
     31 }
     32 
     33 pass_capsh () {
     34     echo -n "EXPECT SUCCESS: "
     35     try_capsh "$@"
     36     if [ $? -eq 0 ]; then
     37 	return 0
     38     else
     39 	echo "Undesired result - aborting"
     40 	echo "PROBLEM TEST: $*"
     41 	exit 1
     42     fi
     43 }
     44 
     45 pass_capsh --print
     46 
     47 
     48 # Make a local non-setuid-0 version of capsh and call it privileged
     49 cp ./capsh ./privileged && chmod -s ./privileged
     50 if [ $? -ne 0 ]; then
     51     echo "Failed to copy capsh for capability manipulation"
     52     exit 1
     53 fi
     54 
     55 # Give it the forced capability it could need
     56 ./setcap all=ep ./privileged
     57 if [ $? -ne 0 ]; then
     58     echo "Failed to set all capabilities on file"
     59     exit 1
     60 fi
     61 ./setcap cap_setuid,cap_setgid=ep ./privileged
     62 if [ $? -ne 0 ]; then
     63     echo "Failed to set limited capabilities on privileged file"
     64     exit 1
     65 fi
     66 
     67 # Explore keep_caps support
     68 pass_capsh --keep=0 --keep=1 --keep=0 --keep=1 --print
     69 
     70 rm -f tcapsh
     71 cp capsh tcapsh
     72 chown root.root tcapsh
     73 chmod u+s tcapsh
     74 ls -l tcapsh
     75 
     76 # leverage keep caps maintain capabilities accross a change of uid
     77 # from setuid root to capable luser (as per wireshark/dumpcap 0.99.7)
     78 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"
     79 
     80 # This fails, on 2.6.24, but shouldn't
     81 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"
     82 
     83 # only continue with these if --secbits is supported
     84 ./capsh --secbits=0x2f > /dev/null 2>&1
     85 if [ $? -ne 0 ]; then
     86     echo "unable to test securebits manipulation - assume not supported (PASS)"
     87     rm -f tcapsh
     88     rm -f privileged
     89     exit 0
     90 fi
     91 
     92 # nobody's uid. Static compilation of the capsh binary can disable pwd
     93 # info discovery.
     94 nouid=$(/usr/bin/id nobody -u)
     95 
     96 pass_capsh --secbits=42 --print
     97 fail_capsh --secbits=32 --keep=1 --keep=0 --print
     98 pass_capsh --secbits=10 --keep=0 --keep=1 --print
     99 fail_capsh --secbits=47 -- -c "./tcapsh --uid=$nouid"
    100 
    101 rm -f tcapsh
    102 
    103 # Suppress uid=0 privilege
    104 fail_capsh --secbits=47 --print -- -c "./capsh --uid=$nouid"
    105 
    106 # suppress uid=0 privilege and test this privileged
    107 pass_capsh --secbits=0x2f --print -- -c "./privileged --uid=$nouid"
    108 
    109 # observe that the bounding set can be used to suppress this forced capability
    110 fail_capsh --drop=cap_setuid --secbits=0x2f --print -- -c "./privileged --uid=$nouid"
    111 
    112 # change the way the capability is obtained (make it inheritable)
    113 ./setcap cap_setuid,cap_setgid=ei ./privileged
    114 
    115 # Note, the bounding set (edited with --drop) only limits p
    116 # capabilities, not i's.
    117 pass_capsh --secbits=47 --inh=cap_setuid,cap_setgid --drop=cap_setuid \
    118     --uid=500 --print -- -c "./privileged --uid=$nouid"
    119 
    120 rm -f ./privileged
    121 
    122 # test that we do not support capabilities on setuid shell-scripts
    123 cat > hack.sh <<EOF
    124 #!/bin/bash
    125 /usr/bin/id
    126 mypid=\$\$
    127 caps=\$(./getpcaps \$mypid 2>&1 | /usr/bin/cut -d: -f2)
    128 if [ "\$caps" != " =" ]; then
    129   echo "Shell script got [\$caps] - you should upgrade your kernel"
    130   exit 1
    131 else
    132   ls -l \$0
    133   echo "Good, no capabilities [\$caps] for this setuid-0 shell script"
    134 fi
    135 exit 0
    136 EOF
    137 chmod +xs hack.sh
    138 ./capsh --uid=500 --inh=none --print -- ./hack.sh
    139 status=$?
    140 rm -f ./hack.sh
    141 if [ $status -ne 0 ]; then
    142     echo "shell scripts can have capabilities (bug)"
    143     exit 1
    144 fi
    145 
    146 # Max lockdown
    147 pass_capsh --keep=1 --uid=$nouid --caps=cap_setpcap=ep \
    148     --drop=all --secbits=0x2f --caps= --print
    149 
    150 # Verify we can chroot
    151 pass_capsh --chroot=$(/bin/pwd)
    152 pass_capsh --chroot=$(/bin/pwd) ==
    153 fail_capsh --chroot=$(/bin/pwd) -- -c "echo oops"
    154