[PATCH] selinux-testsuite: update for mprotect PROT_EXEC regression fix

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



commit 66fc13039422ba7df2d01a8ee0873e4ef965b50b ("mm: shmem_zero_setup skip
security check and lockdep conflict with XFS") caused a regression for
SELinux by disabling any SELinux checking of mprotect PROT_EXEC on
shared anonymous mappings.  Previously SELinux was applying a tmpfs
file execute check in this situation because the kernel created an internal
shmem dev/zero file for the mapping.  commit
892e8cac99a71f6254f84fc662068d912e1943bf ("selinux: fix mprotect
PROT_EXEC regression caused by mm change") fixed the regression by changing
SELinux to detect and apply an execmem check on private inodes, making the
mmap and mprotect checking consistent for shared anonymous mappings as well
as for /dev/zero and ashmem.  Update the SELinux test policy and case for
mprotect PROT_EXEC of shared anonymous mappings so that it will pass
on both kernels that predate the regression and on kernels that include
the fix despite the difference in permission checking, only failing on
kernels the completely omit the checking (e.g. 4.1, 4.2-rc1).  Rename
the test domain to more accurately reflect its purpose.

Also add new tests for mmap/mprotect PROT_EXEC /dev/zero.

Signed-off-by: Stephen Smalley <sds@xxxxxxxxxxxxx>
---
 policy/test_mmap.te | 67 ++++++++++++++++++++++++++++++++++++++++++-----------
 tests/mmap/test     | 22 ++++++++++++++----
 2 files changed, 72 insertions(+), 17 deletions(-)

diff --git a/policy/test_mmap.te b/policy/test_mmap.te
index 0246e31..2a66514 100644
--- a/policy/test_mmap.te
+++ b/policy/test_mmap.te
@@ -38,23 +38,64 @@ typeattribute test_no_execmem_t mmaptestdomain;
 # For mprotect_file_private test.
 allow test_no_execmem_t test_mmap_file_t:file { open read };
 
-type test_tmpfs_execute_t;
-domain_type(test_tmpfs_execute_t)
-unconfined_runs_test(test_tmpfs_execute_t)
-typeattribute test_tmpfs_execute_t testdomain;
-typeattribute test_tmpfs_execute_t mmaptestdomain;
+type test_mprotect_anon_shared_t;
+domain_type(test_mprotect_anon_shared_t)
+unconfined_runs_test(test_mprotect_anon_shared_t)
+typeattribute test_mprotect_anon_shared_t testdomain;
+typeattribute test_mprotect_anon_shared_t mmaptestdomain;
 
 gen_require(`
 	type tmpfs_t;
 ')
-allow test_tmpfs_execute_t tmpfs_t:file { read write execute };
-
-type test_no_tmpfs_execute_t;
-domain_type(test_no_tmpfs_execute_t)
-unconfined_runs_test(test_no_tmpfs_execute_t)
-typeattribute test_no_tmpfs_execute_t testdomain;
-typeattribute test_no_tmpfs_execute_t mmaptestdomain;
-allow test_no_tmpfs_execute_t tmpfs_t:file { read write };
+# In old kernels, mprotect PROT_EXEC on an anonymous shared mapping
+# triggers a tmpfs file execute check on the kernel-internal shmem /dev/zero
+# inode.  In new kernels, mprotect PROT_EXEC will instead trigger an
+# execmem check, making it consistent with the mmap PROT_EXEC case.
+# We allow both permissions here so that the test passes regardless.
+allow test_mprotect_anon_shared_t tmpfs_t:file { read execute };
+allow test_mprotect_anon_shared_t self:process execmem;
+
+type test_no_mprotect_anon_shared_t;
+domain_type(test_no_mprotect_anon_shared_t)
+unconfined_runs_test(test_no_mprotect_anon_shared_t)
+typeattribute test_no_mprotect_anon_shared_t testdomain;
+typeattribute test_no_mprotect_anon_shared_t mmaptestdomain;
+allow test_no_mprotect_anon_shared_t tmpfs_t:file read;
+
+type test_mmap_dev_zero_t;
+domain_type(test_mmap_dev_zero_t)
+unconfined_runs_test(test_mmap_dev_zero_t)
+typeattribute test_mmap_dev_zero_t testdomain;
+typeattribute test_mmap_dev_zero_t mmaptestdomain;
+dev_rwx_zero(test_mmap_dev_zero_t)
+
+type test_no_mmap_dev_zero_t;
+domain_type(test_no_mmap_dev_zero_t)
+unconfined_runs_test(test_no_mmap_dev_zero_t)
+typeattribute test_no_mmap_dev_zero_t testdomain;
+typeattribute test_no_mmap_dev_zero_t mmaptestdomain;
+dev_rw_zero(test_no_mmap_dev_zero_t)
+
+type test_mprotect_dev_zero_t;
+domain_type(test_mprotect_dev_zero_t)
+unconfined_runs_test(test_mprotect_dev_zero_t)
+typeattribute test_mprotect_dev_zero_t testdomain;
+typeattribute test_mprotect_dev_zero_t mmaptestdomain;
+dev_rw_zero(test_mprotect_dev_zero_t)
+# In old kernels, mprotect PROT_EXEC on /dev/zero
+# triggers a tmpfs file execute check on the kernel-internal shmem /dev/zero
+# inode.  In new kernels, mprotect PROT_EXEC will instead trigger an
+# execmem check, making it consistent with the mmap PROT_EXEC case.
+# We allow both permissions here so that the test passes regardless.
+allow test_mprotect_dev_zero_t tmpfs_t:file { read execute };
+allow test_mprotect_dev_zero_t self:process execmem;
+
+type test_no_mprotect_dev_zero_t;
+domain_type(test_no_mprotect_dev_zero_t)
+unconfined_runs_test(test_no_mprotect_dev_zero_t)
+typeattribute test_no_mprotect_dev_zero_t testdomain;
+typeattribute test_no_mprotect_dev_zero_t mmaptestdomain;
+dev_rw_zero(test_no_mprotect_dev_zero_t)
 
 type test_file_rwx_t;
 domain_type(test_file_rwx_t)
diff --git a/tests/mmap/test b/tests/mmap/test
index 4337b43..6b1de55 100755
--- a/tests/mmap/test
+++ b/tests/mmap/test
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 
 use Test;
-BEGIN { plan tests => 26}
+BEGIN { plan tests => 30}
 
 $basedir = $0;  $basedir =~ s|(.*)/[^/]*|$1|;
 
@@ -36,10 +36,24 @@ ok($result, 0);
 $result = system "runcon -t test_no_execmem_t $basedir/mmap_anon_shared 2>&1";
 ok($result);
 
-# Test success and failure for tmpfs execute on mprotect w/ anonymous shared memory.
-$result = system "runcon -t test_tmpfs_execute_t $basedir/mprotect_anon_shared";
+# Test success and failure for mmap /dev/zero.
+$result = system "runcon -t test_mmap_dev_zero_t $basedir/mmap_file_shared /dev/zero";
 ok($result, 0);
-$result = system "runcon -t test_no_tmpfs_execute_t $basedir/mprotect_anon_shared 2>&1";
+$result = system "runcon -t test_no_mmap_dev_zero_t $basedir/mmap_file_shared /dev/zero 2>&1";
+ok($result);
+
+# Test success and failure for mprotect w/ anonymous shared memory.
+# In old kernels, this triggers a tmpfs file execute check.
+# In new kernels, it triggers an execmem check.
+$result = system "runcon -t test_mprotect_anon_shared_t $basedir/mprotect_anon_shared";
+ok($result, 0);
+$result = system "runcon -t test_no_mprotect_anon_shared_t $basedir/mprotect_anon_shared 2>&1";
+ok($result);
+
+# Test success and failure for mprotect /dev/zero.
+$result = system "runcon -t test_mprotect_dev_zero_t $basedir/mprotect_file_shared /dev/zero";
+ok($result, 0);
+$result = system "runcon -t test_no_mprotect_dev_zero_t $basedir/mprotect_file_shared /dev/zero 2>&1";
 ok($result);
 
 # Test success and failure for execheap, independent of execmem.
-- 
2.1.0

_______________________________________________
Selinux mailing list
Selinux@xxxxxxxxxxxxx
To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.



[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux