@@ -114,6 +114,10 @@ TARGETS += test_lockdown.te
export M4PARAM += -Dlockdown_defined
endif
+ifeq ($(shell grep -q sandbox $(POLDEV)/include/support/all_perms.spt && echo true),true)
+TARGETS += test_sandbox.te
+endif
+
ifeq ($(shell grep -q filesystem $(POLDEV)/include/support/all_perms.spt && echo true),true)
TARGETS += test_filesystem.te
ifeq ($(shell [ $(MOD_POL_VERS) -ge 11 -a $(POL_VERS) -ge 25 ] && echo true),true)
new file mode 100644
@@ -0,0 +1,48 @@
+attribute test_sandbox_domain;
+
+type test_sandbox_file_t;
+files_type(test_sandbox_file_t)
+
+type test_sandbox_dir_t;
+files_type(test_sandbox_dir_t);
+
+type test_sandbox_nodir_t;
+domain_type(test_sandbox_nodir_t)
+unconfined_runs_test(test_sandbox_nodir_t)
+typeattribute test_sandbox_nodir_t test_sandbox_domain;
+typeattribute test_sandbox_nodir_t testdomain;
+allow test_sandbox_nodir_t test_sandbox_dir_t:file { getattr };
+
+type test_sandbox_rxdir_t;
+domain_type(test_sandbox_rxdir_t)
+unconfined_runs_test(test_sandbox_rxdir_t)
+typeattribute test_sandbox_rxdir_t test_sandbox_domain;
+typeattribute test_sandbox_rxdir_t testdomain;
+allow test_sandbox_rxdir_t test_sandbox_dir_t:dir { getattr read open };
+allow test_sandbox_rxdir_t test_sandbox_dir_t:dir search_dir_perms;
+allow test_sandbox_rxdir_t test_sandbox_dir_t:file { getattr };
+
+require {
+ type ls_exec_t;
+}
+domain_entry_file(test_sandbox_domain, ls_exec_t)
+domain_transition_pattern(sysadm_t, ls_exec_t, test_sandbox_domain)
+
+type test_sandbox_noop;
+domain_type(test_sandbox_noop)
+unconfined_runs_test(test_sandbox_noop)
+typeattribute test_sandbox_noop test_sandbox_domain;
+typeattribute test_sandbox_noop testdomain;
+allow test_sandbox_noop test_sandbox_file_t:file { getattr read open };
+allow test_sandbox_noop test_sandbox_nodir_t:sandbox { load_policy unload_policy };
+allow test_sandbox_noop test_sandbox_rxdir_t:sandbox { load_policy unload_policy };
+
+type test_sandbox_op;
+domain_type(test_sandbox_op)
+unconfined_runs_test(test_sandbox_op)
+typeattribute test_sandbox_op test_sandbox_domain;
+typeattribute test_sandbox_op testdomain;
+allow test_sandbox_op test_sandbox_file_t:file { getattr read open };
+allow test_sandbox_op test_sandbox_op:security { sandbox };
+allow test_sandbox_op test_sandbox_nodir_t:sandbox { load_policy unload_policy };
+allow test_sandbox_op test_sandbox_rxdir_t:sandbox { load_policy unload_policy };
@@ -6,7 +6,7 @@ export CFLAGS+=-g -O0 -Wall -D_GNU_SOURCE
DISTRO=$(shell ./os_detect)
-SUBDIRS:= domain_trans entrypoint execshare exectrace execute_no_trans \
+SUBDIRS:=sandbox domain_trans entrypoint execshare exectrace execute_no_trans \
fdreceive inherit link mkdir msg open ptrace readlink relabel rename \
rxdir sem setattr setnice shm sigkill stat sysctl task_create \
task_setnice task_setscheduler task_getscheduler task_getsid \
new file mode 100644
@@ -0,0 +1,2 @@
+all:
+clean:
new file mode 100644
@@ -0,0 +1,29 @@
+; This information is NOT compiled into a sandbox policy, it is here just to
+; make the cil compiler happy. For now, we leave it here with dummy information.
+(sid SID)
+(sidorder (SID))
+(user USER)
+(role ROLE)
+(category CAT)
+(categoryorder (CAT))
+(sensitivity SENS)
+(sensitivityorder (SENS))
+(sensitivitycategory SENS (CAT))
+(roletype ROLE test_sandbox_dir_t)
+(userrole USER ROLE)
+(userlevel USER (SENS))
+(userrange USER ((SENS)(SENS (CAT))))
+(sidcontext SID (USER ROLE test_sandbox_dir_t ((SENS)(SENS))))
+
+; type: test_sandbox_nodir_t
+; perms: no
+; mode: deny
+
+(class dir (read getattr open search rmdir))
+(class file (getattr))
+(classorder (dir file))
+(type test_sandbox_nodir_t)
+(type test_sandbox_dir_t)
+(deny test_sandbox_nodir_t test_sandbox_dir_t (dir (read getattr open)))
+(deny test_sandbox_nodir_t test_sandbox_dir_t (dir (getattr search open)))
+(deny test_sandbox_nodir_t test_sandbox_dir_t (file (getattr)))
new file mode 100644
@@ -0,0 +1,27 @@
+; This information is NOT compiled into a sandbox policy, it is here just to
+; make the cil compiler happy. For now, we leave it here with dummy information.
+(sid SID)
+(sidorder (SID))
+(user USER)
+(role ROLE)
+(category CAT)
+(categoryorder (CAT))
+(sensitivity SENS)
+(sensitivityorder (SENS))
+(sensitivitycategory SENS (CAT))
+(roletype ROLE test_sandbox_dir_t)
+(userrole USER ROLE)
+(userlevel USER (SENS))
+(userrange USER ((SENS)(SENS (CAT))))
+(sidcontext SID (USER ROLE test_sandbox_dir_t ((SENS)(SENS))))
+
+; type: test_sandbox_nodir_t
+; perms: rx
+; mode: deny
+
+(class dir (read getattr open search rmdir))
+(class file (getattr))
+(classorder (dir file))
+(type test_sandbox_nodir_t)
+(type test_sandbox_dir_t)
+(deny test_sandbox_nodir_t test_sandbox_dir_t (dir (rmdir)))
new file mode 100644
@@ -0,0 +1,29 @@
+; This information is NOT compiled into a sandbox policy, it is here just to
+; make the cil compiler happy. For now, we leave it here with dummy information.
+(sid SID)
+(sidorder (SID))
+(user USER)
+(role ROLE)
+(category CAT)
+(categoryorder (CAT))
+(sensitivity SENS)
+(sensitivityorder (SENS))
+(sensitivitycategory SENS (CAT))
+(roletype ROLE test_sandbox_dir_t)
+(userrole USER ROLE)
+(userlevel USER (SENS))
+(userrange USER ((SENS)(SENS (CAT))))
+(sidcontext SID (USER ROLE test_sandbox_dir_t ((SENS)(SENS))))
+
+; type: test_sandbox_rxdir_t
+; perms: no
+; mode: deny
+
+(class dir (read getattr open search rmdir))
+(class file (getattr))
+(classorder (dir file))
+(type test_sandbox_rxdir_t)
+(type test_sandbox_dir_t)
+(deny test_sandbox_rxdir_t test_sandbox_dir_t (dir (read getattr open)))
+(deny test_sandbox_rxdir_t test_sandbox_dir_t (dir (getattr search open)))
+(deny test_sandbox_rxdir_t test_sandbox_dir_t (file (getattr)))
new file mode 100644
@@ -0,0 +1,27 @@
+; This information is NOT compiled into a sandbox policy, it is here just to
+; make the cil compiler happy. For now, we leave it here with dummy information.
+(sid SID)
+(sidorder (SID))
+(user USER)
+(role ROLE)
+(category CAT)
+(categoryorder (CAT))
+(sensitivity SENS)
+(sensitivityorder (SENS))
+(sensitivitycategory SENS (CAT))
+(roletype ROLE test_sandbox_dir_t)
+(userrole USER ROLE)
+(userlevel USER (SENS))
+(userrange USER ((SENS)(SENS (CAT))))
+(sidcontext SID (USER ROLE test_sandbox_dir_t ((SENS)(SENS))))
+
+; type: test_sandbox_rxdir_t
+; perms: rx
+; mode: deny
+
+(class dir (read getattr open search rmdir))
+(class file (getattr))
+(classorder (dir file))
+(type test_sandbox_rxdir_t)
+(type test_sandbox_dir_t)
+(deny test_sandbox_rxdir_t test_sandbox_dir_t (dir (rmdir)))
new file mode 100755
@@ -0,0 +1,215 @@
+#!/usr/bin/perl
+
+use Test;
+BEGIN { plan tests => 68 }
+
+$basedir = $0;
+$basedir =~ s|(.*)/[^/]*|$1|;
+
+# The test_sandbox.te policy sets the base policy permissions for these tests.
+# We use sandbox policies to further restrict the base policy. Some sandbox
+# policies attempt to grant themselves extra permissions so that we can test
+# that those permissions are NOT actually granted. All sandbox tests check for
+# permissions to read and search directories.
+#
+# The following tests are performed
+#
+# | base | sandbox | expected result | expected result
+# type | policy | policy | without sandbox | WITH sandbox
+# ----------------------|------------------------------------------------------
+# test_sandbox_nodir_t | deny | deny | deny | deny
+# test_sandbox_nodir_t | deny | allow | deny | deny
+# test_sandbox_rxdir_t | allow | deny | allow | deny
+# test_sandbox_rxdir_t | allow | allow | allow | allow
+#
+# To test both loading and unloading of policies, each test occurs in the
+# following sequence:
+# 1. test read/search operations (without sandbox)
+# 2. load sandbox
+# 3. test read/search operations (WITH sandbox)
+# 4. unload sandbox
+# 5. test read/search operations (without sandbox)
+#
+# Finally, each test is performed twice. Once with sandboxes written in ALLOW
+# mode and a second time with sandboxes written in DENY mode. The same results
+# are expected in each mode.
+#
+# The sandbox policy files are named using the following scheme:
+# <type>_<perms>_<mode>.cil
+# Where:
+# <type> is either 'nodir' or 'rxdir' -- indicates type sandbox is applied to
+# <perms> is either 'no' or 'rx' -- indicates permissions granted by sandbox
+# <mode> is either 'allow' or 'deny' -- indicates mode sandbox is written in
+#
+
+# setup test directory and file
+system("rm -rf $basedir/test_dir");
+system("mkdir $basedir/test_dir");
+system("chcon -t test_sandbox_dir_t $basedir/test_dir");
+system("touch $basedir/test_dir/test_file");
+
+# compile sandboxes
+$allow_mode=0;
+$deny_mode=1;
+&compile( "test_sandbox_nodir_t", "nodir_no_allow.cil", $allow_mode);
+&compile( "test_sandbox_nodir_t", "nodir_rx_allow.cil", $allow_mode);
+&compile( "test_sandbox_rxdir_t", "rxdir_no_allow.cil", $allow_mode);
+&compile( "test_sandbox_rxdir_t", "rxdir_rx_allow.cil", $allow_mode);
+&compile( "test_sandbox_nodir_t", "nodir_no_deny.cil", $deny_mode);
+&compile( "test_sandbox_nodir_t", "nodir_rx_deny.cil", $deny_mode);
+&compile( "test_sandbox_rxdir_t", "rxdir_no_deny.cil", $deny_mode);
+&compile( "test_sandbox_rxdir_t", "rxdir_rx_deny.cil", $deny_mode);
+
+# For the compiled sandbox files to be readable by test_sandbox_op and
+# test_sandbox_noop, we must change the files security contexts.
+system("chcon -t test_sandbox_file_t $basedir/*.sandbox");
+
+# confirm op/noop types can read .sandbox files
+$result = system("runcon -t test_sandbox_op -- cat $basedir/rxdir_rx_allow.sandbox > /dev/null");
+ok( $result, 0 );
+$result = system("runcon -t test_sandbox_noop -- cat $basedir/rxdir_rx_allow.sandbox > /dev/null");
+ok( $result, 0 );
+
+# First, we want to make sure that types without the sandbox operate permission
+# (specifically the test_sandbox_noop type) are denied from loading and
+# unloading a sandbox policy.
+
+$sandbox="$basedir/rxdir_rx_allow.sandbox";
+$result = system("runcon -t test_sandbox_noop -- sebox --load $sandbox > /dev/null 2>&1");
+ok( $result );
+$result = system("runcon -t test_sandbox_noop -- sebox --unload $sandbox > /dev/null 2>&1");
+ok( $result );
+
+# ================================================================= #
+# deny, deny (ALLOW MODE) #
+# ================================================================= #
+&test_rx( "test_sandbox_nodir_t", -1 );
+&load_sandbox( "test_sandbox_op", "nodir_no_allow.sandbox" );
+&test_rx( "test_sandbox_nodir_t", -1 );
+&unload_sandbox( "test_sandbox_op", "nodir_no_allow.sandbox" );
+&test_rx( "test_sandbox_nodir_t", -1 );
+
+# ================================================================= #
+# deny, allow (ALLOW MODE) #
+# ================================================================= #
+&test_rx( "test_sandbox_nodir_t", -1 );
+&load_sandbox( "test_sandbox_op", "nodir_rx_allow.sandbox" );
+&test_rx( "test_sandbox_nodir_t", -1 );
+&unload_sandbox( "test_sandbox_op", "nodir_rx_allow.sandbox" );
+&test_rx( "test_sandbox_nodir_t", -1 );
+
+# ================================================================= #
+# allow, deny (ALLOW MODE) #
+# ================================================================= #
+&test_rx( "test_sandbox_rxdir_t", 0 );
+&load_sandbox( "test_sandbox_op", "rxdir_no_allow.sandbox" );
+&test_rx( "test_sandbox_rxdir_t", -1 );
+&unload_sandbox( "test_sandbox_op", "rxdir_no_allow.sandbox" );
+&test_rx( "test_sandbox_rxdir_t", 0 );
+
+# ================================================================= #
+# allow, allow (ALLOW MODE) #
+# ================================================================= #
+&test_rx( "test_sandbox_rxdir_t", 0 );
+&load_sandbox( "test_sandbox_op", "rxdir_rx_allow.sandbox" );
+&test_rx( "test_sandbox_rxdir_t", 0 );
+&unload_sandbox( "test_sandbox_op", "rxdir_rx_allow.sandbox" );
+&test_rx( "test_sandbox_rxdir_t", 0 );
+
+# ================================================================= #
+# deny, deny (DENY MODE) #
+# ================================================================= #
+&test_rx( "test_sandbox_nodir_t", -1 );
+&load_sandbox( "test_sandbox_op", "nodir_no_deny.sandbox" );
+&test_rx( "test_sandbox_nodir_t", -1 );
+&unload_sandbox( "test_sandbox_op", "nodir_no_deny.sandbox" );
+&test_rx( "test_sandbox_nodir_t", -1 );
+
+# ================================================================= #
+# deny, allow (DENY MODE) #
+# ================================================================= #
+&test_rx( "test_sandbox_nodir_t", -1 );
+&load_sandbox( "test_sandbox_op", "nodir_rx_deny.sandbox" );
+&test_rx( "test_sandbox_nodir_t", -1 );
+&unload_sandbox( "test_sandbox_op", "nodir_rx_deny.sandbox" );
+&test_rx( "test_sandbox_nodir_t", -1 );
+
+# ================================================================= #
+# allow, deny (DENY MODE) #
+# ================================================================= #
+&test_rx( "test_sandbox_rxdir_t", 0 );
+&load_sandbox( "test_sandbox_op", "rxdir_no_deny.sandbox" );
+&test_rx( "test_sandbox_rxdir_t", -1 );
+&unload_sandbox( "test_sandbox_op", "rxdir_no_deny.sandbox" );
+&test_rx( "test_sandbox_rxdir_t", 0 );
+
+# ================================================================= #
+# allow, allow (DENY MODE) #
+# ================================================================= #
+&test_rx( "test_sandbox_rxdir_t", 0 );
+&load_sandbox( "test_sandbox_op", "rxdir_rx_deny.sandbox" );
+&test_rx( "test_sandbox_rxdir_t", 0 );
+&unload_sandbox( "test_sandbox_op", "rxdir_rx_deny.sandbox" );
+&test_rx( "test_sandbox_rxdir_t", 0 );
+
+# clean up
+system("rm -rf $basedir/test_dir");
+system("rm $basedir/*.sandbox");
+
+sub compile {
+ $type = shift;
+ $filename = shift;
+ $mode = shift;
+
+ $input="$basedir/$filename";
+ $output="$basedir/$filename";
+ $output=~s/\.cil/\.sandbox/ig;
+
+ # generate context
+ $context=`runcon -t $type -- id -Z`;
+ chomp($context);
+
+ # compile
+ if ($mode == 0) {
+ system("secilc --sandbox=\"$context\" --sandbox-allow -o $output $input");
+ } else {
+ system("secilc --sandbox=\"$context\" --sandbox-deny -o $output $input");
+ }
+}
+
+sub test_rx {
+ $type = shift;
+ $expected = shift;
+
+ $result = system("runcon -t $type -- ls $basedir/test_dir 2>&1");
+ if ($expected == 0) {
+ ok( $result, 0 );
+ } else {
+ ok( $result );
+ }
+
+ $result = system("runcon -t $type -- ls $basedir/test_dir/test_file 2>&1");
+ if ($expected == 0) {
+ ok( $result, 0 );
+ } else {
+ ok( $result );
+ }
+}
+
+sub load_sandbox {
+ $type = shift;
+ $filename = shift;
+
+ $sandbox="$basedir/$filename";
+ $result = system("runcon -t $type -- sebox --load $sandbox > /dev/null 2>&1");
+ ok( $result, 0 );
+}
+
+sub unload_sandbox {
+ $type = shift;
+ $filename = shift;
+
+ $sandbox="$basedir/$filename";
+ $result = system("runcon -t $type -- sebox --unload $sandbox > /dev/null 2>&1");
+ ok( $result, 0 );
+}