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".
These are CERTAINLY NOT ready to be applied. I first need to 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 -- 1.5.6.3 ------------------------------------------------------------------------------ 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
