diff mbox series

[RFC,1/1] selinux-testsuite: Test all mount option context types

Message ID 20200204143707.318337-2-richard_c_haines@btinternet.com (mailing list archive)
State Rejected
Headers show
Series selinux-testsuite: Test all mount option context types | expand

Commit Message

Richard Haines Feb. 4, 2020, 2:37 p.m. UTC
Test supported filesystems for mount options: context, defcontext,
rootcontext and fscontext. The tests use fsconfig(2) and therefore does
not actually mount the filesystem to a target.

All /sbin/mkfs.* entries are read and if supported, tested with each option.

Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
---
 policy/test_filesystem.te      |  12 +++
 tests/Makefile                 |   2 +-
 tests/filesystem/Filesystem.pm |  19 +++-
 tests/fs_contexts/.gitignore   |   1 +
 tests/fs_contexts/Makefile     |  13 +++
 tests/fs_contexts/fsconfig.c   |  72 ++++++++++++++++
 tests/fs_contexts/test         | 153 +++++++++++++++++++++++++++++++++
 7 files changed, 268 insertions(+), 4 deletions(-)
 create mode 100644 tests/fs_contexts/.gitignore
 create mode 100644 tests/fs_contexts/Makefile
 create mode 100644 tests/fs_contexts/fsconfig.c
 create mode 100755 tests/fs_contexts/test
diff mbox series

Patch

diff --git a/policy/test_filesystem.te b/policy/test_filesystem.te
index 4ff493a..220f79e 100644
--- a/policy/test_filesystem.te
+++ b/policy/test_filesystem.te
@@ -6,6 +6,9 @@ 
 attribute filesystemdomain;
 kernel_setsched(filesystemdomain)
 
+# For module filesystems
+kernel_request_load_module(filesystemdomain)
+
 #################### Create test file contexts ######################
 type test_filesystem_filecon_t;
 files_type(test_filesystem_filecon_t)
@@ -58,6 +61,15 @@  type_transition test_filesystem_t test_filesystem_file_t:file test_filesystem_fi
 allow test_filesystem_t test_filesystem_filetranscon_t:file { create getattr open write relabelfrom };
 dontaudit unconfined_t test_filesystem_filetranscon_t:file { getattr read };
 
+#
+# For fs_contexts tests
+#
+allow test_filesystem_t test_filesystem_file_t:filesystem { mount relabelfrom relabelto };
+allow test_filesystem_t unlabeled_t:filesystem { relabelfrom };
+# For fs_context test rootcontext= minix
+allow test_filesystem_file_t unlabeled_t:filesystem { associate };
+allow test_filesystem_t unlabeled_t:filesystem { mount };
+
 #################### Deny filesystem { relabelfrom } ######################
 # hooks.c may_context_mount_sb_relabel() FILESYSTEM__RELABELFROM
 type test_filesystem_sb_relabel_no_relabelfrom_t;
diff --git a/tests/Makefile b/tests/Makefile
index 46a1641..87708fb 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -100,7 +100,7 @@  endif
 
 ifeq ($(shell grep -q filesystem $(POLDEV)/include/support/all_perms.spt && echo true),true)
 ifneq ($(shell ./kvercmp $$(uname -r) 5.2),-1)
-SUBDIRS += fs_filesystem
+SUBDIRS += fs_filesystem fs_contexts
 endif
 endif
 
diff --git a/tests/filesystem/Filesystem.pm b/tests/filesystem/Filesystem.pm
index 3d4194d..680bf0b 100644
--- a/tests/filesystem/Filesystem.pm
+++ b/tests/filesystem/Filesystem.pm
@@ -111,17 +111,30 @@  sub attach_dev {
 
 sub make_fs {
     my ( $mk_type, $mk_dev, $mk_dir ) = @_;
+
+    if ( $mk_type eq "btrfs" or $mk_type eq "reiserfs" ) {
+        $count = "count=27904";
+    }
+    else {
+        $count = "count=4096";
+    }
+
     print "Create $mk_dir/fstest with dd\n";
-    $result = system(
-        "dd if=/dev/zero of=$mk_dir/fstest bs=1024 count=10240 2>/dev/null");
+    $result =
+      system("dd if=/dev/zero of=$mk_dir/fstest bs=4096 $count 2>/dev/null");
     if ( $result != 0 ) {
         print "dd failed to create $mk_dir/fstest\n";
     }
 
     attach_dev( $mk_dev, $mk_dir );
 
+    $opt = " ";
+    if ( $mk_type eq "reiserfs" ) {
+        $opt = "-q";    # Otherwise asks to proceed
+    }
+
     print "Make $mk_type filesystem on $mk_dev\n";
-    $result = system("mkfs.$mk_type -I 256 $mk_dev >& /dev/null");
+    $result = system("mkfs.$mk_type $opt $mk_dev >& /dev/null");
     if ( $result != 0 ) {
         system("losetup -d $mk_dev 2>/dev/null");
         print "mkfs.$mk_type failed to create filesystem on $mk_dev\n";
diff --git a/tests/fs_contexts/.gitignore b/tests/fs_contexts/.gitignore
new file mode 100644
index 0000000..c870437
--- /dev/null
+++ b/tests/fs_contexts/.gitignore
@@ -0,0 +1 @@ 
+fsconfig
diff --git a/tests/fs_contexts/Makefile b/tests/fs_contexts/Makefile
new file mode 100644
index 0000000..012c4fa
--- /dev/null
+++ b/tests/fs_contexts/Makefile
@@ -0,0 +1,13 @@ 
+TARGETS = fsconfig
+USE_FS = ../fs_filesystem
+DEPS = $(USE_FS)/fs_common.c $(USE_FS)/fs_common.h
+LDLIBS += -lselinux
+
+all: $(TARGETS)
+	@set -e; for i in $(USE_FS); do $(MAKE) -C $$i all ; done
+
+clean:
+	rm -f $(TARGETS)
+	@set -e; for i in $(USE_FS); do $(MAKE) -C $$i clean ; done
+
+$(TARGETS): $(DEPS)
diff --git a/tests/fs_contexts/fsconfig.c b/tests/fs_contexts/fsconfig.c
new file mode 100644
index 0000000..e4cd8d8
--- /dev/null
+++ b/tests/fs_contexts/fsconfig.c
@@ -0,0 +1,72 @@ 
+#include "../fs_filesystem/fs_common.h"
+
+static void print_usage(char *progname)
+{
+	fprintf(stderr,
+		"usage:  %s -s src -f fs_type -o options [-v]\n"
+		"Where:\n\t"
+		"-s  Source path\n\t"
+		"-f  Filesystem type\n\t"
+		"-o  Options list (comma separated list)\n\t"
+		"-v  Print information.\n", progname);
+	exit(-1);
+}
+
+int main(int argc, char *argv[])
+{
+	int opt, result, fsfd;
+	char *context, *src = NULL, *opts1, *fs_type = NULL, *opts = NULL;
+	bool verbose = false;
+
+	while ((opt = getopt(argc, argv, "s:f:o:v")) != -1) {
+		switch (opt) {
+		case 's':
+			src = optarg;
+			break;
+		case 'f':
+			fs_type = optarg;
+			break;
+		case 'o':
+			opts = optarg;
+			break;
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			print_usage(argv[0]);
+		}
+	}
+
+	if (!src || !fs_type || !opts)
+		print_usage(argv[0]);
+
+	if (verbose) {
+		result = getcon(&context);
+		if (result < 0) {
+			fprintf(stderr, "Failed to obtain process context\n");
+			return -1;
+		}
+		printf("Process context:\n\t%s\n", context);
+		free(context);
+	}
+
+	fsfd = fsopen(fs_type, 0);
+	if (fsfd < 0) {
+		fprintf(stderr, "Failed fsopen(2): %s\n", strerror(errno));
+		return -1;
+	}
+
+	opts1 = strdup(opts);
+
+	/* fsconfig_opts() will return 0 or errno from fsconfig(2) */
+	result = fsconfig_opts(fsfd, src, NULL, opts, verbose);
+	if (result) {
+		fprintf(stderr, "Failed config_opts\n");
+		return result;
+	}
+	if (verbose)
+		printf("Successfully added options: %s\n", opts1);
+
+	close(fsfd);
+	return 0;
+}
diff --git a/tests/fs_contexts/test b/tests/fs_contexts/test
new file mode 100755
index 0000000..8437dcb
--- /dev/null
+++ b/tests/fs_contexts/test
@@ -0,0 +1,153 @@ 
+#!/usr/bin/perl
+use Test::More;
+
+my @mkfs_list;
+my @fs_type_list;
+
+BEGIN {
+    $basedir = $0;
+    $basedir =~ s|(.*)/[^/]*|$1|;
+
+    # Load common subroutines.
+    use File::Basename qw(dirname);
+    use Cwd qw(abs_path);
+    use lib dirname( abs_path $0) . '/../filesystem';
+    use Filesystem
+      qw(udisks2_stop udisks2_restart get_loop_dev make_fs mk_mntpoint_1 cleanup1 reaper);
+
+    # Options: -v = Verbose, -e enable udisks(8) daemon
+    $v = " ";
+
+    # MUST stop udisksd(8) as it interferes with creating/deleting
+    # filesystems during these tests
+    $disable_udisks = 1;
+    $udisks2_status = 0;
+    foreach $arg (@ARGV) {
+        if ( $arg eq "-v" ) {
+            $v = $arg;
+        }
+        elsif ( $arg eq "-e" ) {
+            $disable_udisks = 0;
+        }
+    }
+
+    my @mkfs_list = map { chomp; $_ } `find /sbin/mkfs.* -printf "%f\n"`;
+    $i = 0;
+    foreach my $fstype (@mkfs_list) {
+        @split_fn = split( /\./, $fstype );
+        if ( $split_fn[1] eq "cramfs" ) {
+            print "$split_fn[1] - unsupported\n";
+            next;
+        }
+        elsif ($split_fn[1] eq "btrfs"
+            or $split_fn[1] eq "ext2"
+            or $split_fn[1] eq "ext3"
+            or $split_fn[1] eq "ext4"
+            or $split_fn[1] eq "fat"
+            or $split_fn[1] eq "hfsplus"
+            or $split_fn[1] eq "minix"
+            or $split_fn[1] eq "msdos"
+            or $split_fn[1] eq "ntfs"
+            or $split_fn[1] eq "reiserfs"
+            or $split_fn[1] eq "vfat"
+            or $split_fn[1] eq "xfs" )
+        {
+            $fs_type_list[$i] = $split_fn[1];
+            print "$split_fn[1] - supported\n";
+            $i++;
+        }
+    }
+
+    plan tests => ( $i * 4 );
+}
+
+# Keep a list of devices used for removal at end of test.
+$device_count = 0;
+my @device_list;
+
+if ($disable_udisks) {
+    $udisks2_status = udisks2_stop();
+}
+
+$context_opt     = "context=system_u:object_r:test_filesystem_file_t:s0";
+$rootcontext_opt = "rootcontext=system_u:object_r:test_filesystem_file_t:s0";
+$defcontext_opt  = "defcontext=system_u:object_r:test_filesystem_file_t:s0";
+$fscontext_opt   = "fscontext=system_u:object_r:test_filesystem_file_t:s0";
+
+foreach my $fs_type (@fs_type_list) {
+    mk_mntpoint_1("$basedir/mntpoint");
+    ( $dev, $device_count ) = get_loop_dev( \@device_list, $device_count );
+    make_fs( $fs_type, $dev, $basedir );
+
+    if ( $fs_type eq "ntfs" ) {
+        $fs_type = "fuseblk";
+    }
+    if ( $fs_type eq "fat" ) {
+        $fs_type = "vfat";
+    }
+
+    # Test context
+    print "Testing context= for $fs_type\n";
+    $result = system(
+"runcon -t test_filesystem_t $basedir/fsconfig $v -f $fs_type -s $dev -o $context_opt 2>&1"
+    );
+    if ( $fs_type eq "fuseblk" ) {    # This is expected to fail
+        ok(1);
+    }
+    else {
+        ok( $result eq 0 );
+    }
+
+    # Test defcontext
+    print "Testing defcontext= for $fs_type\n";
+    $result = system(
+"runcon -t test_filesystem_t $basedir/fsconfig $v -f $fs_type -s $dev -o $defcontext_opt 2>&1"
+    );
+    if (   $fs_type eq "vfat"
+        or $fs_type eq "hfsplus"
+        or $fs_type eq "minix"
+        or $fs_type eq "msdos"
+        or $fs_type eq "fuseblk"
+        or $fs_type eq "reiserfs" )
+    {    # These are expected to fail
+        ok(1);
+    }
+    else {
+        ok( $result eq 0 );
+    }
+
+    # Test rootcontext
+    print "Testing rootcontext= for $fs_type\n";
+    $result = system(
+"runcon -t test_filesystem_t $basedir/fsconfig $v -f $fs_type -s $dev -o $rootcontext_opt 2>&1"
+    );
+    if ( $fs_type eq "fuseblk" ) {    # This is expected to fail
+        ok(1);
+    }
+    else {
+        ok( $result eq 0 );
+    }
+
+    # Test fscontext
+    print "Testing fscontext= for $fs_type\n";
+    $result = system(
+"runcon -t test_filesystem_t $basedir/fsconfig $v -f $fs_type -s $dev -o $fscontext_opt 2>&1"
+    );
+    if ( $fs_type eq "fuseblk" ) {    # This is expected to fail
+        ok(1);
+    }
+    else {
+        ok( $result eq 0 );
+    }
+
+    cleanup1( $basedir, $dev );
+}
+
+cleanup1( $basedir, $dev );
+reaper( \@device_list, $basedir, $v );
+
+if ($disable_udisks) {
+    udisks2_restart($udisks2_status);
+}
+
+exit;