Hi Subrata,

here is yet another version.  There must be a cleaner way to
do this, but this appears to at least work so I'd like to let
it sit for awhile and see how it goes.

(The reason for splitting up the libcap and
CONFIG_SECURITY_CAPABILITIES checks is that if libcap isn't
there then the tests can't be compiled, whereas if it's the
kernel missing a feature then compilation can succeed, the
tests simply shouldn't run.)

thanks,
-serge
diff -Nrup ltp-full-20071231/runltp ltp-full-20071231-filecaps/runltp
--- ltp-full-20071231/runltp    2008-01-01 06:44:38.000000000 -0500
+++ ltp-full-20071231-filecaps/runltp   2008-01-21 08:34:20.000000000 -0500
@@ -487,7 +487,8 @@ main()
                      ${LTPROOT}/runtest/mm ${LTPROOT}/runtest/ipc \
                      ${LTPROOT}/runtest/sched ${LTPROOT}/runtest/math \
                      ${LTPROOT}/runtest/nptl ${LTPROOT}/runtest/pty \
-                     ${LTPROOT}/runtest/containers
+                     ${LTPROOT}/runtest/containers \
+                     ${LTPROOT}/runtest/filecaps
         do
             [ -a "$SCENFILES" ] || \
             {
diff -Nrup ltp-full-20071231/runtest/filecaps 
ltp-full-20071231-filecaps/runtest/filecaps
--- ltp-full-20071231/runtest/filecaps  1969-12-31 19:00:00.000000000 -0500
+++ ltp-full-20071231-filecaps/runtest/filecaps 2008-01-21 08:34:20.000000000 
-0500
@@ -0,0 +1,2 @@
+#DESCRIPTION:file capabilities
+Filecaps       filecapstest.sh
diff -Nrup 
ltp-full-20071231/testcases/kernel/security/filecaps/checkforfilecaps.sh 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/checkforfilecaps.sh
--- ltp-full-20071231/testcases/kernel/security/filecaps/checkforfilecaps.sh    
1969-12-31 19:00:00.000000000 -0500
+++ 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/checkforfilecaps.sh
   2008-01-22 14:38:24.000000000 -0500
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+check_simple_capset
+ret=$?
+if [ $ret -ne 0 ]; then
+       echo Posix capabilities not compiled into the kernel.  Please
+       echo modprobe capability or recompile your kernel with
+       echo CONFIG_SECURITY_CAPABILITIES=y.
+       exit 1
+fi
+
+touch testme
+setcap cap_sys_admin=ip testme
+ret=$?
+rm -f testme
+if [ $ret -ne 0 ]; then
+       echo File capabilities not compiled into kernel.  Please
+       echo make sure your kernel is compiled with
+       echo CONFIG_SECURITY_FILE_CAPABILITIES=y.
+       exit 1
+fi
+
+exit 0
diff -Nrup 
ltp-full-20071231/testcases/kernel/security/filecaps/checkforlibcap.sh 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/checkforlibcap.sh
--- ltp-full-20071231/testcases/kernel/security/filecaps/checkforlibcap.sh      
1969-12-31 19:00:00.000000000 -0500
+++ 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/checkforlibcap.sh 
    2008-01-22 14:38:24.000000000 -0500
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+yesno=0
+if [ "$1" == "yesno" ]; then
+       yesno=1
+fi
+SETCAP=`which setcap`
+ret=$?
+if [ $ret -eq 0 ]; then
+       #also test for -lcap
+       gcc -o check_simple_capset check_simple_capset.c -lcap
+       ret=$?
+fi
+
+if [ $ret -ne 0 ]; then
+       if [ $yesno -eq 1 ]; then
+               echo no
+       else
+               exit 1
+       fi
+else
+       if [ $yesno -eq 1 ]; then
+               echo yes
+       else
+               exit 0
+       fi
+fi
diff -Nrup 
ltp-full-20071231/testcases/kernel/security/filecaps/check_simple_capset.c 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/check_simple_capset.c
--- ltp-full-20071231/testcases/kernel/security/filecaps/check_simple_capset.c  
1969-12-31 19:00:00.000000000 -0500
+++ 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/check_simple_capset.c
 2008-01-22 14:38:24.000000000 -0500
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <sys/capability.h>
+
+int main()
+{
+       cap_t caps;
+       int ret;
+
+       caps = cap_from_text("cap_setpcap+ep");
+       ret = cap_set_proc(caps);
+
+       cap_free(caps);
+       return ret;
+}
diff -Nrup ltp-full-20071231/testcases/kernel/security/filecaps/filecapstest.sh 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/filecapstest.sh
--- ltp-full-20071231/testcases/kernel/security/filecaps/filecapstest.sh        
1969-12-31 19:00:00.000000000 -0500
+++ 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/filecapstest.sh   
    2008-01-22 14:38:23.000000000 -0500
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+checkforlibcap
+ret=$?
+if [ $ret -ne 0 ]; then
+       echo setcap not installed.  Please install libcap from
+       echo ftp://ftp.kernel.org/pub/linux/libs/security/linux-privs/libcap2
+       exit 1
+fi
+checkforfilecaps.sh
+ret=$?
+if [ $ret -ne 0 ]; then
+       exit 1
+fi
+
+echo "Running in:"
+cp $LTPROOT/testcases/bin/print_caps .
+mkfifo caps_fifo
+chmod 777 caps_fifo
+exit_code=0
+echo "cap_sys_admin tests"
+verify_caps_exec 0
+tmp=$?
+if [ $tmp -ne 0 ]; then
+       exit_code=$tmp
+fi
+
+echo "testing for correct caps"
+verify_caps_exec 1
+tmp=$?
+if [ $tmp -ne 0 ]; then
+       exit_code=$tmp
+fi
+
+echo "testing for correct pI checks"
+inh_capped
+tmp=$?
+if [ $tmp -ne 0 ]; then
+       exit_code=$tmp
+fi
+
+exit $exit_code
diff -Nrup ltp-full-20071231/testcases/kernel/security/filecaps/gotlibcap.c 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/gotlibcap.c
--- ltp-full-20071231/testcases/kernel/security/filecaps/gotlibcap.c    
1969-12-31 19:00:00.000000000 -0500
+++ ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/gotlibcap.c   
2008-01-22 14:38:24.000000000 -0500
@@ -0,0 +1 @@
+int main() { return 0; }
diff -Nrup ltp-full-20071231/testcases/kernel/security/filecaps/inh_capped.c 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/inh_capped.c
--- ltp-full-20071231/testcases/kernel/security/filecaps/inh_capped.c   
1969-12-31 19:00:00.000000000 -0500
+++ ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/inh_capped.c  
2008-01-22 14:38:24.000000000 -0500
@@ -0,0 +1,94 @@
+/*
+ * File: inh_capped
+ * Author: Serge Hallyn
+ * Copyright 2008 IBM Corp
+ * Purpose: test that CAP_SETPCAP is needed to add bits to pI
+ * Uses no command line arguments.
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <sys/capability.h>
+#include <test.h>
+
+char *TCID = "filecaps";
+int TST_TOTAL=1;
+
+#define DEBUG 1
+
+void debug_print_caps(char *when)
+{
+#ifdef DEBUG
+       char buf[2000];
+       tst_resm(TINFO, "%s", when);
+       snprintf(buf, 2000, "%s", cap_to_text(cap_get_proc(), NULL));
+       tst_resm(TINFO, "%s", buf);
+#endif
+}
+
+int set_caps_from_text(char *capstr)
+{
+       cap_t caps = cap_from_text(capstr);
+       int ret;
+
+       if (!caps) {
+               tst_resm(TFAIL, "Bad capability name: %s\n", capstr);
+               return 1;
+       }
+       ret = cap_set_proc(caps);
+       cap_free(caps);
+       return ret;
+}
+
+int main()
+{
+       int ret;
+
+       debug_print_caps("start");
+       ret = set_caps_from_text("all=eip");
+       debug_print_caps("after raising all caps");
+       if (ret) {
+               tst_resm(TFAIL, "failed to raise all caps");
+               tst_exit(ret);
+       }
+
+       ret = set_caps_from_text("all=iep cap_sys_admin-iep");
+       debug_print_caps("after first drop cap_sys_admin");
+       if (ret) {
+               tst_resm(TFAIL, "failed to drop capsysadmin from pI");
+               tst_exit(ret);
+       }
+
+       /* we can't regain cap_sys_admin in pE or pP, only pI */
+       ret = set_caps_from_text("all=eip cap_sys_admin-ep+i");
+       debug_print_caps("after first raise cap_sys_admin");
+       if (ret) {
+               tst_resm(TFAIL, "failed to raise capsysadmin in pI");
+               tst_exit(ret);
+       }
+
+       ret = set_caps_from_text("all=ip cap_setpcap-e+ip cap_sys_admin+i-ep");
+       debug_print_caps("after drop cappset");
+       if (ret) {
+               tst_resm(TFAIL, "failed to drop cappset from pE");
+               tst_exit(ret);
+       }
+
+       ret = set_caps_from_text("all=iep cap_sys_admin-iep cap_setpcap-e+ip");
+       debug_print_caps("after second drop cap_sys_admin");
+       if (ret) {
+               tst_resm(TFAIL, "failed to drop capsysadmin from pI "
+                               "after dropping cappset from pE");
+               tst_exit(ret);
+       }
+
+       ret = set_caps_from_text("all=iep cap_sys_admin-ep+i cap_setpcap-e+ip");
+       debug_print_caps("final");
+       if (ret) {
+               tst_resm(TPASS, "pI is properly capped\n");
+               tst_exit(0);
+       }
+
+       tst_resm(TFAIL, "succeeded raising capsysadmin in pI "
+                       "without having setpcap");
+       tst_exit(ret);
+}
diff -Nrup ltp-full-20071231/testcases/kernel/security/filecaps/Makefile 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/Makefile
--- ltp-full-20071231/testcases/kernel/security/filecaps/Makefile       
1969-12-31 19:00:00.000000000 -0500
+++ ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/Makefile      
2008-01-22 14:38:23.000000000 -0500
@@ -0,0 +1,25 @@
+SCRIPTS = filecapstest.sh checkforlibcap.sh checkforfilecaps.sh
+ifeq ($(shell sh checkforlibcap.sh yesno),yes)
+CC=gcc
+
+CFLAGS += -I../../../../include -Wall
+LDLIBS += -L../../../../lib -lltp -lcap
+
+SRCS    = $(wildcard *.c)
+TARGETS = $(patsubst %.c,%,$(SRCS))
+INSTALLTARGETS = $(TARGETS) $(SCRIPTS)
+all: $(TARGETS)
+       gcc -o checkforlibcap gotlibcap.c
+else
+all:
+       @echo "setcap not installed.  Please install libcap from"; echo 
"ftp://ftp.kernel.org/pub/linux/libs/security/linux-privs/libcap2";; echo "Then 
make clean in ltp or ltp/testcases/kernel/security/filecaps, and recompile ltp."
+       gcc -o checkforlibcap nolibcap.c
+TARGETS =
+endif
+
+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
diff -Nrup ltp-full-20071231/testcases/kernel/security/filecaps/nolibcap.c 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/nolibcap.c
--- ltp-full-20071231/testcases/kernel/security/filecaps/nolibcap.c     
1969-12-31 19:00:00.000000000 -0500
+++ ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/nolibcap.c    
2008-01-22 14:38:24.000000000 -0500
@@ -0,0 +1 @@
+int main() { return 1; }
diff -Nrup ltp-full-20071231/testcases/kernel/security/filecaps/print_caps.c 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/print_caps.c
--- ltp-full-20071231/testcases/kernel/security/filecaps/print_caps.c   
1969-12-31 19:00:00.000000000 -0500
+++ ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/print_caps.c  
2008-01-22 14:38:23.000000000 -0500
@@ -0,0 +1,46 @@
+/*
+ * File: print_caps.c
+ * Author: Serge Hallyn
+ * Copyright 2007,2008 IBM Corp
+ * Purpose: print out the POSIX capabilities with which it runs
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/capability.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define FIFOFILE "caps_fifo"
+
+int main(int argc, char *argv[])
+{
+       cap_t cap = cap_get_proc();
+       int fd;
+       int seqno = 0;
+       char buf[2000];
+
+       if (argc>1)
+               seqno = atoi(argv[1]);
+
+       if (!cap) {
+               perror("print_caps - cap_get_proc");
+               exit(1);
+       }
+
+       fd = open(FIFOFILE, O_WRONLY);
+       if (!fd) {
+               perror("print_caps: open fifo");
+               exit(2);
+       }
+
+       snprintf(buf, 2000, "%d.%s", seqno, cap_to_text(cap, NULL));
+       write(fd, buf, strlen(buf)+1);
+       close(fd);
+
+       cap_free(cap);
+
+       return 0;
+}
diff -Nrup ltp-full-20071231/testcases/kernel/security/filecaps/README 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/README
--- ltp-full-20071231/testcases/kernel/security/filecaps/README 1969-12-31 
19:00:00.000000000 -0500
+++ ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/README        
2008-01-22 14:38:24.000000000 -0500
@@ -0,0 +1,36 @@
+POSIX capabilities are pieces of root privilege, for instance
+CAP_SYS_NICE to set priority on other tasks and CAP_SYS_TIME
+to set system time.  See
+http://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.4/capfaq-0.2.txt
+for more information.
+
+A task's capabilities are set when it executes a new file, and
+when it explicitly changes them (see capset(2)).  After exec,
+the task's new capabilities are a function of its previous
+capabilities and the file's capabilities:
+
+       pI' = pI
+       pP' = fP | (fI & pI)
+       pE' = fE ? pP' : 0
+
+Where pX is capability set X for process p before exec, pX' is
+capability set X for process P after exec and fX is file
+capability set X.  The capability sets are I for inheritable,
+P for permitted, and E for effective.  Note that fE is a
+boolean rather than a set.
+
+File capabilities are stored in extended attributes named
+'security.capability.'  Setting this xattr requires the
+CAP_SETFCAP capability when the capability security module is
+loaded, or CAP_SYS_ADMIN when it is not.
+
+The following tests are implemented here:
+
+inh_capped: check whether a process without CAP_SETPCAP
+       is properly prohibited from raising bits in its
+       inheritable set using setcap.
+
+verify_caps_exec:
+       1. check that privilege is needed to set file capabilities
+       2. check that pI', pP', and pE' are properly
+          calculated upon exec.
diff -Nrup 
ltp-full-20071231/testcases/kernel/security/filecaps/verify_caps_exec.c 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/verify_caps_exec.c
--- ltp-full-20071231/testcases/kernel/security/filecaps/verify_caps_exec.c     
1969-12-31 19:00:00.000000000 -0500
+++ 
ltp-full-20071231-filecaps/testcases/kernel/security/filecaps/verify_caps_exec.c
    2008-01-22 14:38:23.000000000 -0500
@@ -0,0 +1,421 @@
+/*
+ * File: verify_caps_exec.c
+ * Author: Serge Hallyn
+ * Copyright 2007,2008 IBM Corp
+ * Purpose: perform several tests of file capabilities:
+ *  1. try setting caps without CAP_SYS_ADMIN
+ *  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
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <endian.h>
+#include <byteswap.h>
+#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>
+
+#define TSTPATH "./print_caps"
+char *TCID = "filecaps";
+int TST_TOTAL=1;
+
+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, "  1: test that file caps are set correctly on exec\n");
+       tst_exit(1);
+}
+
+#define DROP_PERMS 0
+#define KEEP_PERMS 1
+
+void print_my_caps()
+{
+       cap_t cap = cap_get_proc();
+       tst_resm(TINFO, "\ncaps are %s\n", cap_to_text(cap, NULL));
+}
+
+int drop_root(int keep_perms)
+{
+       int ret;
+
+       if (keep_perms)
+               prctl(PR_SET_KEEPCAPS, 1);
+       ret = setresuid(1000, 1000, 1000);
+       if (ret) {
+               perror("setresuid");
+               tst_resm(TFAIL, "Error dropping root privs\n");
+               tst_exit(4);
+       }
+       if (keep_perms) {
+               cap_t cap = cap_from_text("=eip cap_setpcap-eip");
+               cap_set_proc(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;
+
+       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);
+       if (ret) {
+               perror("setxattr");
+               tst_resm(TPASS, "could not set capabilities as non-root\n");
+               ret = 0;
+       } else {
+               tst_resm(TFAIL, "could set capabilities as non-root\n");
+               ret = 1;
+       }
+
+       return ret;
+}
+
+#define FIFOFILE "caps_fifo"
+void create_fifo(void)
+{
+       int ret;
+
+       ret = mkfifo(FIFOFILE, S_IRWXU | S_IRWXG | S_IRWXO);
+       if (ret == -1 && errno != EEXIST) {
+               perror("mkfifo");
+               tst_resm(TFAIL, "failed creating %s\n", FIFOFILE);
+               tst_exit(1);
+       }
+}
+
+void write_to_fifo(char *buf)
+{
+       int fd;
+
+       fd = open(FIFOFILE, O_WRONLY);
+       write(fd, buf, strlen(buf));
+       close(fd);
+}
+
+void read_from_fifo(char *buf)
+{
+       int fd;
+
+       memset(buf, 0, 200);
+       fd = open(FIFOFILE, O_RDONLY);
+       if (fd < 0) {
+               perror("open");
+               tst_resm(TFAIL, "Failed opening fifo\n");
+               tst_exit(1);
+       }
+       read(fd, buf, 199);
+       close(fd);
+}
+
+int compare_caps(char *buf1, char *buf2)
+{
+       int res;
+
+       res = strcmp(buf1, buf2) == 0;
+       return res;
+}
+
+int fork_drop_and_exec(int keepperms, char *capstxt)
+{
+       int pid;
+       int ret = 0;
+       char buf[200], *p;
+       static int seqno = 0;
+
+       pid = fork();
+       if (pid < 0) {
+               perror("fork");
+               tst_resm(TFAIL, "%s: failed fork\n", __FUNCTION__);
+               tst_exit(1);
+       }
+       if (pid == 0) {
+               drop_root(keepperms);
+               print_my_caps();
+               sprintf(buf, "%d", seqno);
+               ret = execlp(TSTPATH, TSTPATH, buf, NULL);
+               perror("execl");
+               tst_resm(TFAIL, "%s: exec failed\n", __FUNCTION__);
+               snprintf(buf, 200, "failed to run as %s\n", capstxt);
+               write_to_fifo(buf);
+               tst_exit(1);
+       } else {
+               p = buf;
+               while (1) {
+                       int c, s;
+                       read_from_fifo(buf);
+                       c = sscanf(buf, "%d", &s);
+                       if (c==1 && s==seqno)
+                               break;
+                       tst_resm(TINFO, "got a bad seqno (c=%d, s=%d, 
seqno=%d)",
+                               c, s, seqno);
+               }
+               p = index(buf, '.')+1;
+               if (p==(char *)1) {
+                       tst_resm(TFAIL, "got a bad message from print_caps\n");
+                       tst_exit(1);
+               }
+               tst_resm(TINFO, "Expected to run as .%s., ran as .%s..\n",
+                       capstxt, p);
+               if (strcmp(p, capstxt) != 0) {
+                       tst_resm(TINFO, "those are not the same\n");
+                       ret = -1;
+               }
+               seqno++;
+       }
+       return ret;
+}
+
+int caps_actually_set_test(void)
+{
+       int i, whichset, whichcap, finalret = 0, ret;
+       cap_t cap;
+       char *capstxt;
+       unsigned int value[3];
+       cap_value_t capvalue[1];
+       unsigned int magic;
+
+       magic = VFS_CAP_REVISION;
+
+       cap = cap_init();
+       if (!cap) {
+               perror("cap_init");
+               exit(2);
+       }
+
+       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 */
+               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);
+               if (ret) {
+                       tst_resm(TINFO, "%d %d\n", whichset, whichcap);
+                       perror("setxattr");
+                       continue;
+               }
+               /* do a sanity check */
+               cap_clear(cap);
+               cap_set_flag(cap, CAP_PERMITTED, 1, capvalue, CAP_SET);
+               capstxt = cap_to_text(cap, NULL);
+               ret = fork_drop_and_exec(DROP_PERMS, capstxt);
+               if (ret) {
+                       tst_resm(TINFO, "Failed CAP_PERMITTED=%d 
CAP_EFFECTIVE=0\n",
+                                       whichcap);
+                       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);
+               if (ret) {
+                       tst_resm(TINFO, "%d %d\n", whichset, whichcap);
+                       perror("setxattr");
+                       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);
+               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);
+               if (ret) {
+                       tst_resm(TINFO, "Failed CAP_PERMITTED=%d 
CAP_EFFECTIVE=1\n",
+                               whichcap);
+                       if (!finalret)
+                               finalret = ret;
+               }
+       }
+
+
+       /*
+        * next try each bit in fI
+        * The first two attemps have the bit which is in fI in pI.
+        *     This should result in the bit being in pP'.
+        *     If fE was set then it should also be in pE'.
+        * The last attempt starts with an empty pI.
+        *     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;
+               /*
+                * bit is in fI and pI, so should be in pI'.
+                * but fE=0, so cap is in pP' but not pE'.
+                */
+               value[0] = cpu_to_le32(magic);
+               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);
+               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);
+               ret = fork_drop_and_exec(KEEP_PERMS,  capstxt);
+               if (ret) {
+                       tst_resm(TINFO, "Failed with_perms CAP_INHERITABLE=%d "
+                                       "CAP_EFFECTIVE=0\n", whichcap);
+                       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'.
+                */
+
+               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);
+               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);
+               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);
+               if (ret) {
+                       tst_resm(TINFO, "Failed with_perms CAP_INHERITABLE=%d "
+                                       "CAP_EFFECTIVE=1\n", whichcap);
+                       if (!finalret)
+                               finalret = ret;
+               }
+
+               /*
+                * bit is in fI but not in pI
+                * So pP' is empty.
+                * pE' must be empty.
+                */
+               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);
+               ret = fork_drop_and_exec(DROP_PERMS, capstxt);
+               if (ret) {
+                       tst_resm(TINFO, "Failed without_perms 
CAP_INHERITABLE=%d",
+                                       whichcap);
+                       if (!finalret)
+                               finalret = ret;
+               }
+       }
+
+       cap_free(cap);
+       return finalret;
+}
+
+int main(int argc, char *argv[])
+{
+       int ret = 0;
+
+       if (argc < 2)
+               usage(argv[0]);
+
+       switch(atoi(argv[1])) {
+               case 0:
+                       ret = perms_test();
+                       break;
+               case 1:
+                       ret = caps_actually_set_test();
+                       if (ret)
+                               tst_resm(TFAIL, "Some tests failed\n");
+                       else
+                               tst_resm(TPASS, "All tests passed\n");
+                       break;
+               default: usage(argv[0]);
+       }
+
+       tst_exit(ret);
+}
diff -Nrup ltp-full-20071231/testcases/kernel/security/Makefile 
ltp-full-20071231-filecaps/testcases/kernel/security/Makefile
--- ltp-full-20071231/testcases/kernel/security/Makefile        2008-01-01 
06:44:42.000000000 -0500
+++ ltp-full-20071231-filecaps/testcases/kernel/security/Makefile       
2008-01-22 09:13:52.000000000 -0500
@@ -1,4 +1,4 @@
-SUBDIRS = mmc_security
+SUBDIRS = mmc_security filecaps
 
 all:
        @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i ; done
diff -Nrup ltp-full-20071231/testscripts/test_filecaps.sh 
ltp-full-20071231-filecaps/testscripts/test_filecaps.sh
--- ltp-full-20071231/testscripts/test_filecaps.sh      1969-12-31 
19:00:00.000000000 -0500
+++ ltp-full-20071231-filecaps/testscripts/test_filecaps.sh     2008-01-21 
08:34:20.000000000 -0500
@@ -0,0 +1,47 @@
+#!/bin/bash
+#
+# Copyright 2007 IBM
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# test_filecaps.sh - Run the file capabilities test suite.
+
+# Must be root to run the containers testsuite
+if [ $UID != 0 ]
+then
+        echo "FAILED: Must be root to execute this script"
+        exit 1
+fi
+
+# set the LTPROOT directory
+cd `dirname $0`
+LTPROOT=${PWD}
+echo $LTPROOT | grep testscripts > /dev/null 2>&1
+if [ $? -eq 0 ]
+then
+       cd ..
+       LTPROOT=${PWD}
+fi
+
+# set the PATH to include testcase/bin
+
+export PATH=$PATH:/usr/sbin:$LTPROOT/testcases/bin
+export LTPBIN=$LTPROOT/testcases/bin
+
+# We will store the logfiles in $LTPROOT/results, so make sure
+# it exists.
+if [ ! -d $LTPROOT/results ]
+then
+       mkdir $LTPROOT/results
+fi
+
+# Check the role and mode testsuite is being executed under.
+echo "Running the file capabilities testsuite..."
+
+$LTPROOT/pan/pan -S -a $LTPROOT/results/filecaps -n ltp-filecaps -l 
$LTPROOT/results/filecaps.logfile -o $LTPROOT/results/filecaps.outfile -p -f 
$LTPROOT/runtest/filecaps
+
+echo "Done."
+exit 0

Reply via email to