Serge E. Hallyn wrote:
Quoting Andrew G. Morgan ([EMAIL PROTECTED]):
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

[EMAIL PROTECTED] wrote:
| Figure in the meantime I can at least send it out for some
| more comments from Andrew.  Andrew, I'm also attaching the
| new verify_caps_exec.c verbatim for easier review.

Thanks.

As per email to Chris F. the 'all' shorthand in 2.07 is broken when
running on 32-bit capabilities systems. I've fixed it in the git tree,
but need to make a 2.08 to release that fix. Perhaps this is related to
your problem?
Comments inline below...

Thanks for the comments.  New patch follows.  Subrata, please apply.

Applied. Thanks.

--Subrata
(Note - it's based on the 20080229 release because I seem unable to do a
full cvs checkout for the last week... hopefully no conflicts)

thanks,
-serge

Signed-off-by: Serge E. Hallyn <[EMAIL PROTECTED]>
--
testcases/kernel/security/filecaps/Makefile | 8 testcases/kernel/security/filecaps/makenumcapsh.c | 21 +
 testcases/kernel/security/filecaps/verify_caps_exec.c |  231 +++++++-----------
 3 files changed, 126 insertions(+), 134 deletions(-)

diff -Nrup ltp-full-20080229/testcases/kernel/security/filecaps/Makefile 
ltp-full-20080229-patched/testcases/kernel/security/filecaps/Makefile
--- ltp-full-20080229/testcases/kernel/security/filecaps/Makefile       
2008-02-29 08:55:42.000000000 +0100
+++ ltp-full-20080229-patched/testcases/kernel/security/filecaps/Makefile       
2008-03-09 21:27:00.000000000 +0100
@@ -37,9 +37,15 @@ all:
 TARGETS =
 endif

+numcaps.h: makenumcapsh.c
+       gcc -o makenumcapsh makenumcapsh.c
+       ./makenumcapsh > numcaps.h
+
+verify_caps_exec: verify_caps_exec.c numcaps.h
+
 INSTALLTARGETS = $(TARGETS) $(SCRIPTS) checkforlibcap
 install: $(INSTALLTARGETS)
        @set -e; for i in $(INSTALLTARGETS); do ln -f $$i ../../../bin/$$i ; 
chmod +x ../../../bin/$$i; done

 clean:
-       rm -f $(TARGETS) *.o caps_fifo checkforlibcap
+       rm -f $(TARGETS) *.o caps_fifo checkforlibcap numcaps.h makenumcapsh
diff -Nrup ltp-full-20080229/testcases/kernel/security/filecaps/makenumcapsh.c 
ltp-full-20080229-patched/testcases/kernel/security/filecaps/makenumcapsh.c
--- ltp-full-20080229/testcases/kernel/security/filecaps/makenumcapsh.c 
1970-01-01 01:00:00.000000000 +0100
+++ ltp-full-20080229-patched/testcases/kernel/security/filecaps/makenumcapsh.c 
2008-03-09 21:27:00.000000000 +0100
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <errno.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+
+#ifndef PR_CAPBSET_READ
+#define PR_CAPBSET_READ 23
+#endif
+
+int main(int argc, char *argv[])
+{
+       int i, ret = 0;
+
+       for (i=0; ret != -1; i++) {
+               ret = prctl(PR_CAPBSET_READ, i);
+               if (ret == -1)
+                       break;
+       }
+       printf("#define NUM_CAPS %d\n", i);
+       return 0;
+}
diff -Nrup 
ltp-full-20080229/testcases/kernel/security/filecaps/verify_caps_exec.c 
ltp-full-20080229-patched/testcases/kernel/security/filecaps/verify_caps_exec.c
--- ltp-full-20080229/testcases/kernel/security/filecaps/verify_caps_exec.c     
2008-02-29 08:55:42.000000000 +0100
+++ 
ltp-full-20080229-patched/testcases/kernel/security/filecaps/verify_caps_exec.c 
    2008-03-10 22:06:49.000000000 +0100
@@ -21,7 +21,7 @@
  * File: verify_caps_exec.c
  * Author: Serge Hallyn
  * Purpose: perform several tests of file capabilities:
- *  1. try setting caps without CAP_SYS_ADMIN
+ *  1. try setting caps without privilege
  *  2. test proper calculation of pI', pE', and pP'.
  *     Try setting valid caps, drop rights, and run the executable,
  *     make sure we get the rights
@@ -35,13 +35,14 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
-#include <attr/xattr.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <sys/capability.h>
 #include <sys/prctl.h>
 #include <test.h>

+#include "numcaps.h"
+
 #define TSTPATH "./print_caps"
 char *TCID = "filecaps";
 int TST_TOTAL=1;
@@ -51,7 +52,7 @@ int errno;
 void usage(char *me)
 {
        tst_resm(TFAIL, "Usage: %s <0|1> [arg]\n", me);
-       tst_resm(TINFO, "  0: set file caps without CAP_SYS_ADMIN\n");
+       tst_resm(TINFO, "  0: set file caps without privilege\n");
        tst_resm(TINFO, "  1: test that file caps are set correctly on exec\n");
        tst_exit(1);
 }
@@ -62,7 +63,10 @@ void usage(char *me)
 void print_my_caps()
 {
        cap_t cap = cap_get_proc();
-       tst_resm(TINFO, "\ncaps are %s\n", cap_to_text(cap, NULL));
+       char *txt = cap_to_text(cap, NULL);
+       tst_resm(TINFO, "\ncaps are %s\n", txt);
+       cap_free(cap);
+       cap_free(txt);
 }

 int drop_root(int keep_perms)
@@ -78,52 +82,27 @@ int drop_root(int keep_perms)
                tst_exit(4);
        }
        if (keep_perms) {
-               cap_t cap = cap_from_text("=eip cap_setpcap-eip");
+               cap_t cap = cap_from_text("=eip");
                cap_set_proc(cap);
+               cap_free(cap);
        }

        return 1;
 }

-#if BYTE_ORDER == LITTLE_ENDIAN
-#define cpu_to_le32(x)  x
-#else
-#define cpu_to_le32(x)  bswap_32(x)
-#endif
-
-/*
- * TODO: find a better way to do this.  Emulate libcap's
- * way, or just take it from linux/capability.h
- */
-/*
- * TODO: accomodate 64-bit capabilities
- */
-#define CAPNAME "security.capability"
-#ifndef __CAP_BITS
-#define __CAP_BITS 31
-#endif
-
-#define XATTR_CAPS_SZ (3*sizeof(__le32))
-#define VFS_CAP_REVISION_MASK   0xFF000000
-#define VFS_CAP_REVISION        0x01000000
-
-#define VFS_CAP_FLAGS_MASK      ~VFS_CAP_REVISION_MASK
-#define VFS_CAP_FLAGS_EFFECTIVE 0x000001
-
 int perms_test(void)
 {
        int ret;
-       unsigned int value[3];
-       unsigned int v;
+       cap_t cap;

        drop_root(DROP_PERMS);
-       v = VFS_CAP_REVISION | VFS_CAP_FLAGS_EFFECTIVE;
-       value[0] = cpu_to_le32(v);
-       value[1] = 1;
-       value[2] = 1;
-       ret = setxattr(TSTPATH, CAPNAME, value, 3*sizeof(unsigned int), 0);
+       cap = cap_from_text("all=eip");
+       if (!cap) {
+               tst_resm(TFAIL, "could not get cap from text for perms test\n");
+               return 1;
+       }
+       ret = cap_set_file(TSTPATH, cap);
        if (ret) {
-               perror("setxattr");
                tst_resm(TPASS, "could not set capabilities as non-root\n");
                ret = 0;
        } else {
@@ -131,6 +110,7 @@ int perms_test(void)
                ret = 1;
        }

+       cap_free(cap);
        return ret;
 }

@@ -231,17 +211,15 @@ int fork_drop_and_exec(int keepperms, ch

 int caps_actually_set_test(void)
 {
-       int i, whichset, whichcap, finalret = 0, ret;
-       cap_t cap;
+       int  whichcap, finalret = 0, ret;
+       cap_t fcap, pcap, cap_fullpi;
        char *capstxt;
-       unsigned int value[3];
        cap_value_t capvalue[1];
-       unsigned int magic;
-
-       magic = VFS_CAP_REVISION;
+       int i;

-       cap = cap_init();
-       if (!cap) {
+       fcap = cap_init();
+       pcap = cap_init();
+       if (!fcap || !pcap) {
                perror("cap_init");
                exit(2);
        }
@@ -249,61 +227,64 @@ int caps_actually_set_test(void)
        create_fifo();

        /* first, try each bit in fP (forced) with fE on and off. */
-       value[1] = value[2] =  cpu_to_le32(0);
-       for (whichcap=0; whichcap < __CAP_BITS; whichcap++) {
-               if (whichcap == 8)
-                       continue;
-               /* fE = 0, don't gain the perm */
+       for (whichcap=0; whichcap < NUM_CAPS; whichcap++) {
+               /*
+                * fP=whichcap, fE=fI=0
+                * pP'=whichcap, pI'=pE'=0
+                */
                capvalue[0] = whichcap;
-               value[0] = cpu_to_le32(magic);
-               value[1] = cpu_to_le32(1 << whichcap);
-               ret = setxattr(TSTPATH, CAPNAME, value, 3*sizeof(unsigned int), 
0);
+               cap_clear(fcap);
+               cap_set_flag(fcap, CAP_PERMITTED, 1, capvalue, CAP_SET);
+               ret = cap_set_file(TSTPATH, fcap);
                if (ret) {
-                       tst_resm(TINFO, "%d %d\n", whichset, whichcap);
-                       perror("setxattr");
+                       tst_resm(TINFO, "%d\n", whichcap);
                        continue;
                }
-               /* do a sanity check */
-               cap_clear(cap);
-               cap_set_flag(cap, CAP_PERMITTED, 1, capvalue, CAP_SET);
-               capstxt = cap_to_text(cap, NULL);
+               capstxt = cap_to_text(fcap, NULL);
                ret = fork_drop_and_exec(DROP_PERMS, capstxt);
+               cap_free(capstxt);
                if (ret) {
                        tst_resm(TINFO, "Failed CAP_PERMITTED=%d 
CAP_EFFECTIVE=0\n",
                                        whichcap);
-                       if (!finalret)
-                               finalret = ret;
+                       if (!finalret) finalret = ret;
                }

-               /* fE = 1, do gain the perm */
-               value[0] = cpu_to_le32(magic | VFS_CAP_FLAGS_EFFECTIVE);
-               value[1] = cpu_to_le32(1 << whichcap);
-               ret = setxattr(TSTPATH, CAPNAME, value, 3*sizeof(unsigned int), 
0);
+/* SERGE here */
+               /*
+                * fP = fE = whichcap, fI = 0
+                * pP = pE = whichcap, pI = 0
+                */
+               cap_clear(fcap);
+               cap_set_flag(fcap, CAP_PERMITTED, 1, capvalue, CAP_SET);
+               cap_set_flag(fcap, CAP_EFFECTIVE, 1, capvalue, CAP_SET);
+               ret = cap_set_file(TSTPATH, fcap);
                if (ret) {
-                       tst_resm(TINFO, "%d %d\n", whichset, whichcap);
-                       perror("setxattr");
+                       tst_resm(TINFO, "%d\n", whichcap);
                        continue;
                }
-               /* do a sanity check */
-               cap_clear(cap);
-               cap_set_flag(cap, CAP_PERMITTED, 1, capvalue, CAP_SET);
-               cap_set_flag(cap, CAP_EFFECTIVE, 1, capvalue, CAP_SET);
-               capstxt = cap_to_text(cap, NULL);
+               capstxt = cap_to_text(fcap, NULL);
                if (strcmp(capstxt, "=")==0) {
                        tst_resm(TINFO, "%s: libcap doesn't know about cap %d, not 
running\n",
                                __FUNCTION__, whichcap);
                        ret = 0;
                } else
                        ret = fork_drop_and_exec(DROP_PERMS, capstxt);
+               cap_free(capstxt);
                if (ret) {
                        tst_resm(TINFO, "Failed CAP_PERMITTED=%d 
CAP_EFFECTIVE=1\n",
                                whichcap);
-                       if (!finalret)
-                               finalret = ret;
+                       if (!finalret) finalret = ret;
                }
        }


+       cap_free(pcap);
+       cap_free(fcap);
+       cap_fullpi = cap_init();
+       for (i=0; i<NUM_CAPS; i++) {
+               capvalue[0] = i;
+               cap_set_flag(cap_fullpi, CAP_INHERITABLE, 1, capvalue, CAP_SET);
+       }
        /*
         * next try each bit in fI
         * The first two attemps have the bit which is in fI in pI.
@@ -313,72 +294,60 @@ int caps_actually_set_test(void)
         *     This should result in empty capability, as there were
         *     no bits to be inherited from the original process.
         */
-       value[1] = value[2] =  cpu_to_le32(0);
-       for (whichcap=0; whichcap < __CAP_BITS; whichcap++) {
-               if (whichcap == 8)
-                       continue;
+       for (whichcap=0; whichcap < NUM_CAPS; whichcap++) {
+               capvalue[0] = whichcap;
+
                /*
-                * bit is in fI and pI, so should be in pI'.
-                * but fE=0, so cap is in pP' but not pE'.
+                * fI=whichcap, fP=fE=0
+                * pI=full
+                * pI'=full, pP'=whichcap, pE'=0
                 */
-               value[0] = cpu_to_le32(magic);
-               value[2] = cpu_to_le32(1 << whichcap);
-               ret = setxattr(TSTPATH, CAPNAME, value, 3*sizeof(unsigned int), 
0);
+               /* fill pI' */
+               pcap = cap_dup(cap_fullpi);
+               /* pP' = whichcap */
+               cap_set_flag(pcap, CAP_PERMITTED, 1, capvalue, CAP_SET);
+
+               /* fI = whichcap */
+               fcap = cap_init();
+               cap_set_flag(fcap, CAP_INHERITABLE, 1, capvalue, CAP_SET);
+               ret = cap_set_file(TSTPATH, fcap);
                if (ret) {
-                       tst_resm(TINFO, "%d %d\n", whichset, whichcap);
-                       perror("setxattr");
+                       tst_resm(TINFO, "%d\n", whichcap);
                        continue;
                }
-               /* do a sanity check */
-               cap_clear(cap);
-               for (i=0; i<32; i++) {
-                       if (i != 8) {
-                               capvalue[0] = i;
-                               cap_set_flag(cap, CAP_INHERITABLE, 1, capvalue, 
CAP_SET);
-                       }
-               }
-               capvalue[0] = whichcap;
-               cap_set_flag(cap, CAP_PERMITTED, 1, capvalue, CAP_SET);
-               capstxt = cap_to_text(cap, NULL);
+               capstxt = cap_to_text(pcap, NULL);
                ret = fork_drop_and_exec(KEEP_PERMS,  capstxt);
+               cap_free(capstxt);
                if (ret) {
                        tst_resm(TINFO, "Failed with_perms CAP_INHERITABLE=%d "
                                        "CAP_EFFECTIVE=0\n", whichcap);
-                       if (!finalret)
-                               finalret = ret;
+                       if (!finalret) finalret = ret;
                }

                /*
-                * bit is in fI and pI, so should be in pI'.
-                * and fE=1, so cap is in pP' and pE'.
+                * fI=fE=whichcap, fP=0
+                * pI=full
+                * pI'=full, pP'=whichcap, pE'=whichcap
+                *
+                * Note that only fE and pE' change, so keep prior
+                * fcap and pcap and set those bits.
                 */

-               value[0] = cpu_to_le32(magic | VFS_CAP_FLAGS_EFFECTIVE);
-               value[2] = cpu_to_le32(1 << whichcap);
-               ret = setxattr(TSTPATH, CAPNAME, value, 3*sizeof(unsigned int), 
0);
+               cap_set_flag(fcap, CAP_EFFECTIVE, 1, capvalue, CAP_SET);
+               cap_set_flag(pcap, CAP_EFFECTIVE, 1, capvalue, CAP_SET);
+               ret = cap_set_file(TSTPATH, fcap);
                if (ret) {
-                       tst_resm(TINFO, "%d %d\n", whichset, whichcap);
-                       perror("setxattr");
+                       tst_resm(TINFO, "%d\n", whichcap);
                        continue;
                }
-               /* do a sanity check */
-               cap_clear(cap);
-               for (i=0; i<32; i++) {
-                       if (i != 8) {
-                               capvalue[0] = i;
-                               cap_set_flag(cap, CAP_INHERITABLE, 1, capvalue, 
CAP_SET);
-                       }
-               }
-               capvalue[0] = whichcap;
-               cap_set_flag(cap, CAP_PERMITTED, 1, capvalue, CAP_SET);
-               cap_set_flag(cap, CAP_EFFECTIVE, 1, capvalue, CAP_SET);
-               capstxt = cap_to_text(cap, NULL);
+               capstxt = cap_to_text(pcap, NULL);
                if (strcmp(capstxt, "=")==0) {
                        tst_resm(TINFO, "%s: libcap doesn't know about cap %d, not 
running\n",
                                __FUNCTION__, whichcap);
                        ret = 0;
                } else
                        ret = fork_drop_and_exec(KEEP_PERMS, capstxt);
+               cap_free(capstxt);
                if (ret) {
                        tst_resm(TINFO, "Failed with_perms CAP_INHERITABLE=%d "
                                        "CAP_EFFECTIVE=1\n", whichcap);
@@ -387,31 +356,27 @@ int caps_actually_set_test(void)
                }

                /*
-                * bit is in fI but not in pI
-                * So pP' is empty.
-                * pE' must be empty.
+                * fI=fE=whichcap, fP=0  (so fcap is same as before)
+                * pI=0  (achieved using DROP_PERMS)
+                * pI'=pP'=pE'=0
                 */
-               value[0] = cpu_to_le32(magic | VFS_CAP_FLAGS_EFFECTIVE);
-               value[2] = cpu_to_le32(1 << whichcap);
-               ret = setxattr(TSTPATH, CAPNAME, value, 3*sizeof(unsigned int), 
0);
-               if (ret) {
-                       tst_resm(TINFO, "%d %d\n", whichset, whichcap);
-                       perror("setxattr");
-                       continue;
-               }
-               /* do a sanity check */
-               cap_clear(cap);
-               capstxt = cap_to_text(cap, NULL);
+               cap_clear(pcap);
+               capstxt = cap_to_text(pcap, NULL);
                ret = fork_drop_and_exec(DROP_PERMS, capstxt);
+               cap_free(capstxt);
                if (ret) {
                        tst_resm(TINFO, "Failed without_perms 
CAP_INHERITABLE=%d",
                                        whichcap);
                        if (!finalret)
                                finalret = ret;
                }
+
+               cap_free(fcap);
+               cap_free(pcap);
        }

-       cap_free(cap);
+       cap_free(cap_fullpi);
+
        return finalret;
 }


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to