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
