On Mon, 2009-04-20 at 17:42 -0500, Serge E. Hallyn wrote:
> Hi,
> 
> I had intended to write the keepcaps and securebits testcases,
> but given that prctl(CAPBSET_READ) was broken for quite awhile in
> mainline, I figured I'd start there.  I inted to write the remaining
> testcases "soon".

Thanks. Plan is great.

> 
> These are CERTAINLY NOT ready to be applied.  I first need to

Sure. I would mark this and wait for your confirmation.

Regards--
Subrata

> write the back-compat tests for kernel and userspace support
> (sigh), and get these tests to actually install.  I just tested
> by typing 'make' and running the tests by hand.  The testcases
> themselves, however, appear to be ok.
> 
> thanks,
> -serge
> 
> >From a732d245dba975cfa0441db50810e2bc65862819 Mon Sep 17 00:00:00 2001
> From: Serge Hallyn <[email protected]>
> Date: Mon, 20 Apr 2009 17:35:21 -0500
> Subject: [PATCH 1/1] add capability bounding set testcases
> 
> 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]>
> ---
>  testcases/kernel/security/Makefile                 |    2 +-
>  testcases/kernel/security/cap_bound/Makefile       |   36 ++++++
>  testcases/kernel/security/cap_bound/cap_bounds_r.c |   79 ++++++++++++
>  .../kernel/security/cap_bound/cap_bounds_rw.c      |  118 ++++++++++++++++++
>  .../security/cap_bound/cap_bset_inh_bounds.c       |  131 
> ++++++++++++++++++++
>  testcases/kernel/security/cap_bound/check_pe.c     |   80 ++++++++++++
>  .../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     |   59 +++++++++
>  9 files changed, 685 insertions(+), 1 deletions(-)
>  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_pe.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/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..f9f0768
> --- /dev/null
> +++ b/testcases/kernel/security/cap_bound/Makefile
> @@ -0,0 +1,36 @@
> +################################################################################
> +##                                                                           
>  ##
> +## 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   
>  ##
> +##                                                                           
>  ##
> +################################################################################
> +
> +SCRIPTS = run_capbounds.sh
> +
> +CFLAGS += -I../../../../include -Wall
> +LDLIBS += -L../../../../lib -lltp -lcap
> +
> +SRCS    = $(wildcard *.c)
> +TARGETS+= $(patsubst %.c,%,$(SRCS))
> +
> +all: $(TARGETS)
> +
> +INSTALLTARGETS = $(TARGETS) $(SCRIPTS)
> +install: $(INSTALLTARGETS)
> +     @set -e; for i in $(INSTALLTARGETS); do ln -f $$i ../../../bin/$$i ; 
> chmod +x ../../../bin/$$i; done
> +
> +clean:
> +     rm -f $(TARGETS) *.o
> 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..56f3deb
> --- /dev/null
> +++ b/testcases/kernel/security/cap_bound/cap_bounds_r.c
> @@ -0,0 +1,79 @@
> +/******************************************************************************/
> +/*                                                                           
>  */
> +/* 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);
> +     }
> +     ret = prctl(CAP_BSET_READ, 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..2bbbb8d
> --- /dev/null
> +++ b/testcases/kernel/security/cap_bound/cap_bounds_rw.c
> @@ -0,0 +1,118 @@
> +/******************************************************************************/
> +/*                                                                           
>  */
> +/* 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);
> +     }
> +     ret = prctl(CAP_BSET_DROP, CAP_LAST_CAP+1);
> +     if (ret != -1) {
> +             tst_resm(TFAIL, "prctl(CAP_BSET_DROP, %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);
> +     }
> +     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_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/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..2980b61
> --- /dev/null
> +++ b/testcases/kernel/security/cap_bound/run_capbounds.sh
> @@ -0,0 +1,59 @@
> +#!/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   
>  ##
> +##                                                                           
>  ##
> +################################################################################
> +
> +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
> +
> +chmod u+s check_pe
> +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
> +
> +chmod 600 check_pe
> +
> +exit $exit_code


------------------------------------------------------------------------------
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