@@ -16,7 +16,7 @@ TARGETS = \
test_entrypoint.te test_execshare.te test_exectrace.te \
test_execute_no_trans.te test_fdreceive.te test_file.te \
test_inherit.te test_ioctl.te test_ipc.te test_link.te test_mkdir.te \
- test_nnp.te test_open.te test_ptrace.te test_readlink.te \
+ test_nnp_nosuid.te test_open.te test_ptrace.te test_readlink.te \
test_relabel.te test_rename.te test_rxdir.te test_setattr.te \
test_setnice.te test_sigkill.te test_stat.te test_sysctl.te \
test_task_create.te test_task_getpgid.te test_task_getsched.te \
@@ -57,6 +57,10 @@ ifeq ($(shell grep -q all_file_perms.*map $(POLDEV)/include/support/all_perms.sp
export M4PARAM = -Dmap_permission_defined
endif
+ifeq ($(shell grep -q nnp_transition $(POLDEV)/include/support/all_perms.spt && echo true),true)
+export M4PARAM += -Dnnp_nosuid_transition_permission_defined
+endif
+
ifeq (x$(DISTRO),$(filter x$(DISTRO),xRHEL4 xRHEL5 xRHEL6))
TARGETS:=$(filter-out test_overlayfs.te test_mqueue.te, $(TARGETS))
endif
deleted file mode 100644
@@ -1,34 +0,0 @@
-#################################
-#
-# Policy for testing NO_NEW_PRIVS transitions.
-#
-
-# A domain bounded by the unconfined domain.
-type test_nnp_bounded_t;
-domain_type(test_nnp_bounded_t)
-typeattribute test_nnp_bounded_t testdomain;
-typebounds unconfined_t test_nnp_bounded_t;
-
-# The entrypoint type for this domain.
-type test_nnp_bounded_exec_t;
-files_type(test_nnp_bounded_exec_t)
-domain_entry_file(test_nnp_bounded_t, test_nnp_bounded_exec_t)
-domain_entry_file(unconfined_t, test_nnp_bounded_exec_t)
-
-# Run it! This should succeed on v3.18 or later, fail on older kernels.
-unconfined_runs_test(test_nnp_bounded_t)
-unconfined_run_to(test_nnp_bounded_t, test_nnp_bounded_exec_t)
-
-# A domain that is not bounded by the unconfined domain.
-type test_nnp_notbounded_t;
-domain_type(test_nnp_notbounded_t)
-typeattribute test_nnp_notbounded_t testdomain;
-
-# The entrypoint type for this domain.
-type test_nnp_notbounded_exec_t;
-files_type(test_nnp_notbounded_exec_t)
-domain_entry_file(test_nnp_notbounded_t, test_nnp_notbounded_exec_t)
-
-# Run it! This should fail always.
-unconfined_runs_test(test_nnp_notbounded_t)
-unconfined_run_to(test_nnp_notbounded_t, test_nnp_notbounded_exec_t)
new file mode 100644
@@ -0,0 +1,85 @@
+#################################
+#
+# Policy for testing NO_NEW_PRIVS and nosuid transitions.
+#
+
+# A domain bounded by the unconfined domain.
+type test_bounded_t;
+domain_type(test_bounded_t)
+typeattribute test_bounded_t testdomain;
+typebounds unconfined_t test_bounded_t;
+
+# The entrypoint type for this domain.
+type test_bounded_exec_t;
+files_type(test_bounded_exec_t)
+domain_entry_file(test_bounded_t, test_bounded_exec_t)
+domain_entry_file(unconfined_t, test_bounded_exec_t)
+
+# Run it! This should succeed on v3.18 or later, fail on older kernels.
+unconfined_runs_test(test_bounded_t)
+unconfined_run_to(test_bounded_t, test_bounded_exec_t)
+
+# A domain that is not bounded by the unconfined domain.
+type test_notbounded_t;
+domain_type(test_notbounded_t)
+typeattribute test_notbounded_t testdomain;
+
+# The entrypoint type for this domain.
+type test_notbounded_exec_t;
+files_type(test_notbounded_exec_t)
+domain_entry_file(test_notbounded_t, test_notbounded_exec_t)
+
+# Run it! This should fail always.
+unconfined_runs_test(test_notbounded_t)
+unconfined_run_to(test_notbounded_t, test_notbounded_exec_t)
+
+# A domain to which the unconfined domain is allowed nnp_transition.
+type test_nnptransition_t;
+domain_type(test_nnptransition_t)
+typeattribute test_nnptransition_t testdomain;
+
+# The entrypoint type for this domain.
+type test_nnptransition_exec_t;
+files_type(test_nnptransition_exec_t)
+domain_entry_file(test_nnptransition_t, test_nnptransition_exec_t)
+
+# Run it! This should succeed on v4.14 or later.
+unconfined_runs_test(test_nnptransition_t)
+unconfined_run_to(test_nnptransition_t, test_nnptransition_exec_t)
+ifdef(`nnp_nosuid_transition_permission_defined', `
+allow unconfined_t test_nnptransition_t:process2 nnp_transition;
+')
+
+# A domain to which the unconfined domain is allowed nosuid_transition.
+type test_nosuidtransition_t;
+domain_type(test_nosuidtransition_t)
+typeattribute test_nosuidtransition_t testdomain;
+
+# The entrypoint type for this domain.
+type test_nosuidtransition_exec_t;
+files_type(test_nosuidtransition_exec_t)
+domain_entry_file(test_nosuidtransition_t, test_nosuidtransition_exec_t)
+
+# Run it! This should succeed on v4.14 or later.
+unconfined_runs_test(test_nosuidtransition_t)
+unconfined_run_to(test_nosuidtransition_t, test_nosuidtransition_exec_t)
+ifdef(`nnp_nosuid_transition_permission_defined', `
+allow unconfined_t test_nosuidtransition_t:process2 nosuid_transition;
+')
+
+# A domain to which the unconfined domain is allowed both nosuid_transition and nnp_transition.
+type test_nnpnosuidtransition_t;
+domain_type(test_nnpnosuidtransition_t)
+typeattribute test_nnpnosuidtransition_t testdomain;
+
+# The entrypoint type for this domain.
+type test_nnpnosuidtransition_exec_t;
+files_type(test_nosuidtransition_exec_t)
+domain_entry_file(test_nnpnosuidtransition_t, test_nnpnosuidtransition_exec_t)
+
+# Run it! This should succeed on v4.14 or later.
+unconfined_runs_test(test_nnpnosuidtransition_t)
+unconfined_run_to(test_nosuidtransition_t, test_nnpnosuidtransition_exec_t)
+ifdef(`nnp_nosuid_transition_permission_defined', `
+allow unconfined_t test_nnpnosuidtransition_t:process2 { nnp_transition nosuid_transition };
+')
@@ -9,8 +9,8 @@ SUBDIRS:= domain_trans entrypoint execshare exectrace execute_no_trans \
rxdir sem setattr setnice shm sigkill stat sysctl task_create \
task_setnice task_setscheduler task_getscheduler task_getsid \
task_getpgid task_setpgid file ioctl capable_file capable_net \
- capable_sys dyntrans dyntrace bounds nnp mmap unix_socket inet_socket \
- overlay checkreqprot mqueue mac_admin infiniband_pkey \
+ capable_sys dyntrans dyntrace bounds nnp_nosuid mmap unix_socket \
+ inet_socket overlay checkreqprot mqueue mac_admin infiniband_pkey \
infiniband_endport atsecure
ifeq ($(shell grep -q cap_userns $(POLDEV)/include/support/all_perms.spt && echo true),true)
@@ -32,15 +32,15 @@ SUBDIRS += prlimit
endif
ifeq ($(DISTRO),RHEL4)
- SUBDIRS:=$(filter-out bounds dyntrace dyntrans inet_socket mmap nnp overlay unix_socket, $(SUBDIRS))
+ SUBDIRS:=$(filter-out bounds dyntrace dyntrans inet_socket mmap nnp_nosuid overlay unix_socket, $(SUBDIRS))
endif
ifeq ($(DISTRO),RHEL5)
- SUBDIRS:=$(filter-out bounds inet_socket mmap nnp overlay unix_socket, $(SUBDIRS))
+ SUBDIRS:=$(filter-out bounds inet_socket mmap nnp_nosuid overlay unix_socket, $(SUBDIRS))
endif
ifeq ($(DISTRO),RHEL6)
- SUBDIRS:=$(filter-out nnp overlay, $(SUBDIRS))
+ SUBDIRS:=$(filter-out nnp_nosuid overlay, $(SUBDIRS))
endif
ifeq ($(DISTRO),RHEL7)
deleted file mode 100755
@@ -1,44 +0,0 @@
-#!/usr/bin/perl
-
-use Test;
-BEGIN { plan tests => 4 }
-
-$basedir = $0;
-$basedir =~ s|(.*)/[^/]*|$1|;
-
-# Remove any leftover programs from prior failed runs.
-system("rm -f $basedir/true");
-
-# Set entrypoint type for bounded domain.
-system("chcon -t test_nnp_bounded_exec_t $basedir/checkcon");
-
-# Transition to bounded type via setexec.
-$result = system(
-"$basedir/execnnp runcon -t test_nnp_bounded_t $basedir/checkcon test_nnp_bounded_t 2>&1"
-);
-ok( $result, 0 ); #this should pass
-
-# Automatic transition to bounded domain via exec.
-$result = system("$basedir/execnnp $basedir/checkcon test_nnp_bounded_t 2>&1");
-ok( $result, 0 ); #this should pass
-
-# Use true as an entrypoint program to test ability to exec at all.
-system("cp /bin/true $basedir/true");
-
-# Set entrypoint type for notbounded domain.
-system("chcon -t test_nnp_notbounded_exec_t $basedir/checkcon $basedir/true");
-
-# Transition to notbounded domain via setexec.
-$result =
- system("$basedir/execnnp runcon -t test_nnp_notbounded_t $basedir/true 2>&1");
-ok($result); #this should fail
-
-# Automatic transition to notbounded domain via exec.
-$result =
- system("$basedir/execnnp $basedir/checkcon test_nnp_notbounded_t 2>&1");
-ok($result); #this should fail
-
-# Cleanup.
-system("rm -f $basedir/true");
-
-exit;
similarity index 100%
rename from tests/nnp/Makefile
rename to tests/nnp_nosuid/Makefile
similarity index 100%
rename from tests/nnp/checkcon.c
rename to tests/nnp_nosuid/checkcon.c
similarity index 62%
rename from tests/nnp/execnnp.c
rename to tests/nnp_nosuid/execnnp.c
@@ -2,24 +2,42 @@
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
+#include <getopt.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <sys/wait.h>
+static void usage(const char *progname)
+{
+ fprintf(stderr, "usage: %s [-n] command [args...]\n", progname);
+ exit(-1);
+}
+
int main(int argc, char **argv)
{
bool nobounded;
struct utsname uts;
pid_t pid;
int rc, status;
+ int opt;
+ bool nnp = false;
- if (argc < 2) {
- fprintf(stderr, "usage: %s command [args...]\n", argv[0]);
- exit(-1);
+ while ((opt = getopt(argc, argv, "n")) != -1) {
+ switch (opt) {
+ case 'n':
+ nnp = true;
+ break;
+ default:
+ usage(argv[0]);
+ break;
+ }
}
+ if ((argc - optind) < 2)
+ usage(argv[0]);
+
if (uname(&uts) < 0) {
perror("uname");
exit(-1);
@@ -28,10 +46,12 @@ int main(int argc, char **argv)
nobounded = ((strcmp(argv[argc - 1], "test_nnp_bounded_t") == 0) &&
(strverscmp(uts.release, "3.18") < 0));
- rc = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
- if (rc < 0) {
- perror("prctl PR_SET_NO_NEW_PRIVS");
- exit(-1);
+ if (nnp) {
+ rc = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ if (rc < 0) {
+ perror("prctl PR_SET_NO_NEW_PRIVS");
+ exit(-1);
+ }
}
pid = fork();
@@ -41,8 +61,8 @@ int main(int argc, char **argv)
}
if (pid == 0) {
- execvp(argv[1], &argv[1]);
- perror(argv[1]);
+ execvp(argv[optind], &argv[optind]);
+ perror(argv[optind]);
exit(-1);
}
new file mode 100755
@@ -0,0 +1,179 @@
+#!/usr/bin/perl
+
+use Test;
+
+BEGIN {
+ $test_count = 8;
+ $test_nnp_nosuid_transition = 0;
+
+ if (
+ system(
+"grep -q 1 /sys/fs/selinux/policy_capabilities/nnp_nosuid_transition 2> /dev/null"
+ ) == 0
+ )
+ {
+ $test_nnp_nosuid_transition = 1;
+ $test_count += 9;
+ }
+
+ plan tests => $test_count;
+}
+
+$basedir = $0;
+$basedir =~ s|(.*)/[^/]*|$1|;
+
+# Remove any leftover programs from prior failed runs.
+system("rm -f $basedir/true");
+
+# Set entrypoint type for bounded domain under NNP.
+system("chcon -t test_bounded_exec_t $basedir/checkcon");
+
+# Create nosuid mount.
+system("mkdir -p $basedir/testdir");
+system("mount -t tmpfs -o nosuid none $basedir/testdir");
+
+# Set entrypoint type for bounded domain under nosuid.
+system("cp $basedir/checkcon $basedir/testdir");
+system("chcon -t test_bounded_exec_t $basedir/testdir/checkcon");
+
+# Transition under NNP to bounded type via setexec.
+$result = system(
+"$basedir/execnnp -n -- runcon -t test_bounded_t $basedir/checkcon test_bounded_t 2>&1"
+);
+ok( $result, 0 ); #this should pass
+
+# Transition on nosuid to bounded type via setexec.
+$result = system(
+"$basedir/execnnp -- runcon -t test_bounded_t $basedir/testdir/checkcon test_bounded_t 2>&1"
+);
+ok( $result, 0 ); #this should pass
+
+# Automatic transition under NNP to bounded domain via exec.
+$result =
+ system("$basedir/execnnp -n -- $basedir/checkcon test_bounded_t 2>&1");
+ok( $result, 0 ); #this should pass
+
+# Automatic transition on nosuid to bounded domain via exec.
+$result =
+ system( "$basedir/execnnp -- $basedir/testdir/checkcon test_bounded_t 2>&1" );
+ok( $result, 0 ); #this should pass
+
+# Use true as an entrypoint program to test ability to exec at all.
+system("cp /bin/true $basedir/true");
+system("cp /bin/true $basedir/testdir/true");
+
+# Set entrypoint type for notbounded domain.
+system( "chcon -t test_notbounded_exec_t $basedir/checkcon $basedir/true" );
+system(
+"chcon -t test_notbounded_exec_t $basedir/testdir/checkcon $basedir/testdir/true"
+);
+
+# Transition under NNP to notbounded domain via setexec.
+$result =
+ system(
+ "$basedir/execnnp -n -- runcon -t test_notbounded_t $basedir/true 2>&1" );
+ok($result); #this should fail
+
+# Transition on nosuid to notbounded domain via setexec.
+$result =
+ system(
+ "$basedir/execnnp -- runcon -t test_notbounded_t $basedir/testdir/true 2>&1"
+ );
+ok($result); #this should fail
+
+# Automatic transition under NNP to notbounded domain via exec.
+$result =
+ system( "$basedir/execnnp -n -- $basedir/checkcon test_notbounded_t 2>&1" );
+ok($result); #this should fail
+
+# Automatic transition on nosuid to notbounded domain via exec.
+$result =
+ system(
+ "$basedir/execnnp -- $basedir/testdir/checkcon test_notbounded_t 2>&1" );
+ok($result); #this should fail
+
+if ($test_nnp_nosuid_transition) {
+
+ # Set entrypoint type for nnptransition domain.
+ system(
+ "chcon -t test_nnptransition_exec_t $basedir/checkcon $basedir/true" );
+
+ # Set entrypoint type for nosuid domain.
+ system(
+"chcon -t test_nosuidtransition_exec_t $basedir/testdir/checkcon $basedir/testdir/true"
+ );
+
+ # Transition under NNP to nnptransition domain via setexec.
+ $result =
+ system(
+"$basedir/execnnp -n -- runcon -t test_nnptransition_t $basedir/true 2>&1"
+ );
+ ok( $result, 0 ); #this should succeed
+
+ # Transition under NNP+nosuid to nnptransition domain via setexec.
+ $result =
+ system(
+"$basedir/execnnp -n -- runcon -t test_nnptransition_t $basedir/testdir/true 2>&1"
+ );
+ ok($result); #this should fail
+
+ # Transition on nosuid to nosuid domain via setexec.
+ $result =
+ system(
+"$basedir/execnnp -- runcon -t test_nosuidtransition_t $basedir/testdir/true 2>&1"
+ );
+ ok( $result, 0 ); #this should succeed
+
+ # Transition on NNP+nosuid to nosuid domain via setexec.
+ $result =
+ system(
+"$basedir/execnnp -n -- runcon -t test_nosuidtransition_t $basedir/testdir/true 2>&1"
+ );
+ ok($result); #this should fail
+
+ # Automatic transition under NNP to nnptransition domain via exec.
+ $result =
+ system(
+ "$basedir/execnnp -n -- $basedir/checkcon test_nnptransition_t 2>&1" );
+ ok( $result, 0 ); #this should succeed
+
+ # Automatic transition on NNP+nosuid to nnptransition domain via exec.
+ $result =
+ system(
+"$basedir/execnnp -n -- $basedir/testdir/checkcon test_nnptransition_t 2>&1"
+ );
+ ok($result); #this should fail
+
+ # Automatic transition on nosuid to nosuid domain via exec.
+ $result =
+ system(
+"$basedir/execnnp -- $basedir/testdir/checkcon test_nosuidtransition_t 2>&1"
+ );
+ ok( $result, 0 ); #this should succeed
+
+ # Automatic transition on NNP+nosuid to nosuid domain via exec.
+ $result =
+ system(
+"$basedir/execnnp -n -- $basedir/testdir/checkcon test_nosuidtransition_t 2>&1"
+ );
+ ok($result); #this should fail
+
+ # Set entrypoint type for nnpnosuid domain.
+ system(
+"chcon -t test_nnpnosuidtransition_exec_t $basedir/testdir/checkcon $basedir/testdir/true"
+ );
+
+ # Transition on NNP+nosuid to nnpnosuid domain via setexec.
+ $result =
+ system(
+"$basedir/execnnp -n -- runcon -t test_nnpnosuidtransition_t $basedir/testdir/true 2>&1"
+ );
+ ok( $result, 0 ); #this should succeed
+}
+
+# Cleanup.
+system("rm -f $basedir/true");
+system("umount $basedir/testdir");
+system("rmdir $basedir/testdir");
+
+exit;
Duplicate the existing tests for transitions under NNP for transitions on a nosuid mount, and then augment both the NNP and nosuid tests to also test the new support for allowing transitions based on nnp_transition and/or nosuid_transition permission if the nnp_nosuid_transition policy capability is enabled. Test NNP and nosuid independently and together. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> --- v2 merges the nnp and nosuid tests together since they overlap significantly in policy and code, and adds new tests for the case where both NNP and nosuid are enabled. policy/Makefile | 6 +- policy/test_nnp.te | 34 ------- policy/test_nnp_nosuid.te | 85 +++++++++++++++++ tests/Makefile | 10 +- tests/nnp/test | 44 --------- tests/{nnp => nnp_nosuid}/Makefile | 0 tests/{nnp => nnp_nosuid}/checkcon.c | 0 tests/{nnp => nnp_nosuid}/execnnp.c | 38 ++++++-- tests/nnp_nosuid/test | 179 +++++++++++++++++++++++++++++++++++ 9 files changed, 303 insertions(+), 93 deletions(-) delete mode 100644 policy/test_nnp.te create mode 100644 policy/test_nnp_nosuid.te delete mode 100755 tests/nnp/test rename tests/{nnp => nnp_nosuid}/Makefile (100%) rename tests/{nnp => nnp_nosuid}/checkcon.c (100%) rename tests/{nnp => nnp_nosuid}/execnnp.c (62%) create mode 100755 tests/nnp_nosuid/test