Add capability bounding set testcases, to verify the following:

        1. prctl(CAP_BSET_READ, 0..NCAPS) returns 1
        2. prctl(CAP_BSET_READ, -1|NCAPS+1) return -1

        3. prctl(CAP_BSET_DROP, -1|NCAPS+1) returns -1
        4. prctl(CAP_BSET_DROP, 0..NCAPS) returns 1
           4b. prctl(CAP_BSET_READ, N) returns 0 after each unset, 1 for those 
not yet removed

        5. fI=empty; N \notin pP; prctl(CAPBSET_DROP, N); setting pI=N fails

        6. pI=N; fI=fE=N; prctl(CAPBSET_DROP, N); exec(f) - N \in pE
                (or make f setuid-root)
        7. pI=0; fI=fE=N; prctl(CAPBSET_DROP, N); exec(f) - N \notin pE
                (or make f setuid-root)

A set of securebits and keepcaps tests have yet to be written (as
per an email I sent a few months ago).

Signed-off-by: Serge Hallyn <[email protected]>
---
 runltp                                             |    1 +
 runtest/cap_bounds                                 |    2 +
 testcases/kernel/security/Makefile                 |    2 +-
 testcases/kernel/security/cap_bound/Makefile       |   58 +++++++++
 testcases/kernel/security/cap_bound/cap_bounds_r.c |   86 +++++++++++++
 .../kernel/security/cap_bound/cap_bounds_rw.c      |  124 ++++++++++++++++++
 .../security/cap_bound/cap_bset_inh_bounds.c       |  131 ++++++++++++++++++++
 .../kernel/security/cap_bound/check_for_libcap.sh  |   46 +++++++
 testcases/kernel/security/cap_bound/check_pe.c     |   80 ++++++++++++
 testcases/kernel/security/cap_bound/dummy.c        |    9 ++
 .../kernel/security/cap_bound/exec_with_inh.c      |   93 ++++++++++++++
 .../kernel/security/cap_bound/exec_without_inh.c   |   88 +++++++++++++
 .../kernel/security/cap_bound/run_capbounds.sh     |   62 +++++++++
 13 files changed, 781 insertions(+), 1 deletions(-)
 create mode 100644 runtest/cap_bounds
 create mode 100644 testcases/kernel/security/cap_bound/Makefile
 create mode 100644 testcases/kernel/security/cap_bound/cap_bounds_r.c
 create mode 100644 testcases/kernel/security/cap_bound/cap_bounds_rw.c
 create mode 100644 testcases/kernel/security/cap_bound/cap_bset_inh_bounds.c
 create mode 100644 testcases/kernel/security/cap_bound/check_for_libcap.sh
 create mode 100644 testcases/kernel/security/cap_bound/check_pe.c
 create mode 100644 testcases/kernel/security/cap_bound/dummy.c
 create mode 100644 testcases/kernel/security/cap_bound/exec_with_inh.c
 create mode 100644 testcases/kernel/security/cap_bound/exec_without_inh.c
 create mode 100755 testcases/kernel/security/cap_bound/run_capbounds.sh

diff --git a/runltp b/runltp
index 8626cc0..ceff41e 100755
--- a/runltp
+++ b/runltp
@@ -538,6 +538,7 @@ main()
                          ${LTPROOT}/runtest/fs_bind                 \
                          ${LTPROOT}/runtest/controllers             \
                          ${LTPROOT}/runtest/filecaps                \
+                         ${LTPROOT}/runtest/cap_bounds              \
                          ${LTPROOT}/runtest/fcntl-locktests         \
                          ${LTPROOT}/runtest/connectors              \
                          ${LTPROOT}/runtest/admin_tools             \
diff --git a/runtest/cap_bounds b/runtest/cap_bounds
new file mode 100644
index 0000000..518d1e3
--- /dev/null
+++ b/runtest/cap_bounds
@@ -0,0 +1,2 @@
+#DESCRIPTION:Posix capability bounding set
+Cap_bounds     run_capbounds.sh
diff --git a/testcases/kernel/security/Makefile 
b/testcases/kernel/security/Makefile
index d94ff24..862691a 100644
--- a/testcases/kernel/security/Makefile
+++ b/testcases/kernel/security/Makefile
@@ -1,4 +1,4 @@
-SUBDIRS = mmc_security filecaps integrity
+SUBDIRS = mmc_security filecaps integrity cap_bound
 
 all:
        @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i ; done
diff --git a/testcases/kernel/security/cap_bound/Makefile 
b/testcases/kernel/security/cap_bound/Makefile
new file mode 100644
index 0000000..5d0ae8b
--- /dev/null
+++ b/testcases/kernel/security/cap_bound/Makefile
@@ -0,0 +1,58 @@
+################################################################################
+##                                                                            
##
+## Copyright (c) International Business Machines  Corp., 2008                 
##
+##                                                                            
##
+## 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.                                        
##
+##                                                                            
##
+## This program is distributed in the hope that it will be useful, but        
##
+## WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
##
+## or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License   
##
+## for more details.                                                          
##
+##                                                                            
##
+## You should have received a copy of the GNU General Public License          
##
+## along with this program;  if not, write to the Free Software               
##
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    
##
+##                                                                            
##
+################################################################################
+
+HAVE_LIBCAP := $(shell sh check_for_libcap.sh yesno)
+
+SCRIPTS = run_capbounds.sh
+TARGETS = checkforlibcap
+
+CFLAGS += -I../../../../include -Wall
+LDLIBS += -L../../../../lib -lltp -lcap
+
+ifeq ($(HAVE_LIBCAP),yes)
+SRCS    = $(wildcard *.c)
+TARGETS+= $(patsubst %.c,%,$(SRCS))
+endif
+
+all: $(TARGETS)
+
+ifeq ($(HAVE_LIBCAP),yes)
+checkforlibcap:
+       echo "#!/bin/sh" > $@
+       echo true >> $@
+       chmod a+rx $@
+else
+       @echo "libcap is not installed.  Please install libcap from"; \
+       echo 
"ftp://ftp.kernel.org/pub/linux/libs/security/linux-privs/libcap2.";; \
+       echo "You must use libcap-2.11 or newer."; \
+       echo "Then make clean in ltp or ltp/testcases/kernel/security/filecaps, 
and recompile ltp."
+checkforlibcap:
+       echo "#!/bin/sh" > $@
+       echo false >> $@
+       chmod a+rx $@
+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 checkforlibcap
diff --git a/testcases/kernel/security/cap_bound/cap_bounds_r.c 
b/testcases/kernel/security/cap_bound/cap_bounds_r.c
new file mode 100644
index 0000000..9742494
--- /dev/null
+++ b/testcases/kernel/security/cap_bound/cap_bounds_r.c
@@ -0,0 +1,86 @@
+/******************************************************************************/
+/*                                                                            
*/
+/* Copyright (c) International Business Machines  Corp., 2007, 2008           
*/
+/*                                                                            
*/
+/* 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.                                        
*/
+/*                                                                            
*/
+/* This program is distributed in the hope that it will be useful,            
*/
+/* but WITHOUT ANY WARRANTY;  without even the implied warranty of            
*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  
*/
+/* the GNU General Public License for more details.                           
*/
+/*                                                                            
*/
+/* You should have received a copy of the GNU General Public License          
*/
+/* along with this program;  if not, write to the Free Software               
*/
+/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    
*/
+/*                                                                            
*/
+/******************************************************************************/
+/*
+ * File: cap_bounds_r.c
+ * Author: Serge Hallyn
+ * Purpose: test reading of capability bounding set.
+ *     Test each valid cap value, as well as edge cases
+ */
+
+#include <errno.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#include <test.h>
+
+#ifndef CAP_LAST_CAP
+#warning out-of-date capability.h does not define CAP_LAST_CAP
+#define CAP_LAST_CAP 28  /* be ultra-conservative */
+#endif
+
+#ifndef CAP_BSET_READ
+#warning CAP_BSET_READ not defined
+#define CAP_BSET_READ 23
+#endif
+
+#ifndef CAP_BSET_DROP
+#warning CAP_BSET_DROP not defined
+#define CAP_BSET_DROP 24
+#endif
+
+char *TCID = "cap_bounds_r";
+int TST_TOTAL=1;
+
+int errno;
+
+int main(int argc, char *argv[])
+{
+       int ret = 1;
+       int i;
+
+       for (i=0; i<=CAP_LAST_CAP; i++) {
+               ret = prctl(CAP_BSET_READ, i);
+               if (ret != 1) {
+                       tst_resm(TFAIL, "prctl(CAP_BSET_READ, %d) returned 
%d\n", i, ret);
+                       if (ret == -1)
+                               tst_resm(TINFO, "errno was %d\n", errno);
+                       tst_exit(1);
+               }
+       }
+       ret = prctl(CAP_BSET_READ, -1);
+       if (ret != -1) {
+               tst_resm(TFAIL, "prctl(CAP_BSET_READ, -1) returned %d\n", -1, 
ret);
+               tst_exit(1);
+       }
+
+       /* Ideally I'd check CAP_LAST_CAP+1, but userspace
+        * tends to be far too unreliable to trust CAP_LAST_CAP>
+        * We could test using kernel API, but that's what we're
+        * testing...  So let's take an insanely high value */
+#define INSANE 63
+#define max(x,y) (x > y ? x : y)
+       ret = prctl(CAP_BSET_READ, max(INSANE,CAP_LAST_CAP+1));
+       if (ret != -1) {
+               tst_resm(TFAIL, "prctl(CAP_BSET_READ, %d) returned %d\n", 
CAP_LAST_CAP+1, ret);
+               tst_resm(TINFO, " %d is CAP_LAST_CAP+1 and should not exist\n", 
CAP_LAST_CAP+1);
+               tst_exit(1);
+       }
+       tst_resm(TPASS, "CAP_BSET_READ tests passed\n");
+       tst_exit(0);
+}
diff --git a/testcases/kernel/security/cap_bound/cap_bounds_rw.c 
b/testcases/kernel/security/cap_bound/cap_bounds_rw.c
new file mode 100644
index 0000000..fb4f065
--- /dev/null
+++ b/testcases/kernel/security/cap_bound/cap_bounds_rw.c
@@ -0,0 +1,124 @@
+/******************************************************************************/
+/*                                                                            
*/
+/* Copyright (c) International Business Machines  Corp., 2007, 2008           
*/
+/*                                                                            
*/
+/* 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.                                        
*/
+/*                                                                            
*/
+/* This program is distributed in the hope that it will be useful,            
*/
+/* but WITHOUT ANY WARRANTY;  without even the implied warranty of            
*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  
*/
+/* the GNU General Public License for more details.                           
*/
+/*                                                                            
*/
+/* You should have received a copy of the GNU General Public License          
*/
+/* along with this program;  if not, write to the Free Software               
*/
+/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    
*/
+/*                                                                            
*/
+/******************************************************************************/
+/*
+ * File: cap_bounds_rw
+ * Author: Serge Hallyn
+ * Purpose: test dropping capabilities from bounding set
+ */
+
+#include <errno.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#include <test.h>
+
+#ifndef CAP_LAST_CAP
+#warning out-of-date capability.h does not define CAP_LAST_CAP
+#define CAP_LAST_CAP 28  /* be ultra-conservative */
+#endif
+
+#ifndef CAP_BSET_READ
+#warning CAP_BSET_READ not defined
+#define CAP_BSET_READ 23
+#endif
+
+#ifndef CAP_BSET_DROP
+#warning CAP_BSET_DROP not defined
+#define CAP_BSET_DROP 24
+#endif
+
+char *TCID = "cap_bounds_rw";
+int TST_TOTAL=1;
+
+int errno;
+
+int check_remaining_caps(int lastdropped)
+{
+       int i;
+       int ret;
+
+       for (i=0; i <= lastdropped; i++) {
+               ret = prctl(CAP_BSET_READ, i);
+               if (ret == -1) {
+                       tst_resm(TBROK, "Failed to read bounding set during 
sanity check\n");
+                       tst_exit(1);
+               }
+               if (ret == 1) {
+                       tst_resm(TFAIL, "Bit %d should have been dropped but 
wasn't\n", i);
+                       return i;
+               }
+       }
+       for (; i<=CAP_LAST_CAP; i++) {
+               ret = prctl(CAP_BSET_READ, i);
+               if (ret == -1) {
+                       tst_resm(TBROK, "Failed to read bounding set during 
sanity check\n");
+                       tst_exit(1);
+               }
+               if (ret == 0) {
+                       tst_resm(TFAIL, "Bit %d wasn't yet dropped, but isn't 
in bounding set\n", i);
+                       return -i;
+               }
+       }
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+       int ret = 1;
+       int i;
+
+       ret = prctl(CAP_BSET_DROP, -1);
+       if (ret != -1) {
+               tst_resm(TFAIL, "prctl(CAP_BSET_DROP, -1) returned %d\n", ret);
+               tst_exit(1);
+       }
+       /* Ideally I'd check CAP_LAST_CAP+1, but userspace
+        * tends to be far too unreliable to trust CAP_LAST_CAP>
+        * We could test using kernel API, but that's what we're
+        * testing...  So let's take an insanely high value */
+#define INSANE 63
+#define max(x,y) (x > y ? x : y)
+       ret = prctl(CAP_BSET_DROP, max(INSANE,CAP_LAST_CAP+1));
+       if (ret != -1) {
+               tst_resm(TFAIL, "prctl(CAP_BSET_DROP, %d) returned %d\n", 
max(INSANE, CAP_LAST_CAP+1), ret);
+               tst_resm(TINFO, " %d is should not exist\n", max(INSANE, 
CAP_LAST_CAP+1));
+               tst_exit(1);
+       }
+       for (i=0; i<=CAP_LAST_CAP; i++) {
+               ret = prctl(CAP_BSET_DROP, i);
+               if (ret != 0) {
+                       tst_resm(TFAIL, "prctl(CAP_BSET_DROP, %d) returned 
%d\n", i, ret);
+                       if (ret == -1)
+                               tst_resm(TINFO, "errno was %d\n", errno);
+                       tst_exit(1);
+               }
+               ret = check_remaining_caps(i);
+               if (ret > 0) {
+                       tst_resm(TFAIL, "after dropping bits 0..%d, %d was 
still in bounding set\n",
+                               i, ret);
+                       tst_exit(1);
+               } else if (ret < 0) {
+                       tst_resm(TFAIL, "after dropping bits 0..%d, %d was not 
in bounding set\n",
+                               i, -ret);
+                       tst_exit(1);
+               }
+       }
+       tst_resm(TPASS, "CAP_BSET_DROP tests passed\n");
+       tst_exit(0);
+}
diff --git a/testcases/kernel/security/cap_bound/cap_bset_inh_bounds.c 
b/testcases/kernel/security/cap_bound/cap_bset_inh_bounds.c
new file mode 100644
index 0000000..ff9f374
--- /dev/null
+++ b/testcases/kernel/security/cap_bound/cap_bset_inh_bounds.c
@@ -0,0 +1,131 @@
+/******************************************************************************/
+/*                                                                            
*/
+/* Copyright (c) International Business Machines  Corp., 2007, 2008           
*/
+/*                                                                            
*/
+/* 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.                                        
*/
+/*                                                                            
*/
+/* This program is distributed in the hope that it will be useful,            
*/
+/* but WITHOUT ANY WARRANTY;  without even the implied warranty of            
*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  
*/
+/* the GNU General Public License for more details.                           
*/
+/*                                                                            
*/
+/* You should have received a copy of the GNU General Public License          
*/
+/* along with this program;  if not, write to the Free Software               
*/
+/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    
*/
+/*                                                                            
*/
+/******************************************************************************/
+/*
+ * File: cap_bset_inh_bounds.c
+ * Author: Serge Hallyn
+ * Purpose: test bounding set constraint on pI
+ *     (X = the capability bounding set)
+ *     1. if N \in pI, then dropping N from X does not drop it from pI
+ *     2. if N \notin X and N \notin pI, then adding N to pI fails
+ */
+
+#include <errno.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#include <test.h>
+
+#ifndef CAP_LAST_CAP
+#warning out-of-date capability.h does not define CAP_LAST_CAP
+#define CAP_LAST_CAP 28  /* be ultra-conservative */
+#endif
+
+#ifndef CAP_BSET_READ
+#warning CAP_BSET_READ not defined
+#define CAP_BSET_READ 23
+#endif
+
+#ifndef CAP_BSET_DROP
+#warning CAP_BSET_DROP not defined
+#define CAP_BSET_DROP 24
+#endif
+
+char *TCID = "cap_bounds_r";
+int TST_TOTAL=2;
+
+int errno;
+
+int main(int argc, char *argv[])
+{
+       int ret = 1;
+       cap_value_t v[1];
+       cap_flag_value_t f;
+       cap_t cur, tmpcap;
+
+       /* We pick a random capability... let's use CAP_SYS_ADMIN */
+       /* make sure we have the capability now */
+       ret = prctl(CAP_BSET_READ, CAP_SYS_ADMIN);
+       if (ret != 1) {
+               tst_resm(TBROK, "Not starting with CAP_SYS_ADMIN\n");
+               tst_exit(1);
+       }
+
+       /* Make sure it's in pI */
+       cur = cap_from_text("all=eip");
+       if (!cur) {
+               tst_resm(TBROK, "Failed to create cap_sys_admin+i cap_t (errno 
%d)\n", errno);
+               tst_exit(1);
+       }
+       ret = cap_set_proc(cur);
+       if (ret) {
+               tst_resm(TBROK, "Failed to cap_set_proc with cap_sys_admin+i 
(ret %d errno %d)\n",
+                       ret, errno);
+               tst_exit(1);
+       }
+       cap_free(cur);
+       cur = cap_get_proc();
+       ret = cap_get_flag(cur, CAP_SYS_ADMIN, CAP_INHERITABLE, &f);
+       if (ret || f != CAP_SET) {
+               tst_resm(TBROK, "Failed to add CAP_SYS_ADMIN to pI\n");
+               tst_exit(1);
+       }
+       cap_free(cur);
+
+       /* drop the capability from bounding set */
+       ret = prctl(CAP_BSET_DROP, CAP_SYS_ADMIN);
+       if (ret) {
+               tst_resm(TFAIL, "Failed to drop CAP_SYS_ADMIN from bounding 
set.\n");
+               tst_resm(TINFO, "(ret=%d, errno %d)\n", ret, errno);
+               tst_exit(1);
+       }
+
+       /* test 1: is CAP_SYS_ADMIN still in pI? */
+       cur = cap_get_proc();
+       ret = cap_get_flag(cur, CAP_SYS_ADMIN, CAP_INHERITABLE, &f);
+       if (ret || f != CAP_SET) {
+               tst_resm(TFAIL, "CAP_SYS_ADMIN not in pI after dropping from 
bounding set\n");
+               tst_exit(1);
+       }
+       tst_resm(TPASS, "CAP_SYS_ADMIN remains in pI after removing from 
bounding set\n");
+
+       tmpcap = cap_dup(cur);
+       v[0] = CAP_SYS_ADMIN;
+       ret = cap_set_flag(tmpcap, CAP_INHERITABLE, 1, v, CAP_CLEAR);
+       if (ret) {
+               tst_resm(TFAIL, "Failed to drop CAP_SYS_ADMIN from cap_t\n");
+               tst_exit(1);
+       }
+       ret = cap_set_proc(tmpcap);
+       if (ret) {
+               tst_resm(TFAIL, "Failed to drop CAP_SYS_ADMIN from pI\n");
+               tst_exit(1);
+       }
+       cap_free(tmpcap);
+
+       /* test 2: can we put it back in pI? */
+       ret = cap_set_proc(cur);
+       if (ret == 0) { /* success means pI was not bounded by X */
+               tst_resm(TFAIL, "Managed to put CAP_SYS_ADMIN back into pI 
though not in X\n");
+               tst_exit(1);
+       }
+       cap_free(cur);
+
+       tst_resm(TPASS, "Couldn't put CAP_SYS_ADMIN back into pI when not in 
bounding set\n");
+       tst_exit(0);
+}
diff --git a/testcases/kernel/security/cap_bound/check_for_libcap.sh 
b/testcases/kernel/security/cap_bound/check_for_libcap.sh
new file mode 100644
index 0000000..b8d7f15
--- /dev/null
+++ b/testcases/kernel/security/cap_bound/check_for_libcap.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+################################################################################
+##                                                                            
##
+## Copyright (c) International Business Machines  Corp., 2008                 
##
+##                                                                            
##
+## 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.                                        
##
+##                                                                            
##
+## This program is distributed in the hope that it will be useful, but        
##
+## WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
##
+## or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License   
##
+## for more details.                                                          
##
+##                                                                            
##
+## You should have received a copy of the GNU General Public License          
##
+## along with this program;  if not, write to the Free Software               
##
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    
##
+##                                                                            
##
+################################################################################
+
+if [ "x$CC" = "x" ]; then
+       export CC=gcc
+fi
+yesno=0
+if [ "$1" = "yesno" ]; then
+       yesno=1
+fi
+
+$CC -o dummy dummy.c -lcap 2>/dev/null
+
+ret=$?
+
+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 --git a/testcases/kernel/security/cap_bound/check_pe.c 
b/testcases/kernel/security/cap_bound/check_pe.c
new file mode 100644
index 0000000..56c5be3
--- /dev/null
+++ b/testcases/kernel/security/cap_bound/check_pe.c
@@ -0,0 +1,80 @@
+/******************************************************************************/
+/*                                                                            
*/
+/* Copyright (c) International Business Machines  Corp., 2007, 2008           
*/
+/*                                                                            
*/
+/* 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.                                        
*/
+/*                                                                            
*/
+/* This program is distributed in the hope that it will be useful,            
*/
+/* but WITHOUT ANY WARRANTY;  without even the implied warranty of            
*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  
*/
+/* the GNU General Public License for more details.                           
*/
+/*                                                                            
*/
+/* You should have received a copy of the GNU General Public License          
*/
+/* along with this program;  if not, write to the Free Software               
*/
+/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    
*/
+/*                                                                            
*/
+/******************************************************************************/
+/*
+ * File: check_pe.c
+ * Author: Serge Hallyn
+ * check whether CAP_SYS_ADMIN is in pE.
+ * return PASS if
+ *     *  argv[0] is 1 and CAP_SYS_ADMIN is in PE, or
+ *     * argv[0] is 0 and CAP_SYS_ADMIN is not in pE
+ * otherwise return FAIL
+ */
+
+#include <errno.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#include <test.h>
+
+char *TCID = "check_pe";
+int TST_TOTAL=1;
+
+int errno;
+
+int main(int argc, char *argv[])
+{
+       int ret = 1;
+       cap_flag_value_t f;
+       cap_t cur;
+       int n;
+
+       if (argc != 2) {
+               tst_resm(TBROK, "Usage: check_pe [0|1]\n");
+               tst_exit(1);
+       }
+       n = atoi(argv[1]);
+       if (n != 0 && n != 1) {
+               tst_resm(TBROK, "Usage: check_pe [0|1]\n");
+               tst_exit(1);
+       }
+
+       cur = cap_get_proc();
+       ret = cap_get_flag(cur, CAP_SYS_ADMIN, CAP_EFFECTIVE, &f);
+       if (ret) {
+               tst_resm(TBROK, "cap_get_flag failed (errno %d)\n", errno);
+               tst_exit(1);
+       }
+       
+       cap_free(cur);
+       if (n == 1) {
+               if (f == CAP_SET) {
+                       tst_resm(TPASS, "cap is in pE\n");
+                       tst_exit(0);
+               }
+               tst_resm(TFAIL, "Cap is not in pE\n");
+               tst_exit(1);
+       }
+       if (f == CAP_CLEAR) {
+               tst_resm(TPASS, "cap is not in pE\n");
+               tst_exit(0);
+       }
+       tst_resm(TFAIL, "Cap is in pE\n");
+       tst_exit(1);
+
+}
diff --git a/testcases/kernel/security/cap_bound/dummy.c 
b/testcases/kernel/security/cap_bound/dummy.c
new file mode 100644
index 0000000..cfb8a4d
--- /dev/null
+++ b/testcases/kernel/security/cap_bound/dummy.c
@@ -0,0 +1,9 @@
+#include <sys/capability.h>
+
+int main()
+{
+       cap_t cur;
+       cur = cap_from_text("all=eip");
+       cap_set_proc(cur);
+       cap_free(cur);
+}
diff --git a/testcases/kernel/security/cap_bound/exec_with_inh.c 
b/testcases/kernel/security/cap_bound/exec_with_inh.c
new file mode 100644
index 0000000..8b1f602
--- /dev/null
+++ b/testcases/kernel/security/cap_bound/exec_with_inh.c
@@ -0,0 +1,93 @@
+/******************************************************************************/
+/*                                                                            
*/
+/* Copyright (c) International Business Machines  Corp., 2007, 2008           
*/
+/*                                                                            
*/
+/* 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.                                        
*/
+/*                                                                            
*/
+/* This program is distributed in the hope that it will be useful,            
*/
+/* but WITHOUT ANY WARRANTY;  without even the implied warranty of            
*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  
*/
+/* the GNU General Public License for more details.                           
*/
+/*                                                                            
*/
+/* You should have received a copy of the GNU General Public License          
*/
+/* along with this program;  if not, write to the Free Software               
*/
+/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    
*/
+/*                                                                            
*/
+/******************************************************************************/
+/*
+ * File: exec_with_inh.c
+ * Author: Serge Hallyn
+ * Make sure that CAP_SYS_ADMIN is in pI
+ * drop CAP_SYS_ADMIN from bounding set
+ * Then exec "check_pe 1"
+ * check_pe will return PASS if it has CAP_SYS_ADMIN in pE.
+ */
+
+#include <errno.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#include <test.h>
+
+#ifndef CAP_LAST_CAP
+#warning out-of-date capability.h does not define CAP_LAST_CAP
+#define CAP_LAST_CAP 28  /* be ultra-conservative */
+#endif
+
+#ifndef CAP_BSET_READ
+#warning CAP_BSET_READ not defined
+#define CAP_BSET_READ 23
+#endif
+
+#ifndef CAP_BSET_DROP
+#warning CAP_BSET_DROP not defined
+#define CAP_BSET_DROP 24
+#endif
+
+char *TCID = "exec_with_inh";
+int TST_TOTAL=1;
+
+int errno;
+
+int main(int argc, char *argv[])
+{
+       int ret = 1;
+       cap_flag_value_t f;
+       cap_t cur;
+
+       /* Make sure CAP_SYS_ADMIN is in pI */
+       cur = cap_from_text("all=eip");
+       if (!cur) {
+               tst_resm(TBROK, "Failed to create cap_sys_admin+i cap_t (errno 
%d)\n", errno);
+               tst_exit(1);
+       }
+       ret = cap_set_proc(cur);
+       if (ret) {
+               tst_resm(TBROK, "Failed to cap_set_proc with cap_sys_admin+i 
(ret %d errno %d)\n",
+                       ret, errno);
+               tst_exit(1);
+       }
+       cap_free(cur);
+       cur = cap_get_proc();
+       ret = cap_get_flag(cur, CAP_SYS_ADMIN, CAP_INHERITABLE, &f);
+       if (ret || f != CAP_SET) {
+               tst_resm(TBROK, "Failed to add CAP_SYS_ADMIN to pI\n");
+               tst_exit(1);
+       }
+       cap_free(cur);
+
+       /* drop the capability from bounding set */
+       ret = prctl(CAP_BSET_DROP, CAP_SYS_ADMIN);
+       if (ret) {
+               tst_resm(TFAIL, "Failed to drop CAP_SYS_ADMIN from bounding 
set.\n");
+               tst_resm(TINFO, "(ret=%d, errno %d)\n", ret, errno);
+               tst_exit(1);
+       }
+
+       /* execute "check_pe 1" */
+       execl("check_pe", "check_pe", "1", NULL);
+       tst_resm(TBROK, "Failed to execute check_pe (errno %d)\n", errno);
+       tst_exit(1);
+}
diff --git a/testcases/kernel/security/cap_bound/exec_without_inh.c 
b/testcases/kernel/security/cap_bound/exec_without_inh.c
new file mode 100644
index 0000000..525d03b
--- /dev/null
+++ b/testcases/kernel/security/cap_bound/exec_without_inh.c
@@ -0,0 +1,88 @@
+/******************************************************************************/
+/*                                                                            
*/
+/* Copyright (c) International Business Machines  Corp., 2007, 2008           
*/
+/*                                                                            
*/
+/* 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.                                        
*/
+/*                                                                            
*/
+/* This program is distributed in the hope that it will be useful,            
*/
+/* but WITHOUT ANY WARRANTY;  without even the implied warranty of            
*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  
*/
+/* the GNU General Public License for more details.                           
*/
+/*                                                                            
*/
+/* You should have received a copy of the GNU General Public License          
*/
+/* along with this program;  if not, write to the Free Software               
*/
+/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    
*/
+/*                                                                            
*/
+/******************************************************************************/
+/*
+ * File: exec_without_inh.c
+ * Author: Serge Hallyn
+ * Make sure that CAP_SYS_ADMIN is not in pI
+ * drop CAP_SYS_ADMIN from bounding set
+ * Then exec "check_pe 0"
+ * check_pe will return PASS if it does not have CAP_SYS_ADMIN in pE.
+ */
+
+#include <errno.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#include <test.h>
+
+#ifndef CAP_LAST_CAP
+#warning out-of-date capability.h does not define CAP_LAST_CAP
+#define CAP_LAST_CAP 28  /* be ultra-conservative */
+#endif
+
+#ifndef CAP_BSET_READ
+#warning CAP_BSET_READ not defined
+#define CAP_BSET_READ 23
+#endif
+
+#ifndef CAP_BSET_DROP
+#warning CAP_BSET_DROP not defined
+#define CAP_BSET_DROP 24
+#endif
+
+char *TCID = "exec_without_inh";
+int TST_TOTAL=1;
+
+int errno;
+
+int main(int argc, char *argv[])
+{
+       int ret = 1;
+       cap_flag_value_t f;
+       cap_value_t v[1];
+       cap_t cur;
+
+       /* Make sure CAP_SYS_ADMIN is not in pI */
+       cur = cap_get_proc();
+       ret = cap_get_flag(cur, CAP_SYS_ADMIN, CAP_INHERITABLE, &f);
+       if (f == CAP_SET) {
+               v[0] = CAP_SYS_ADMIN;
+               ret = cap_set_flag(cur, CAP_INHERITABLE, 1, v, CAP_CLEAR);
+               if (!ret)
+                       ret = cap_set_proc(cur);
+               if (ret) {
+                       tst_resm(TBROK, "Failed to drop cap_sys_admin from 
pI\n");
+                       tst_exit(1);
+               }
+       }
+       cap_free(cur);
+
+       /* drop the capability from bounding set */
+       ret = prctl(CAP_BSET_DROP, CAP_SYS_ADMIN);
+       if (ret) {
+               tst_resm(TFAIL, "Failed to drop CAP_SYS_ADMIN from bounding 
set.\n");
+               tst_resm(TINFO, "(ret=%d, errno %d)\n", ret, errno);
+               tst_exit(1);
+       }
+
+       /* execute "check_pe 0" */
+       execl("check_pe", "check_pe", "0", NULL);
+       tst_resm(TBROK, "Failed to execute check_pe (errno %d)\n", errno);
+       tst_exit(1);
+}
diff --git a/testcases/kernel/security/cap_bound/run_capbounds.sh 
b/testcases/kernel/security/cap_bound/run_capbounds.sh
new file mode 100755
index 0000000..8dd760b
--- /dev/null
+++ b/testcases/kernel/security/cap_bound/run_capbounds.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+################################################################################
+##                                                                            
##
+## Copyright (c) International Business Machines  Corp., 2008                 
##
+##                                                                            
##
+## 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.                                        
##
+##                                                                            
##
+## This program is distributed in the hope that it will be useful, but        
##
+## WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
##
+## or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License   
##
+## for more details.                                                          
##
+##                                                                            
##
+## You should have received a copy of the GNU General Public License          
##
+## along with this program;  if not, write to the Free Software               
##
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    
##
+##                                                                            
##
+################################################################################
+
+if tst_kvercmp 2 6 25 ; then
+       tst_resm TCONF "System kernel version is less than 2.6.25"
+       tst_resm TCONF "Cannot execute test"
+       exit 0
+fi
+
+echo "testing bounding set reading"
+exit_code=0
+
+cap_bounds_r
+tmp=$?
+if [ $tmp -ne 0 ]; then
+       exit_code=$tmp
+fi
+
+echo "testing bounding set dropping"
+cap_bounds_rw
+tmp=$?
+if [ $tmp -ne 0 ]; then
+       exit_code=$tmp
+fi
+
+echo "checking bounding set constraint in pI"
+cap_bset_inh_bounds
+tmp=$?
+if [ $tmp -ne 0 ]; then
+       exit_code=$tmp
+fi
+
+exec_with_inh
+tmp=$?
+if [ $tmp -ne 0 ]; then
+       exit_code=$tmp;
+fi
+exec_without_inh
+tmp=$?
+if [ $tmp -ne 0 ]; then
+       exit_code=$tmp;
+fi
+
+exit $exit_code
-- 
1.6.1.1


------------------------------------------------------------------------------
Stay on top of everything new and different, both inside and 
around Java (TM) technology - register by April 22, and save
$200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco.
300 plus technical and hands-on sessions. Register today. 
Use priority code J9JMT32. http://p.sf.net/sfu/p
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to