Re: [PATCH testsuite] selinux-testsuite: Add submount test

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

 



On 9/30/19 9:16 AM, Ondrej Mosnacek wrote:
Add a test that verifies that SELinux permissions are not checked when
mounting submounts. The test sets up a simple local NFS export on a
directory which has another filesystem mounted on its subdirectory.
Since the export is set up with the crossmnt option enabled, any client
mount will try to transparently mount any subdirectory that has a
filesystem mounted on it on the server, triggering an internal mount.
The test tries to access the automounted part of this export via a
client mount without having a permission to mount filesystems, expecting
it to succeed.

The original bug this test is checking for has been fixed in kernel
commit 892620bb3454 ("selinux: always allow mounting submounts"), which
has been backported to 4.9+ stable kernels.

The test first checks whether it is able to export and mount directories
via NFS and skips the actual tests if e.g. NFS daemon is not running.
This means that the testsuite can still be run without having the NFS
server installed and running.

1) We have to manually start nfs-server in order for the test to run; else it will be skipped automatically. Do we want to start/stop the nfs-server as part of the test script?

2) I'm still getting test failures:
submount/test ............... ls: cannot access '/home/sds/selinux-testsuite/tests/submount/nfs_import': Permission denied
submount/test ............... 1/2
#   Failed test at submount/test line 70.
cat: /home/sds/selinux-testsuite/tests/submount/nfs_import/submount/file: Permission denied

#   Failed test at submount/test line 75.
# Looks like you failed 2 tests of 2.
submount/test ............... Dubious, test returned 2 (wstat 512, 0x200)
Failed 2/2 subtests

type=AVC msg=audit(1569852140.955:10938): avc: denied { search } for pid=20535 comm="ls" name="selinux-testsuite" dev="dm-2" ino=17170498 scontext=unconfined_u:unconfined_r:test_readnfs_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=dir permissive=0

It looks like we need more than userdom_search_generic_user_home_dirs() as presently defined (user_home_dir_t vs user_home_t search access?).


Signed-off-by: Ondrej Mosnacek <omosnace@xxxxxxxxxx>
---
  README.md               | 24 ++++++++++++
  defconfig               | 11 ++++++
  policy/Makefile         |  2 +-
  policy/test_submount.te | 31 +++++++++++++++
  tests/Makefile          |  3 +-
  tests/submount/Makefile |  2 +
  tests/submount/test     | 84 +++++++++++++++++++++++++++++++++++++++++
  7 files changed, 155 insertions(+), 2 deletions(-)
  create mode 100644 policy/test_submount.te
  create mode 100644 tests/submount/Makefile
  create mode 100755 tests/submount/test

diff --git a/README.md b/README.md
index 1396c8e..f45f5b4 100644
--- a/README.md
+++ b/README.md
@@ -114,6 +114,30 @@ the tests:
  	tests/infiniband_pkey/ibpkey_test.conf
  	tests/infiniband_endport/ibendport_test.conf
+#### NFS server and client support
+
+The NFS automount test (tests/submount) requires NFS server and client support
+in the kernel.  In addition, it requires the NFS utility programs and a running
+NFS daemon.  On Fedora/RHEL you need the following package (other distributions
+should have a similar package):
+
+* nfs-utils _(to setup the NFS server and export directory trees)_
+
+On a modern Fedora system you can install it with the following command:
+
+	# dnf install nfs-utils
+
+The process to start the NFS server service varies across distributions, but
+usually you can start it by running:
+
+	# service nfs-server start
+	(or)
+	# service nfs start
+	(or)
+	# systemctl start nfs-server
+	(or)
+	# systemctl start nfs
+
  ## Running the Tests
Create a shell with the `unconfined_r` or `sysadm_r` role and the Linux
diff --git a/defconfig b/defconfig
index cb57f22..2bcebbb 100644
--- a/defconfig
+++ b/defconfig
@@ -67,3 +67,14 @@ CONFIG_ANDROID_BINDERFS=y
  # They are not required for SELinux operation itself.
  CONFIG_BPF=y
  CONFIG_BPF_SYSCALL=y
+
+# NFS server and client.
+# This is enabled for testing NFS automount in tests/submount.
+# It is not required for SELinux operation itself.
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_MULTIUSER=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=m
diff --git a/policy/Makefile b/policy/Makefile
index a5942b3..dbef42d 100644
--- a/policy/Makefile
+++ b/policy/Makefile
@@ -24,7 +24,7 @@ TARGETS = \
  	test_task_getsid.te test_task_setpgid.te test_task_setsched.te \
  	test_transition.te test_unix_socket.te \
  	test_mmap.te test_overlayfs.te test_mqueue.te \
-	test_ibpkey.te test_atsecure.te test_cgroupfs.te
+	test_ibpkey.te test_atsecure.te test_cgroupfs.te test_submount.te
ifeq ($(shell [ $(POL_VERS) -ge 24 ] && echo true),true)
  TARGETS += test_bounds.te test_nnp_nosuid.te
diff --git a/policy/test_submount.te b/policy/test_submount.te
new file mode 100644
index 0000000..8694c6b
--- /dev/null
+++ b/policy/test_submount.te
@@ -0,0 +1,31 @@
+#################################
+#
+# Policy for testing NFS crosmnt
+#
+
+# A domain that can access NFS files/directories
+type test_readnfs_t;
+domain_type(test_readnfs_t)
+unconfined_runs_test(test_readnfs_t)
+domain_obj_id_change_exemption(test_readnfs_t)
+typeattribute test_readnfs_t testdomain;
+
+# Allow execution of helper programs
+corecmd_exec_bin(test_readnfs_t)
+domain_exec_all_entry_files(test_readnfs_t)
+libs_use_ld_so(test_readnfs_t)
+libs_use_shared_libs(test_readnfs_t)
+libs_exec_ld_so(test_readnfs_t)
+libs_exec_lib_files(test_readnfs_t)
+
+# Allow this domain to be entered from sysadm domain
+miscfiles_domain_entry_test_files(test_readnfs_t)
+userdom_sysadm_entry_spec_domtrans_to(test_readnfs_t)
+corecmd_bin_entry_type(test_readnfs_t)
+sysadm_bin_spec_domtrans_to(test_readnfs_t)
+
+# Allow the domain to search home dirs so that ls works
+userdom_search_generic_user_home_dirs(test_readnfs_t)
+
+# Allow the domain to read NFS mounted files/directories
+fs_read_nfs_files(test_readnfs_t)
diff --git a/tests/Makefile b/tests/Makefile
index e5bdfff..e292be3 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -11,7 +11,8 @@ SUBDIRS:= domain_trans entrypoint execshare exectrace execute_no_trans \
  	task_setnice task_setscheduler task_getscheduler task_getsid \
  	task_getpgid task_setpgid file ioctl capable_file capable_net \
  	capable_sys dyntrans dyntrace bounds nnp_nosuid mmap unix_socket \
-	inet_socket overlay checkreqprot mqueue mac_admin atsecure
+	inet_socket overlay checkreqprot mqueue mac_admin atsecure \
+	submount
ifeq ($(shell grep -q cap_userns $(POLDEV)/include/support/all_perms.spt && echo true),true)
  ifneq ($(shell ./kvercmp $$(uname -r) 4.7),-1)
diff --git a/tests/submount/Makefile b/tests/submount/Makefile
new file mode 100644
index 0000000..e7c006f
--- /dev/null
+++ b/tests/submount/Makefile
@@ -0,0 +1,2 @@
+all:
+clean:
diff --git a/tests/submount/test b/tests/submount/test
new file mode 100755
index 0000000..754b989
--- /dev/null
+++ b/tests/submount/test
@@ -0,0 +1,84 @@
+#!/usr/bin/perl
+# SPDX-License-Identifier: GPL-2.0
+#
+# This test checks that NFS automounts do not trigger
+# unwanted SELinux checks for mount permission
+#
+# Author:  Ondrej Mosnacek <omosnace@xxxxxxxxxx>
+# Based on code by:  Martin Frodl <mfrodl@xxxxxxxxxx>
+# Copyright (c) 2018 Red Hat, Inc.
+#
+
+use Test::More;
+use File::Spec;
+
+my ( $basedir, $result );
+
+BEGIN {
+    $basedir = File::Spec->rel2abs($0);
+    $basedir =~ s|(.*)/[^/]*|$1|;
+
+    system "rm -rf $basedir/nfs_export 2>&1";
+    system "rm -rf $basedir/nfs_import 2>&1";
+
+    system "mkdir $basedir/nfs_export";
+    system "mkdir $basedir/nfs_import";
+
+    # Try exporting and mounting NFS.
+    $result =
+      system "exportfs -o ro,crossmnt,sync 127.0.0.1:$basedir/nfs_export 2>&1";
+    $result += system "mount -t nfs -o ro,timeo=5,retry=0,retrans=1 "
+      . "127.0.0.1:$basedir/nfs_export $basedir/nfs_import 2>&1";
+
+    # Cleanup.
+    system "umount $basedir/nfs_import 2>&1";
+    system "exportfs -u 127.0.0.1:$basedir/nfs_export 2>&1";
+
+    # If basic NFS workflow failed, then skip the test.
+    if ( $result eq 0 ) {
+        plan tests => 2;
+    }
+    else {
+        system "rm -rf $basedir/nfs_export 2>&1";
+        system "rm -rf $basedir/nfs_import 2>&1";
+        plan skip_all => "Unable to use NFS server/client";
+    }
+}
+
+# Create an EXT2 image to mount as submount (NFS needs a fs with UUID).
+system
+  "dd if=/dev/zero of=$basedir/nfs_export/image.ext2 bs=5M count=1 status=none";
+system "mkfs.ext2 -q -F $basedir/nfs_export/image.ext2";
+
+# Create the submount dir and mount the EXT2 image on it.
+system "mkdir $basedir/nfs_export/submount";
+system "mount -t ext2 -o loop "
+  . "$basedir/nfs_export/image.ext2 $basedir/nfs_export/submount";
+system "touch $basedir/nfs_export/submount/file";
+
+system "chcon -R -t test_file_t $basedir/nfs_export";
+
+# Export the directory.
+system "exportfs -o ro,crossmnt,sync 127.0.0.1:$basedir/nfs_export";
+
+# Mount the NFS export.
+system "mount -t nfs -o ro 127.0.0.1:$basedir/nfs_export $basedir/nfs_import";
+
+# Sanity check if we can access the mounted filesystem.
+$result =
+  system "runcon -t test_readnfs_t -- ls $basedir/nfs_import >/dev/null";
+ok( $result eq 0 );
+
+# Check that we can access the submounted filesystem.
+$result = system "runcon -t test_readnfs_t -- "
+  . "cat $basedir/nfs_import/submount/file >/dev/null";
+ok( $result eq 0 );
+
+# Cleanup.
+system "umount $basedir/nfs_import 2>&1";
+system "exportfs -u 127.0.0.1:$basedir/nfs_export 2>&1";
+while ( system("umount $basedir/nfs_export/submount 2>&1") ne 0 ) {
+    select( undef, undef, undef, 1 );
+}
+system "rm -rf $basedir/nfs_export 2>&1";
+system "rm -rf $basedir/nfs_import 2>&1";





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

  Powered by Linux