diff options
author | Maciej Wereski <m.wereski@partner.samsung.com> | 2014-01-15 16:15:00 +0100 |
---|---|---|
committer | Maciej Wereski <m.wereski@partner.samsung.com> | 2014-01-15 16:15:00 +0100 |
commit | bcca19a055cbdb0d67985ac08fef491f6d4bb42b (patch) | |
tree | 1d49ec65d242cf1dec494570622b3737aef06a03 /progs | |
parent | b138da4a4b9d57b850ca4d0061969f5e3299861d (diff) | |
download | libcap-bcca19a055cbdb0d67985ac08fef491f6d4bb42b.tar.gz libcap-bcca19a055cbdb0d67985ac08fef491f6d4bb42b.tar.bz2 libcap-bcca19a055cbdb0d67985ac08fef491f6d4bb42b.zip |
Imported Upstream version 2.24upstream/2.24
Diffstat (limited to 'progs')
-rw-r--r-- | progs/capsh.c | 3 | ||||
-rwxr-xr-x | progs/quicktest.sh | 44 | ||||
-rw-r--r-- | progs/setcap.c | 27 |
3 files changed, 53 insertions, 21 deletions
diff --git a/progs/capsh.c b/progs/capsh.c index 52336d7..3ceadcd 100644 --- a/progs/capsh.c +++ b/progs/capsh.c @@ -520,7 +520,8 @@ int main(int argc, char *argv[], char *envp[]) if (set >= 0) { const char *b; b = binary(set); /* use verilog convention for binary string */ - printf("Securebits: 0%o/0x%x/%u'b%s\n", set, set, strlen(b), b); + printf("Securebits: 0%o/0x%x/%u'b%s\n", set, set, + (unsigned) strlen(b), b); printf(" secure-noroot: %s (%s)\n", (set & 1) ? "yes":"no", (set & 2) ? "locked":"unlocked"); diff --git a/progs/quicktest.sh b/progs/quicktest.sh index be3fa7d..ca6bf1e 100755 --- a/progs/quicktest.sh +++ b/progs/quicktest.sh @@ -44,18 +44,23 @@ pass_capsh () { pass_capsh --print -# Make a local non-setuid-0 version of ping -cp /bin/ping . && chmod -s ./ping -# Give it the forced capability it needs -./setcap all=ep ./ping +# Make a local non-setuid-0 version of capsh and call it privileged +cp ./capsh ./privileged && chmod -s ./privileged +if [ $? -ne 0 ]; then + echo "Failed to copy capsh for capability manipulation" + exit 1 +fi + +# Give it the forced capability it could need +./setcap all=ep ./privileged if [ $? -ne 0 ]; then echo "Failed to set all capabilities on file" exit 1 fi -./setcap cap_net_raw=ep ./ping +./setcap cap_setuid,cap_setgid=ep ./privileged if [ $? -ne 0 ]; then - echo "Failed to set single capability on ping file" + echo "Failed to set limited capabilities on privileged file" exit 1 fi @@ -75,37 +80,40 @@ pass_capsh --uid=500 -- -c "./tcapsh --keep=1 --caps=\"cap_net_raw,cap_net_admin # 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" -rm -f tcapsh - # only continue with these if --secbits is supported ./capsh --secbits=0x2f > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "unable to test securebits manipulation - assume not supported (PASS)" - rm -f ./ping + rm -f tcapsh + rm -f privileged exit 0 fi pass_capsh --secbits=42 --print fail_capsh --secbits=32 --keep=1 --keep=0 --print pass_capsh --secbits=10 --keep=0 --keep=1 --print -fail_capsh --secbits=47 -- -c "ping -c1 localhost" +fail_capsh --secbits=47 -- -c "./tcapsh --user=nobody" + +rm -f tcapsh # Suppress uid=0 privilege -fail_capsh --secbits=47 --print -- -c "/bin/ping -c1 localhost" +fail_capsh --secbits=47 --print -- -c "./capsh --user=nobody" -# suppress uid=0 privilege and test this ping -pass_capsh --secbits=0x2f --print -- -c "./ping -c1 localhost" +# suppress uid=0 privilege and test this privileged +pass_capsh --secbits=0x2f --print -- -c "./privileged --user=nobody" # observe that the bounding set can be used to suppress this forced capability -fail_capsh --drop=cap_net_raw,cap_chown --secbits=0x2f --print -- -c "./ping -c1 localhost" +fail_capsh --drop=cap_setuid --secbits=0x2f --print -- -c "./privileged --user=nobody" # change the way the capability is obtained (make it inheritable) -./setcap cap_net_raw=ei ./ping +./setcap cap_setuid,cap_setgid=ei ./privileged -pass_capsh --secbits=47 --inh=cap_net_raw --drop=cap_net_raw \ - --uid=500 --print -- -c "./ping -c1 localhost" +# 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 --user=nobody" -rm -f ./ping +rm -f ./privileged # test that we do not support capabilities on setuid shell-scripts cat > hack.sh <<EOF diff --git a/progs/setcap.c b/progs/setcap.c index 0215fc4..83090ae 100644 --- a/progs/setcap.c +++ b/progs/setcap.c @@ -26,7 +26,7 @@ static void usage(void) static int read_caps(int quiet, const char *filename, char *buffer) { - int i=MAXCAP; + int i = MAXCAP; if (!quiet) { fprintf(stderr, "Please enter caps for file [empty line to end]:\n"); @@ -170,10 +170,33 @@ int main(int argc, char **argv) } retval = cap_set_file(*++argv, cap_d); if (retval != 0) { + int explained = 0; +#ifdef linux + cap_value_t cap; + cap_flag_value_t per_state; + + for (cap = 0; + cap_get_flag(cap_d, cap, CAP_PERMITTED, &per_state) != -1; + cap++) { + cap_flag_value_t inh_state, eff_state; + + cap_get_flag(cap_d, cap, CAP_INHERITABLE, &inh_state); + cap_get_flag(cap_d, cap, CAP_EFFECTIVE, &eff_state); + if ((inh_state | per_state) != eff_state) { + fprintf(stderr, "NOTE: Under Linux, effective file capabilities must either be empty, or\n" + " exactly match the union of selected permitted and inheritable bits.\n"); + explained = 1; + break; + } + } +#endif /* def linux */ + fprintf(stderr, "Failed to set capabilities on file `%s' (%s)\n", argv[0], strerror(errno)); - usage(); + if (!explained) { + usage(); + } } } if (cap_d) { |