All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 0/1] selinux-testsuite: Add filesystem tests
@ 2020-01-09 15:07 Richard Haines
  2020-01-09 15:07 ` [PATCH V2 1/1] " Richard Haines
  2020-01-09 18:04 ` [PATCH V2 0/1] " Stephen Smalley
  0 siblings, 2 replies; 19+ messages in thread
From: Richard Haines @ 2020-01-09 15:07 UTC (permalink / raw)
  To: selinux; +Cc: omosnace, Richard Haines

These tests should cover all the areas in selinux/hooks.c that touch
the 'filesystem' class. Each hooks.c function is listed in the 'test'
script as there are some permissions that are checked in multiple places.

Tested on Fedora 31 and Rawhide (5.5 for the new watch perm).

V2 Changes:
1) If udisks(8) daemon is running, stop then restart after tests. The tests
   run faster and stops the annoying habit of adding mounts to the 'files'
   app on the desktop. Supports /usr/bin/systemctl or /usr/sbin/service
   More importantly it stops interferance with the '*context=' tests as it
   can cause intermittent failures. Tested by running 'test' in a continuous
   loop with udisks enabled, and then again disabled.
   Loop 200 times, with udisks failed between 1 to 70 iterations, without
   udisks, no failures.
2) Add "#define QFMT_VFS_V0 2" to quotas_test.c to fix a RHEL/CentOS 7 and
   below build issue.
3) Build new file context based on the original in
   create_file_change_context.c
4) Use "runcon `id -Z` quotacheck ..." to resolve RHEL-6 test run issue.
5) Fix free() contexts in create_file_change_context.c and
   check_mount_context.c

To test fanotify fs watch perm on 5.5+:
1) Build the testsuite policy first:
make -C policy load

2) Add the following CIL statements to watch.cil and install:
semodule -i watch.cil

(common filesystem (watch))
(classcommon filesystem filesystem)
(allow test_filesystem_t self(filesystem (watch)))
; Until 'fs_watch_all_fs(test_filesystem_t)' in Policy use:
(allow test_filesystem_t fs_t (filesystem (watch)))
; Required if notify policy enabled
;(allow test_filesystem_t self (dir (watch_sb)))

3) Edit /usr/share/selinux/devel/include/support/all_perms.spt
   and insert the 'watch' permission at:

define(`all_filesystem_perms',`{ mount remount ..... watch }')

Richard Haines (1):
  selinux-testsuite: Add filesystem tests

 defconfig                                     |   6 +
 policy/Makefile                               |   4 +
 policy/test_filesystem.te                     | 324 +++++++
 tests/Makefile                                |   7 +
 tests/filesystem/.gitignore                   |  11 +
 tests/filesystem/Makefile                     |  16 +
 tests/filesystem/check_file_context.c         |  75 ++
 tests/filesystem/check_mount_context.c        | 125 +++
 tests/filesystem/create_file.c                |  79 ++
 tests/filesystem/create_file_change_context.c | 146 +++
 tests/filesystem/fanotify_fs.c                |  79 ++
 tests/filesystem/fs_relabel.c                 |  72 ++
 tests/filesystem/grim_reaper.c                |  63 ++
 tests/filesystem/mount.c                      | 130 +++
 tests/filesystem/quotas_test.c                | 143 +++
 tests/filesystem/statfs_test.c                |  65 ++
 tests/filesystem/test                         | 882 ++++++++++++++++++
 tests/filesystem/umount.c                     |  84 ++
 18 files changed, 2311 insertions(+)
 create mode 100644 policy/test_filesystem.te
 create mode 100644 tests/filesystem/.gitignore
 create mode 100644 tests/filesystem/Makefile
 create mode 100644 tests/filesystem/check_file_context.c
 create mode 100644 tests/filesystem/check_mount_context.c
 create mode 100644 tests/filesystem/create_file.c
 create mode 100644 tests/filesystem/create_file_change_context.c
 create mode 100644 tests/filesystem/fanotify_fs.c
 create mode 100644 tests/filesystem/fs_relabel.c
 create mode 100644 tests/filesystem/grim_reaper.c
 create mode 100644 tests/filesystem/mount.c
 create mode 100644 tests/filesystem/quotas_test.c
 create mode 100644 tests/filesystem/statfs_test.c
 create mode 100755 tests/filesystem/test
 create mode 100644 tests/filesystem/umount.c

-- 
2.24.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-09 15:07 [PATCH V2 0/1] selinux-testsuite: Add filesystem tests Richard Haines
@ 2020-01-09 15:07 ` Richard Haines
  2020-01-09 17:14   ` Stephen Smalley
                     ` (2 more replies)
  2020-01-09 18:04 ` [PATCH V2 0/1] " Stephen Smalley
  1 sibling, 3 replies; 19+ messages in thread
From: Richard Haines @ 2020-01-09 15:07 UTC (permalink / raw)
  To: selinux; +Cc: omosnace, Richard Haines

Test filesystem permissions and setfscreatecon(3).

From kernels 5.5 filesystem { watch } is also tested.

Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
---
 defconfig                                     |   6 +
 policy/Makefile                               |   4 +
 policy/test_filesystem.te                     | 324 +++++++
 tests/Makefile                                |   7 +
 tests/filesystem/.gitignore                   |  11 +
 tests/filesystem/Makefile                     |  16 +
 tests/filesystem/check_file_context.c         |  75 ++
 tests/filesystem/check_mount_context.c        | 125 +++
 tests/filesystem/create_file.c                |  79 ++
 tests/filesystem/create_file_change_context.c | 146 +++
 tests/filesystem/fanotify_fs.c                |  79 ++
 tests/filesystem/fs_relabel.c                 |  72 ++
 tests/filesystem/grim_reaper.c                |  63 ++
 tests/filesystem/mount.c                      | 130 +++
 tests/filesystem/quotas_test.c                | 143 +++
 tests/filesystem/statfs_test.c                |  65 ++
 tests/filesystem/test                         | 882 ++++++++++++++++++
 tests/filesystem/umount.c                     |  84 ++
 18 files changed, 2311 insertions(+)
 create mode 100644 policy/test_filesystem.te
 create mode 100644 tests/filesystem/.gitignore
 create mode 100644 tests/filesystem/Makefile
 create mode 100644 tests/filesystem/check_file_context.c
 create mode 100644 tests/filesystem/check_mount_context.c
 create mode 100644 tests/filesystem/create_file.c
 create mode 100644 tests/filesystem/create_file_change_context.c
 create mode 100644 tests/filesystem/fanotify_fs.c
 create mode 100644 tests/filesystem/fs_relabel.c
 create mode 100644 tests/filesystem/grim_reaper.c
 create mode 100644 tests/filesystem/mount.c
 create mode 100644 tests/filesystem/quotas_test.c
 create mode 100644 tests/filesystem/statfs_test.c
 create mode 100755 tests/filesystem/test
 create mode 100644 tests/filesystem/umount.c

diff --git a/defconfig b/defconfig
index 3bea332..7cb6a2c 100644
--- a/defconfig
+++ b/defconfig
@@ -88,3 +88,9 @@ CONFIG_TUN=m
 CONFIG_HAVE_PERF_EVENTS=y
 CONFIG_PERF_EVENTS=y
 CONFIG_TRACEPOINTS=y
+
+# Test filesystem permissions.
+# This is not required for SELinux operation itself.
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=0
+CONFIG_QFMT_V2=y
diff --git a/policy/Makefile b/policy/Makefile
index 6f1db03..30896d8 100644
--- a/policy/Makefile
+++ b/policy/Makefile
@@ -114,6 +114,10 @@ TARGETS += test_lockdown.te
 export M4PARAM += -Dlockdown_defined
 endif
 
+ifeq ($(shell grep -q filesystem $(POLDEV)/include/support/all_perms.spt && echo true),true)
+TARGETS += test_filesystem.te
+endif
+
 ifeq (x$(DISTRO),$(filter x$(DISTRO),xRHEL4 xRHEL5 xRHEL6))
 TARGETS:=$(filter-out test_overlayfs.te test_mqueue.te test_ibpkey.te, $(TARGETS))
 endif
diff --git a/policy/test_filesystem.te b/policy/test_filesystem.te
new file mode 100644
index 0000000..2eee1fc
--- /dev/null
+++ b/policy/test_filesystem.te
@@ -0,0 +1,324 @@
+#
+######### Test filesystem permissions policy module ##########
+#
+attribute filesystemdomain;
+
+#################### Create a test file context ######################
+type test_filesystem_filecon_t;
+unconfined_runs_test(test_filesystem_filecon_t)
+
+################# Test all functions ##########################
+type test_filesystem_t;
+domain_type(test_filesystem_t)
+unconfined_runs_test(test_filesystem_t)
+typeattribute test_filesystem_t testdomain;
+typeattribute test_filesystem_t filesystemdomain;
+
+allow test_filesystem_t self:capability { sys_admin };
+allow test_filesystem_t self:filesystem { mount remount quotamod relabelfrom relabelto unmount quotaget };
+allow test_filesystem_t self:dir { mounton add_name write };
+allow test_filesystem_t test_file_t:dir { mounton write remove_name rmdir };
+# Create test file
+allow test_filesystem_t self:dir { add_name write };
+allow test_filesystem_t self:file { create relabelfrom relabelto };
+
+fs_mount_all_fs(test_filesystem_t)
+fs_remount_all_fs(test_filesystem_t)
+fs_unmount_all_fs(test_filesystem_t)
+fs_relabelfrom_all_fs(test_filesystem_t)
+fs_get_xattr_fs_quotas(test_filesystem_t)
+files_search_all(test_filesystem_t)
+# Required for mount opts "rootcontext=system_u:object_r:test_filesystem_t:s0";
+fs_associate(test_filesystem_t)
+fs_getattr_xattr_fs(test_filesystem_t)
+
+# For running quotacheck(8)
+files_type(test_filesystem_t)
+# Update quotas
+fs_set_all_quotas(test_filesystem_t)
+allow test_filesystem_t self:file { quotaon };
+# Create test file and change context:
+fs_associate(test_filesystem_filecon_t)
+allow test_filesystem_t test_filesystem_filecon_t:file { open read getattr relabelto write };
+dontaudit test_filesystem_t kernel_t:process { setsched };
+
+#################### Deny filesystem { getattr } ######################
+type test_filesystem_no_getattr_t;
+domain_type(test_filesystem_no_getattr_t)
+unconfined_runs_test(test_filesystem_no_getattr_t)
+typeattribute test_filesystem_no_getattr_t testdomain;
+typeattribute test_filesystem_no_getattr_t filesystemdomain;
+
+allow test_filesystem_no_getattr_t self:capability { sys_admin };
+fs_mount_all_fs(test_filesystem_no_getattr_t)
+fs_unmount_all_fs(test_filesystem_no_getattr_t)
+fs_relabelfrom_all_fs(test_filesystem_no_getattr_t)
+fs_associate(test_filesystem_no_getattr_t)
+allow test_filesystem_no_getattr_t self:dir { mounton };
+allow test_filesystem_no_getattr_t test_file_t:dir { mounton write remove_name rmdir };
+dontaudit test_filesystem_no_getattr_t kernel_t:process { setsched };
+
+#################### Deny filesystem { remount } ######################
+type test_filesystem_no_remount_t;
+domain_type(test_filesystem_no_remount_t)
+unconfined_runs_test(test_filesystem_no_remount_t)
+typeattribute test_filesystem_no_remount_t testdomain;
+typeattribute test_filesystem_no_remount_t filesystemdomain;
+
+allow test_filesystem_no_remount_t self:capability { sys_admin };
+fs_mount_all_fs(test_filesystem_no_remount_t)
+fs_unmount_all_fs(test_filesystem_no_remount_t)
+fs_relabelfrom_all_fs(test_filesystem_no_remount_t)
+fs_associate(test_filesystem_no_remount_t)
+allow test_filesystem_no_remount_t self:dir { mounton };
+allow test_filesystem_no_remount_t test_file_t:dir { mounton write remove_name rmdir };
+dontaudit test_filesystem_no_remount_t kernel_t:process { setsched };
+
+#################### Deny filesystem { mount } ######################
+type test_filesystem_no_mount_t;
+domain_type(test_filesystem_no_mount_t)
+unconfined_runs_test(test_filesystem_no_mount_t)
+typeattribute test_filesystem_no_mount_t testdomain;
+typeattribute test_filesystem_no_mount_t filesystemdomain;
+
+allow test_filesystem_no_mount_t self:capability { sys_admin };
+fs_relabelfrom_all_fs(test_filesystem_no_mount_t)
+fs_associate(test_filesystem_no_mount_t)
+allow test_filesystem_no_mount_t self:dir { mounton };
+allow test_filesystem_no_mount_t test_file_t:dir { mounton write remove_name rmdir };
+dontaudit test_filesystem_no_mount_t kernel_t:process { setsched };
+
+#################### Deny filesystem { unmount } ######################
+type test_filesystem_no_unmount_t;
+domain_type(test_filesystem_no_unmount_t)
+unconfined_runs_test(test_filesystem_no_unmount_t)
+typeattribute test_filesystem_no_unmount_t testdomain;
+typeattribute test_filesystem_no_unmount_t filesystemdomain;
+
+allow test_filesystem_no_unmount_t self:capability { sys_admin };
+fs_mount_all_fs(test_filesystem_no_unmount_t)
+fs_relabelfrom_all_fs(test_filesystem_no_unmount_t)
+fs_associate(test_filesystem_no_unmount_t)
+allow test_filesystem_no_unmount_t self:dir { mounton };
+allow test_filesystem_no_unmount_t test_file_t:dir { mounton write remove_name rmdir };
+dontaudit test_filesystem_no_unmount_t kernel_t:process { setsched };
+
+#################### Deny filesystem { relabelfrom } ######################
+type test_filesystem_no_relabelfrom_t;
+domain_type(test_filesystem_no_relabelfrom_t)
+unconfined_runs_test(test_filesystem_no_relabelfrom_t)
+typeattribute test_filesystem_no_relabelfrom_t testdomain;
+typeattribute test_filesystem_no_relabelfrom_t filesystemdomain;
+
+allow test_filesystem_no_relabelfrom_t self:capability { sys_admin };
+fs_associate(test_filesystem_no_relabelfrom_t)
+allow test_filesystem_no_relabelfrom_t self:dir { mounton };
+allow test_filesystem_no_relabelfrom_t test_file_t:dir { mounton write remove_name rmdir };
+dontaudit test_filesystem_no_relabelfrom_t kernel_t:process { setsched };
+
+#################### Deny filesystem { relabelto } ######################
+type test_filesystem_no_relabelto_t;
+domain_type(test_filesystem_no_relabelto_t)
+unconfined_runs_test(test_filesystem_no_relabelto_t)
+typeattribute test_filesystem_no_relabelto_t testdomain;
+typeattribute test_filesystem_no_relabelto_t filesystemdomain;
+
+allow test_filesystem_no_relabelto_t self:capability { sys_admin };
+fs_mount_all_fs(test_filesystem_no_relabelto_t)
+fs_relabelfrom_all_fs(test_filesystem_no_relabelto_t)
+fs_associate(test_filesystem_no_relabelto_t)
+allow test_filesystem_no_relabelto_t self:dir { mounton };
+allow test_filesystem_no_relabelto_t test_file_t:dir { mounton write remove_name rmdir };
+dontaudit test_filesystem_no_relabelto_t kernel_t:process { setsched };
+
+#################### Deny filesystem { associate } ######################
+type test_filesystem_no_associate_t;
+type test_filesystem_no_associate1_t;
+domain_type(test_filesystem_no_associate_t)
+unconfined_runs_test(test_filesystem_no_associate_t)
+typeattribute test_filesystem_no_associate_t testdomain;
+typeattribute test_filesystem_no_associate_t filesystemdomain;
+
+allow test_filesystem_no_associate_t self:capability { sys_admin };
+allow test_filesystem_no_associate_t self:filesystem { relabelto mount relabelfrom };
+fs_mount_all_fs(test_filesystem_no_associate_t)
+fs_relabelfrom_all_fs(test_filesystem_no_associate_t)
+allow test_filesystem_no_associate_t self:dir { mounton };
+allow test_filesystem_no_associate_t test_file_t:dir { mounton write remove_name rmdir };
+dontaudit test_filesystem_no_associate_t kernel_t:process { setsched };
+
+########## Deny filesystem { associate } for create file ################
+type test_filesystem_no_associate_file_t;
+domain_type(test_filesystem_no_associate_file_t)
+unconfined_runs_test(test_filesystem_no_associate_file_t)
+typeattribute test_filesystem_no_associate_file_t testdomain;
+typeattribute test_filesystem_no_associate_file_t filesystemdomain;
+
+allow test_filesystem_no_associate_file_t self:capability { sys_admin };
+allow test_filesystem_no_associate_file_t self:filesystem { mount relabelfrom relabelto unmount associate };
+allow test_filesystem_no_associate_file_t self:dir { mounton add_name write };
+allow test_filesystem_no_associate_file_t test_file_t:dir { mounton write remove_name rmdir };
+
+fs_mount_all_fs(test_filesystem_no_associate_file_t)
+fs_unmount_all_fs(test_filesystem_no_associate_file_t)
+fs_relabelfrom_all_fs(test_filesystem_no_associate_file_t)
+fs_associate(test_filesystem_no_associate_file_t)
+fs_getattr_xattr_fs(test_filesystem_no_associate_file_t)
+dontaudit test_filesystem_no_associate_file_t kernel_t:process { setsched };
+
+# Create test file
+allow test_filesystem_no_associate_file_t self:file { create relabelfrom relabelto };
+############ hooks.c may_create() FILESYSTEM__ASSOCIATE #############
+# FOR: neverallow unlabeled_t test_filesystem_no_associate_file_t:filesystem { associate };
+allow test_filesystem_no_associate_file_t unconfined_t:file { open read write };
+allow test_filesystem_no_associate_file_t unlabeled_t:dir { add_name search write };
+allow test_filesystem_no_associate_file_t unlabeled_t:file { create open relabelfrom write };
+############ hooks.c selinux_inode_setxattr() FILESYSTEM__ASSOCIATE ##########
+# FOR: neverallow unconfined_t test_filesystem_no_associate_file_t:filesystem { associate };
+dontaudit unconfined_t test_filesystem_filecon_t:file { getattr read };
+allow test_filesystem_no_associate_file_t unconfined_t:dir { add_name write };
+allow test_filesystem_no_associate_file_t unconfined_t:file { create relabelfrom relabelto };
+
+#################### Deny filesystem { quotamod } ######################
+type test_filesystem_no_quotamod_t;
+domain_type(test_filesystem_no_quotamod_t)
+unconfined_runs_test(test_filesystem_no_quotamod_t)
+typeattribute test_filesystem_no_quotamod_t testdomain;
+typeattribute test_filesystem_no_quotamod_t filesystemdomain;
+
+allow test_filesystem_no_quotamod_t self:capability { sys_admin };
+allow test_filesystem_no_quotamod_t self:filesystem { quotaget relabelto mount unmount};
+fs_mount_all_fs(test_filesystem_no_quotamod_t)
+fs_relabelfrom_all_fs(test_filesystem_no_quotamod_t)
+fs_associate(test_filesystem_no_quotamod_t)
+# Required as $private_path to quota files
+files_search_all(test_filesystem_no_quotamod_t)
+allow test_filesystem_no_quotamod_t self:dir { mounton };
+allow test_filesystem_no_quotamod_t test_file_t:dir { mounton write remove_name rmdir };
+dontaudit test_filesystem_no_quotamod_t kernel_t:process { setsched };
+
+#################### Deny filesystem { quotaget } ######################
+type test_filesystem_no_quotaget_t;
+domain_type(test_filesystem_no_quotaget_t)
+unconfined_runs_test(test_filesystem_no_quotaget_t)
+typeattribute test_filesystem_no_quotaget_t testdomain;
+typeattribute test_filesystem_no_quotaget_t filesystemdomain;
+
+allow test_filesystem_no_quotaget_t self:capability { sys_admin };
+allow test_filesystem_no_quotaget_t self:filesystem { quotamod relabelto mount unmount relabelfrom };
+allow test_filesystem_no_quotaget_t self:dir { mounton };
+allow test_filesystem_no_quotaget_t test_file_t:dir { mounton write remove_name rmdir };
+allow test_filesystem_no_quotaget_t self:file { quotaon };
+fs_mount_all_fs(test_filesystem_no_quotaget_t)
+fs_relabelfrom_all_fs(test_filesystem_no_quotaget_t)
+fs_associate(test_filesystem_no_quotaget_t)
+# Required as $private_path to quota files
+files_search_all(test_filesystem_no_quotaget_t)
+# For running quotacheck(8)
+files_type(test_filesystem_no_quotaget_t)
+dontaudit test_filesystem_no_quotaget_t kernel_t:process { setsched };
+
+#################### Deny filesystem { watch } ######################
+type test_filesystem_no_watch_t;
+domain_type(test_filesystem_no_watch_t)
+unconfined_runs_test(test_filesystem_no_watch_t)
+typeattribute test_filesystem_no_watch_t testdomain;
+typeattribute test_filesystem_no_watch_t filesystemdomain;
+
+allow test_filesystem_no_watch_t self:capability { sys_admin };
+allow test_filesystem_no_watch_t self:filesystem { associate relabelto mount unmount relabelfrom };
+allow test_filesystem_no_watch_t self:dir { mounton };
+allow test_filesystem_no_watch_t test_file_t:dir { mounton write remove_name rmdir };
+fs_mount_all_fs(test_filesystem_no_watch_t)
+fs_relabelfrom_all_fs(test_filesystem_no_watch_t)
+fs_associate(test_filesystem_no_watch_t)
+dontaudit test_filesystem_no_watch_t kernel_t:process { setsched };
+
+################# Test process { setfscreate } #############
+type test_setfscreatecon_t;
+domain_type(test_setfscreatecon_t)
+unconfined_runs_test(test_setfscreatecon_t)
+typeattribute test_setfscreatecon_t testdomain;
+typeattribute test_setfscreatecon_t filesystemdomain;
+
+allow test_setfscreatecon_t self:capability { sys_admin };
+allow test_setfscreatecon_t self:process { setfscreate };
+
+# Set new context on fs:
+type test_setfscreatecon_newcon_t;
+domain_type(test_setfscreatecon_newcon_t)
+typeattribute test_setfscreatecon_newcon_t testdomain;
+
+################# deny process { setfscreate } #############
+type test_no_setfscreatecon_t;
+domain_type(test_no_setfscreatecon_t)
+unconfined_runs_test(test_no_setfscreatecon_t)
+typeattribute test_no_setfscreatecon_t testdomain;
+typeattribute test_no_setfscreatecon_t filesystemdomain;
+
+allow test_no_setfscreatecon_t self:capability { sys_admin };
+# neverallow test_no_setfscreatecon_t self:process { setfscreate };
+
+################# Test fscontext= ##########################
+type test_filesystem_fscontext_t;
+domain_type(test_filesystem_fscontext_t)
+unconfined_runs_test(test_filesystem_fscontext_t)
+typeattribute test_filesystem_fscontext_t testdomain;
+typeattribute test_filesystem_fscontext_t filesystemdomain;
+
+allow test_filesystem_fscontext_t self:capability { sys_admin };
+allow test_filesystem_fscontext_t self:filesystem { associate mount relabelfrom relabelto unmount };
+allow test_filesystem_fscontext_t self:dir { mounton add_name write };
+allow test_filesystem_fscontext_t test_file_t:dir { mounton write remove_name rmdir };
+# Create test file
+allow test_filesystem_fscontext_t self:dir { add_name write };
+allow test_filesystem_fscontext_t self:file { create relabelfrom relabelto };
+allow test_filesystem_fscontext_t test_filesystem_filecon_t:file { relabelto };
+allow test_filesystem_filecon_t test_filesystem_fscontext_t:filesystem { associate };
+allow test_filesystem_fscontext_t test_filesystem_filecon_t:file { open getattr read write };
+
+fs_mount_all_fs(test_filesystem_fscontext_t)
+fs_unmount_all_fs(test_filesystem_fscontext_t)
+fs_relabelfrom_all_fs(test_filesystem_fscontext_t)
+files_search_all(test_filesystem_fscontext_t)
+
+########### Test context=, rootcontext= and defcontext #################
+type test_filesystem_context_t;
+domain_type(test_filesystem_context_t)
+unconfined_runs_test(test_filesystem_context_t)
+typeattribute test_filesystem_context_t testdomain;
+typeattribute test_filesystem_context_t filesystemdomain;
+
+allow test_filesystem_context_t self:capability { sys_admin };
+allow test_filesystem_context_t self:filesystem { associate mount relabelfrom relabelto unmount };
+allow test_filesystem_context_t self:dir { mounton add_name write };
+allow test_filesystem_context_t test_file_t:dir { mounton write remove_name rmdir };
+# Create test file
+allow test_filesystem_context_t self:dir { add_name write };
+allow test_filesystem_context_t self:file { create relabelfrom relabelto };
+allow test_filesystem_context_t test_filesystem_filecon_t:file { open getattr read write relabelto };
+allow test_filesystem_filecon_t test_filesystem_context_t:filesystem { associate };
+
+fs_mount_all_fs(test_filesystem_context_t)
+fs_unmount_all_fs(test_filesystem_context_t)
+fs_relabelfrom_all_fs(test_filesystem_context_t)
+files_search_all(test_filesystem_context_t)
+fs_associate(test_filesystem_context_t)
+allow test_filesystem_context_t test_file_t:dir { add_name };
+dontaudit test_filesystem_context_t kernel_t:process { setsched };
+
+# For testing rootcontext= Set mountpoint to unlabeled first
+allow test_filesystem_context_t test_file_t:dir { relabelfrom };
+allow test_filesystem_context_t unlabeled_t:dir { mounton relabelto };
+
+# For testing defcontext=
+allow test_filesystem_context_t test_filesystem_filecon_t:dir { search };
+allow test_filesystem_fscontext_t test_filesystem_context_t:dir { add_name search write };
+allow test_filesystem_fscontext_t test_filesystem_context_t:file { create getattr open write };
+dontaudit unconfined_t test_filesystem_filecon_t:dir { read search };
+
+#
+########### Allow these domains to be entered from sysadm domain ############
+#
+miscfiles_domain_entry_test_files(filesystemdomain)
+userdom_sysadm_entry_spec_domtrans_to(filesystemdomain)
diff --git a/tests/Makefile b/tests/Makefile
index e19ea2f..a1478f1 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -91,6 +91,13 @@ ifeq ($(shell grep -q lockdown $(POLDEV)/include/support/all_perms.spt && echo t
 SUBDIRS += lockdown
 endif
 
+ifeq ($(shell grep -q filesystem $(POLDEV)/include/support/all_perms.spt && echo true),true)
+SUBDIRS += filesystem
+ifeq ($(shell grep -q all_filesystem_perms.*watch $(POLDEV)/include/support/all_perms.spt && echo true),true)
+export CFLAGS += -DHAVE_FS_WATCH_PERM
+endif
+endif
+
 ifeq ($(DISTRO),RHEL4)
     SUBDIRS:=$(filter-out bounds dyntrace dyntrans inet_socket mmap nnp_nosuid overlay unix_socket, $(SUBDIRS))
 endif
diff --git a/tests/filesystem/.gitignore b/tests/filesystem/.gitignore
new file mode 100644
index 0000000..5ac18d0
--- /dev/null
+++ b/tests/filesystem/.gitignore
@@ -0,0 +1,11 @@
+mount
+umount
+quotas_test
+statfs_test
+fanotify_fs
+create_file_change_context
+fs_relabel
+check_file_context
+check_mount_context
+create_file
+grim_reaper
diff --git a/tests/filesystem/Makefile b/tests/filesystem/Makefile
new file mode 100644
index 0000000..d2fad63
--- /dev/null
+++ b/tests/filesystem/Makefile
@@ -0,0 +1,16 @@
+# Required for local building
+#export CFLAGS += -DHAVE_FS_WATCH_PERM
+
+TARGETS = mount umount quotas_test statfs_test create_file_change_context \
+fs_relabel check_file_context grim_reaper check_mount_context create_file
+
+LDLIBS += -lselinux
+
+ifneq (,$(findstring -DHAVE_FS_WATCH_PERM,$(CFLAGS)))
+	TARGETS += fanotify_fs
+endif
+
+all: $(TARGETS)
+
+clean:
+	rm -f $(TARGETS)
diff --git a/tests/filesystem/check_file_context.c b/tests/filesystem/check_file_context.c
new file mode 100644
index 0000000..1380f16
--- /dev/null
+++ b/tests/filesystem/check_file_context.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <linux/unistd.h>
+#include <selinux/selinux.h>
+
+static void print_usage(char *progname)
+{
+	fprintf(stderr,
+		"usage:  %s [-v] -f -e -n\n"
+		"Where:\n\t"
+		"-f  File to check its context\n\t"
+		"-e  Expected context\n\t"
+		"-v  Print information.\n", progname);
+	exit(-1);
+}
+
+int main(int argc, char **argv)
+{
+	int opt, result, fd;
+	char *context = NULL, *expected = NULL, *file = NULL;
+	bool verbose = false;
+
+	while ((opt = getopt(argc, argv, "f:e:v")) != -1) {
+		switch (opt) {
+		case 'f':
+			file = optarg;
+			break;
+		case 'e':
+			expected = optarg;
+			break;
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			print_usage(argv[0]);
+		}
+	}
+
+	if (!file || !expected)
+		print_usage(argv[0]);
+
+	fd = open(file, O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "open(2) Failed: %s\n", strerror(errno));
+		return -1;
+	}
+
+	result = fgetfilecon(fd, &context);
+	if (result < 0) {
+		fprintf(stderr, "fgetfilecon(3) Failed: %s\n",
+			strerror(errno));
+		result = -1;
+		goto err;
+	}
+	result = 0;
+
+	if (strcmp(expected, context)) {
+		fprintf(stderr, "File context error, expected:\n\t%s\ngot:\n\t%s\n",
+			expected, context);
+		result = -1;
+	} else {
+		if (verbose)
+			printf("Pass - File contexts match: %s\n", context);
+	}
+err:
+	free(context);
+	close(fd);
+
+	return result;
+}
diff --git a/tests/filesystem/check_mount_context.c b/tests/filesystem/check_mount_context.c
new file mode 100644
index 0000000..e523cb3
--- /dev/null
+++ b/tests/filesystem/check_mount_context.c
@@ -0,0 +1,125 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <linux/unistd.h>
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+
+static void print_usage(char *progname)
+{
+	fprintf(stderr,
+		"usage:  %s [-v] -m [-e] -r\n"
+		"Where:\n\t"
+		"-m  Mountpoint\n\t"
+		"-e  Expected MP context\n\t"
+		"-r  Reset MP context to 'unlabeled_t'\n\t"
+		"-v  Print information.\n", progname);
+	exit(-1);
+}
+
+int main(int argc, char **argv)
+{
+	int opt, result;
+	char *context = NULL, *expected = NULL, *mount = NULL, *newcon = NULL;
+	bool verbose = false, reset = false;
+	const char *type = "unlabeled_t";
+	context_t con_t;
+
+	while ((opt = getopt(argc, argv, "m:e:rv")) != -1) {
+		switch (opt) {
+		case 'm':
+			mount = optarg;
+			break;
+		case 'e':
+			expected = optarg;
+			break;
+		case 'r':
+			reset = true;
+			break;
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			print_usage(argv[0]);
+		}
+	}
+
+	if (!mount)
+		print_usage(argv[0]);
+
+	result = getfilecon(mount, &context);
+	if (result < 0) {
+		fprintf(stderr, "getfilecon(3) Failed: %s\n", strerror(errno));
+		result = -1;
+		goto err;
+	}
+	if (verbose)
+		printf("Current MP context: %s\n", context);
+
+	result = 0;
+
+	if (reset) {
+		/* Set context to unlabeled_t */
+		con_t = context_new(context);
+		if (!con_t) {
+			fprintf(stderr, "Unable to create context structure\n");
+			result = -1;
+			goto err;
+		}
+
+		if (context_type_set(con_t, type)) {
+			fprintf(stderr, "Unable to set new type\n");
+			free(con_t);
+			result = -1;
+			goto err;
+		}
+
+		newcon = context_str(con_t);
+		free(con_t);
+		if (!newcon) {
+			fprintf(stderr, "Unable to obtain new context string\n");
+			result = -1;
+			goto err;
+		}
+
+		result = setfilecon(mount, newcon);
+		free(newcon);
+		if (result < 0) {
+			fprintf(stderr, "setfilecon(3) Failed: %s\n",
+				strerror(errno));
+			result = -1;
+			goto err;
+		}
+
+		free(context);
+
+		result = getfilecon(mount, &context);
+		if (result < 0) {
+			fprintf(stderr, "getfilecon(3) Failed: %s\n", strerror(errno));
+			return result;
+		}
+		result = 0;
+
+		if (verbose)
+			printf("Set new MP context: %s\n", context);
+
+	} else {
+		if (strcmp(expected, context)) {
+			fprintf(stderr, "Mount context error, expected:\n\t%s\ngot:\n\t%s\n",
+				expected, context);
+			result = -1;
+		} else {
+			if (verbose)
+				printf("Pass - Mountpoint contexts match: %s\n",
+				       context);
+		}
+	}
+
+err:
+	free(context);
+	return result;
+}
diff --git a/tests/filesystem/create_file.c b/tests/filesystem/create_file.c
new file mode 100644
index 0000000..3d73067
--- /dev/null
+++ b/tests/filesystem/create_file.c
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <linux/unistd.h>
+#include <selinux/selinux.h>
+
+static void print_usage(char *progname)
+{
+	fprintf(stderr,
+		"usage:  %s [-v] -f\n"
+		"Where:\n\t"
+		"-f  File to create\n\t"
+		"-v  Print information.\n", progname);
+	exit(-1);
+}
+
+int main(int argc, char **argv)
+{
+	int opt, result, fd, save_err;
+	char *context, *file = NULL;
+	bool verbose = false;
+
+	while ((opt = getopt(argc, argv, "f:v")) != -1) {
+		switch (opt) {
+		case 'f':
+			file = optarg;
+			break;
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			print_usage(argv[0]);
+		}
+	}
+
+	if (!file)
+		print_usage(argv[0]);
+
+	if (verbose) {
+		result = getcon(&context);
+		if (result < 0) {
+			fprintf(stderr, "Failed to obtain process context\n");
+			exit(-1);
+		}
+		printf("Process context:\n\t%s\n", context);
+		free(context);
+	}
+
+	fd = creat(file, O_RDWR);
+	save_err = errno;
+	if (fd < 0) {
+		fprintf(stderr, "creat(2) Failed: %s\n", strerror(errno));
+		return save_err;
+	}
+
+	context = NULL;
+	result = fgetfilecon(fd, &context);
+	if (result < 0) {
+		fprintf(stderr, "fgetfilecon(3) Failed: %s\n",
+			strerror(errno));
+		result = -1;
+		goto err;
+	}
+	result = 0;
+
+	if (verbose)
+		printf("File context is: %s\n", context);
+
+err:
+	free(context);
+	close(fd);
+
+	return result;
+}
diff --git a/tests/filesystem/create_file_change_context.c b/tests/filesystem/create_file_change_context.c
new file mode 100644
index 0000000..71531f4
--- /dev/null
+++ b/tests/filesystem/create_file_change_context.c
@@ -0,0 +1,146 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <linux/unistd.h>
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+
+static void print_usage(char *progname)
+{
+	fprintf(stderr,
+		"usage:  %s [-v] -t -f\n"
+		"Where:\n\t"
+		"-t  Type for context of created file\n\t"
+		"-f  File to create\n\t"
+		"-v  Print information.\n", progname);
+	exit(-1);
+}
+
+int main(int argc, char **argv)
+{
+	int opt, result, fd, save_err;
+	char *newfcon = NULL, *orgfcon = NULL, *type = NULL, *file = NULL;
+	char *context;
+	bool verbose = false;
+	context_t con_t;
+
+	while ((opt = getopt(argc, argv, "t:f:v")) != -1) {
+		switch (opt) {
+		case 't':
+			type = optarg;
+			break;
+		case 'f':
+			file = optarg;
+			break;
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			print_usage(argv[0]);
+		}
+	}
+
+	if (!type || !file)
+		print_usage(argv[0]);
+
+	if (verbose) {
+		result = getcon(&context);
+		if (result < 0) {
+			fprintf(stderr, "Failed to obtain process context\n");
+			exit(-1);
+		}
+
+		printf("Process context:\n\t%s\n", context);
+		free(context);
+	}
+
+	/* hooks.c may_create() FILESYSTEM__ASSOCIATE */
+	fd = creat(file, O_RDWR);
+	save_err = errno;
+	if (fd < 0) {
+		fprintf(stderr, "creat(2) Failed: %s\n", strerror(errno));
+		return save_err;
+	}
+	if (verbose)
+		printf("Created file: %s\n", file);
+
+	result = fgetfilecon(fd, &orgfcon);
+	if (result < 0) {
+		fprintf(stderr, "fgetfilecon(3) Failed: %s\n",
+			strerror(errno));
+		close(fd);
+		return -1;
+	}
+	if (verbose)
+		printf("Current file context is: %s\n", orgfcon);
+
+	/* Build new file context */
+	con_t = context_new(orgfcon);
+	if (!con_t) {
+		fprintf(stderr, "Unable to create context structure\n");
+		result = -1;
+		goto err;
+	}
+
+	if (context_type_set(con_t, type)) {
+		fprintf(stderr, "Unable to set new type\n");
+		free(con_t);
+		result = -1;
+		goto err;
+	}
+
+	newfcon = context_str(con_t);
+	free(con_t);
+	if (!newfcon) {
+		fprintf(stderr, "Unable to obtain new context string\n");
+		result = -1;
+		goto err;
+	}
+
+	/* hooks.c selinux_inode_setxattr() FILESYSTEM__ASSOCIATE */
+	result = fsetfilecon(fd, newfcon);
+	save_err = errno;
+	close(fd);
+	if (result < 0) {
+		fprintf(stderr, "fsetfilecon(3) Failed: %s\n",
+			strerror(errno));
+		result = save_err;
+		goto err1;
+	}
+
+	fd = open(file, O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "open(2) Failed: %s\n", strerror(errno));
+		result = -1;
+		goto err1;
+	}
+
+	result = fgetfilecon(fd, &context);
+	if (result < 0) {
+		fprintf(stderr, "fgetfilecon(3) Failed: %s\n",
+			strerror(errno));
+		result = -1;
+		goto err1;
+	}
+	if (verbose)
+		printf("New file context is: %s\n", context);
+
+	result = 0;
+	if (strcmp(newfcon, context)) {
+		fprintf(stderr, "File context error, expected:\n\t%s\ngot:\n\t%s\n",
+			newfcon, context);
+		result = -1;
+	}
+
+err:
+	free(orgfcon);
+err1:
+	free(newfcon);
+	close(fd);
+
+	return result;
+}
diff --git a/tests/filesystem/fanotify_fs.c b/tests/filesystem/fanotify_fs.c
new file mode 100644
index 0000000..1f8f165
--- /dev/null
+++ b/tests/filesystem/fanotify_fs.c
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <sys/fanotify.h>
+#include <selinux/selinux.h>
+
+#ifndef FAN_MARK_FILESYSTEM
+#define FAN_MARK_FILESYSTEM	0x00000100
+#endif
+
+static void print_usage(char *progname)
+{
+	fprintf(stderr,
+		"usage:  %s [-v] -t\n"
+		"Where:\n\t"
+		"-t  Target path\n\t"
+		"-v  Print information.\n", progname);
+	exit(-1);
+}
+
+int main(int argc, char *argv[])
+{
+	int mask = FAN_OPEN, flags = FAN_MARK_ADD | FAN_MARK_FILESYSTEM;
+	int fd, result, opt, save_err;
+	char *context, *tgt = NULL;
+	bool verbose = false;
+
+	while ((opt = getopt(argc, argv, "t:v")) != -1) {
+		switch (opt) {
+		case 't':
+			tgt = optarg;
+			break;
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			print_usage(argv[0]);
+		}
+	}
+
+	if (!tgt)
+		print_usage(argv[0]);
+
+	if (verbose) {
+		result = getcon(&context);
+		if (result < 0) {
+			fprintf(stderr, "Failed to obtain process context\n");
+			exit(-1);
+		}
+		printf("Process context:\n\t%s\n", context);
+		free(context);
+	}
+
+	fd = fanotify_init(FAN_CLASS_CONTENT, O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "fanotify_init(2) Failed: %s\n",
+			strerror(errno));
+		exit(-1);
+	}
+
+	result = fanotify_mark(fd, flags, mask, AT_FDCWD, tgt);
+	save_err = errno;
+	if (result < 0) {
+		fprintf(stderr, "fanotify_mark(2) Failed: %s\n",
+			strerror(errno));
+		close(fd);
+		return save_err;
+	}
+
+	if (verbose)
+		printf("Set fanotify_mark(2) on filesystem: %s\n", tgt);
+
+	close(fd);
+	return 0;
+}
diff --git a/tests/filesystem/fs_relabel.c b/tests/filesystem/fs_relabel.c
new file mode 100644
index 0000000..25b1781
--- /dev/null
+++ b/tests/filesystem/fs_relabel.c
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <linux/unistd.h>
+#include <selinux/selinux.h>
+
+static void print_usage(char *progname)
+{
+	fprintf(stderr,
+		"usage:  %s [-v] -n\n"
+		"Where:\n\t"
+		"-n  New fs context\n\t"
+		"-v  Print information.\n", progname);
+	exit(-1);
+}
+
+int main(int argc, char **argv)
+{
+	int opt, result, save_err;
+	char *context, *fscreate_con, *newcon = NULL;
+	bool verbose = false;
+
+	while ((opt = getopt(argc, argv, "n:v")) != -1) {
+		switch (opt) {
+		case 'n':
+			newcon = optarg;
+			break;
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			print_usage(argv[0]);
+		}
+	}
+
+	if (!newcon)
+		print_usage(argv[0]);
+
+	if (verbose) {
+		result = getcon(&context);
+		if (result < 0) {
+			fprintf(stderr, "Failed to obtain process context\n");
+			exit(-1);
+		}
+		printf("Process context:\n\t%s\n", context);
+		free(context);
+	}
+
+	result = setfscreatecon(newcon);
+	save_err = errno;
+	if (result < 0) {
+		fprintf(stderr, "Failed setfscreatecon(3): %s\n",
+			strerror(errno));
+		return save_err;
+	}
+
+	result = getfscreatecon(&fscreate_con);
+	if (result < 0) {
+		fprintf(stderr, "Failed getfscreatecon(3): %s\n",
+			strerror(errno));
+		exit(-1);
+	}
+	if (verbose)
+		printf("New fscreate context: %s\n", fscreate_con);
+
+	free(fscreate_con);
+	return 0;
+}
diff --git a/tests/filesystem/grim_reaper.c b/tests/filesystem/grim_reaper.c
new file mode 100644
index 0000000..0105ab6
--- /dev/null
+++ b/tests/filesystem/grim_reaper.c
@@ -0,0 +1,63 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <sys/mount.h>
+#include <selinux/selinux.h>
+
+#define WAIT_COUNT 60
+#define USLEEP_TIME 10000
+
+/* Remove any mounts associated with the loop device in argv[1] */
+int main(int argc, char *argv[])
+{
+	FILE *fp;
+	size_t len;
+	ssize_t num;
+	int index = 0, i, result = 0;
+	char *mount_info[2];
+	char *buf = NULL, *item;
+
+	if (!argv[1])
+		return -1;
+
+	fp = fopen("/proc/mounts", "re");
+	if (!fp) {
+		fprintf(stderr, "Failed to open /proc/mounts: %s\n",
+			strerror(errno));
+		return -1;
+	}
+
+	while ((num = getline(&buf, &len, fp)) != -1) {
+		index = 0;
+		item = strtok(buf, " ");
+		while (item != NULL) {
+			mount_info[index] = item;
+			index++;
+			if (index == 2)
+				break;
+			item = strtok(NULL, " ");
+		}
+
+		if (strcmp(mount_info[0], argv[1]) == 0) {
+			for (i = 0; i < WAIT_COUNT; i++) {
+				result = umount(mount_info[1]);
+				if (!result)
+					break;
+
+				if (errno != EBUSY) {
+					fprintf(stderr, "Failed umount(2): %s\n",
+						strerror(errno));
+					break;
+				}
+				usleep(USLEEP_TIME);
+			}
+		}
+	}
+
+	free(buf);
+	fclose(fp);
+	return result;
+}
diff --git a/tests/filesystem/mount.c b/tests/filesystem/mount.c
new file mode 100644
index 0000000..034f0ec
--- /dev/null
+++ b/tests/filesystem/mount.c
@@ -0,0 +1,130 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <sys/mount.h>
+#include <selinux/selinux.h>
+
+static void print_usage(char *progname)
+{
+	fprintf(stderr,
+		"usage:  %s [-s src] -t tgt [-f fs_type] [-o options] [-bmprv]\n"
+		"Where:\n\t"
+		"-s  Source path\n\t"
+		"-t  Target path\n\t"
+		"-f  Filesystem type\n\t"
+		"-o  Options list (comma separated list)\n\t"
+		"Zero or one of the following flags:\n\t"
+		"\t-b  MS_BIND\n\t"
+		"\t-m  MS_MOVE\n\t"
+		"\t-p  MS_PRIVATE\n\t"
+		"\t-r  MS_REMOUNT\n\t"
+		"-v  Print information.\n", progname);
+	exit(-1);
+}
+
+static int ck_mount(char *mntpoint)
+{
+	int result = 0;
+	FILE *fp;
+	size_t len;
+	ssize_t num;
+	char *buf = NULL;
+
+	fp = fopen("/proc/mounts", "re");
+	if (fp == NULL) {
+		fprintf(stderr, "Failed to open /proc/mounts: %s\n",
+			strerror(errno));
+		return -1;
+	}
+
+	while ((num = getline(&buf, &len, fp)) != -1) {
+		if (strstr(buf, mntpoint) != NULL) {
+			result = 1;
+			break;
+		}
+	}
+
+	free(buf);
+	fclose(fp);
+	return result;
+}
+
+int main(int argc, char *argv[])
+{
+	int opt, result, save_err, flags = 0;
+	char *context, *src = NULL, *tgt = NULL, *fs_type = NULL, *opts = NULL;
+	bool verbose = false;
+
+	while ((opt = getopt(argc, argv, "s:t:f:o:pbmrv")) != -1) {
+		switch (opt) {
+		case 's':
+			src = optarg;
+			break;
+		case 't':
+			tgt = optarg;
+			break;
+		case 'f':
+			fs_type = optarg;
+			break;
+		case 'o':
+			opts = optarg;
+			break;
+		case 'b':
+			flags = MS_BIND;
+			break;
+		case 'p':
+			flags = MS_PRIVATE;
+			break;
+		case 'm':
+			flags = MS_MOVE;
+			break;
+		case 'r':
+			flags = MS_REMOUNT;
+			break;
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			print_usage(argv[0]);
+		}
+	}
+
+	if (!tgt)
+		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);
+	}
+
+	if (verbose)
+		printf("Mounting\n\tsrc: %s\n\ttgt: %s\n\tfs_type: %s flags: 0x%x\n\topts: %s\n",
+		       src, tgt, fs_type, flags, opts);
+
+	result = mount(src, tgt, fs_type, flags, opts);
+	save_err = errno;
+	if (result < 0) {
+		fprintf(stderr, "Failed mount(2): %s\n", strerror(errno));
+		return save_err;
+	}
+
+	if (flags == MS_MOVE) {
+		if (!ck_mount(src) && ck_mount(tgt)) {
+			if (verbose)
+				printf("MS_MOVE: Moved mountpoint\n");
+		} else {
+			fprintf(stderr, "MS_MOVE: Move mountpoint failed\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
diff --git a/tests/filesystem/quotas_test.c b/tests/filesystem/quotas_test.c
new file mode 100644
index 0000000..91ee469
--- /dev/null
+++ b/tests/filesystem/quotas_test.c
@@ -0,0 +1,143 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <sys/quota.h>
+#include <selinux/selinux.h>
+
+/*
+ * This is required so that the code compiles on RHEL/CentOS 7 and below.
+ * There <sys/quota.h> doesn't contain the definition and it conflicts
+ * with <linux/quota.h>
+ */
+#ifndef QFMT_VFS_V0
+#define QFMT_VFS_V0 2
+#endif
+
+static void print_usage(char *progname)
+{
+	fprintf(stderr,
+		"usage:  %s -s src -t tgt\n"
+		"Where:\n\t"
+		"-s  Source path (e.g. /dev/loop0)\n\t"
+		"-t  Target quota file (Full path with either 'aquota.user'\n\t"
+		"    or 'aquota.group' appended)\n\t"
+		"-v  Print information.\n", progname);
+	exit(-1);
+}
+
+int main(int argc, char *argv[])
+{
+	int opt, result, qcmd, save_err, test_id = geteuid();
+	char *context, *src = NULL, *tgt = NULL;
+	bool verbose = false;
+	char fmt_buf[2];
+
+	while ((opt = getopt(argc, argv, "s:t:v")) != -1) {
+		switch (opt) {
+		case 's':
+			src = optarg;
+			break;
+		case 't':
+			tgt = optarg;
+			break;
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			print_usage(argv[0]);
+		}
+	}
+
+	if (!src || !tgt)
+		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);
+	}
+
+	if (strstr(tgt, "aquota.user") != NULL) {
+		qcmd = QCMD(Q_QUOTAON, USRQUOTA);
+		result = quotactl(qcmd, src, QFMT_VFS_V0, tgt);
+		save_err = errno;
+		if (result < 0) {
+			fprintf(stderr, "quotactl(Q_QUOTAON, USRQUOTA) Failed: %s\n",
+				strerror(errno));
+			return save_err;
+		}
+		if (verbose)
+			printf("User Quota - ON\n");
+
+		qcmd = QCMD(Q_GETFMT, USRQUOTA);
+		result = quotactl(qcmd, src, test_id, fmt_buf);
+		save_err = errno;
+		if (result < 0) {
+			fprintf(stderr, "quotactl(Q_GETFMT, USRQUOTA) Failed: %s\n",
+				strerror(errno));
+			return save_err;
+		}
+		if (verbose)
+			printf("User Format: 0x%x\n", fmt_buf[0]);
+
+		qcmd = QCMD(Q_QUOTAOFF, USRQUOTA);
+		result = quotactl(qcmd, src, QFMT_VFS_V0, tgt);
+		save_err = errno;
+		if (result < 0) {
+			fprintf(stderr, "quotactl(Q_QUOTAOFF, USRQUOTA) Failed: %s\n",
+				strerror(errno));
+			return save_err;
+		}
+		if (verbose)
+			printf("User Quota - OFF\n");
+
+		return 0;
+
+	} else if (strstr(tgt, "aquota.group") != NULL) {
+		qcmd = QCMD(Q_QUOTAON, GRPQUOTA);
+		result = quotactl(qcmd, src, QFMT_VFS_V0, tgt);
+		save_err = errno;
+		if (result < 0) {
+			fprintf(stderr, "quotactl(Q_QUOTAON, GRPQUOTA) Failed: %s\n",
+				strerror(errno));
+			return save_err;
+		}
+		if (verbose)
+			printf("Group Quota - ON\n");
+
+		qcmd = QCMD(Q_GETFMT, GRPQUOTA);
+		result = quotactl(qcmd, src, test_id, fmt_buf);
+		save_err = errno;
+		if (result < 0) {
+			fprintf(stderr, "quotactl(Q_GETFMT, GRPQUOTA) Failed: %s\n",
+				strerror(errno));
+			return save_err;
+		}
+		if (verbose)
+			printf("Group Format: 0x%x\n", fmt_buf[0]);
+
+		qcmd = QCMD(Q_QUOTAOFF, GRPQUOTA);
+		result = quotactl(qcmd, src, QFMT_VFS_V0, tgt);
+		save_err = errno;
+		if (result < 0) {
+			fprintf(stderr, "quotactl(Q_QUOTAOFF, GRPQUOTA) Failed: %s\n",
+				strerror(errno));
+			return save_err;
+		}
+		if (verbose)
+			printf("Group Quota - OFF\n");
+
+		return 0;
+	}
+
+	fprintf(stderr, "Required %s to specify 'aquota.user' or 'aquota.group' file\n",
+		tgt);
+	return -1;
+}
diff --git a/tests/filesystem/statfs_test.c b/tests/filesystem/statfs_test.c
new file mode 100644
index 0000000..5de49b1
--- /dev/null
+++ b/tests/filesystem/statfs_test.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <sys/statfs.h>
+#include <selinux/selinux.h>
+
+static void print_usage(char *progname)
+{
+	fprintf(stderr,
+		"usage:  %s [-v] -t\n"
+		"Where:\n\t"
+		"-t  Target path\n\t"
+		"-v  Print information.\n", progname);
+	exit(-1);
+}
+
+int main(int argc, char *argv[])
+{
+	int opt, result, save_err;
+	char *context, *tgt = NULL;
+	bool verbose = false;
+	struct statfs statfs_t;
+
+	while ((opt = getopt(argc, argv, "t:v")) != -1) {
+		switch (opt) {
+		case 't':
+			tgt = optarg;
+			break;
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			print_usage(argv[0]);
+		}
+	}
+
+	if (!tgt)
+		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);
+	}
+
+	result = statfs(tgt, &statfs_t);
+	save_err = errno;
+	if (result < 0) {
+		fprintf(stderr, "statfs(2) Failed: %s\n", strerror(errno));
+		return save_err;
+	}
+
+	if (verbose)
+		printf("statfs(2) returned magic filesystem: 0x%lx\n",
+		       statfs_t.f_type);
+
+	return 0;
+}
diff --git a/tests/filesystem/test b/tests/filesystem/test
new file mode 100755
index 0000000..fa3f91a
--- /dev/null
+++ b/tests/filesystem/test
@@ -0,0 +1,882 @@
+#!/usr/bin/perl
+use Test::More;
+
+BEGIN {
+    $basedir = $0;
+    $basedir =~ s|(.*)/[^/]*|$1|;
+
+    $test_count = 63;
+
+    # Allow info to be shown.
+    $v = $ARGV[0];
+    if ($v) {
+        if ( $v ne "-v" ) {
+            plan skip_all => "Invalid option (use -v)";
+        }
+    }
+    else {
+        $v = " ";
+    }
+
+    # From kernel 5.5 support for fanotify(7) with filesystem { watch }
+    $kvercur = `uname -r`;
+    chomp($kvercur);
+    $kverminstream = "5.5";
+
+    $result = `$basedir/../kvercmp $kvercur $kverminstream`;
+    if ( $result > 0 && -e "$basedir/fanotify_fs" ) {
+        $test_watch = 1;
+        $test_count += 4;
+    }
+
+    plan tests => $test_count;
+}
+
+# mount(2) MS_BIND | MS_PRIVATE requires an absolute path to a private mount
+# point before MS_MOVE
+$cwd = `pwd 2>/dev/null`;
+chomp($cwd);
+$private_path = "$cwd";
+if ( $basedir eq "." ) {
+    $private_path = "$cwd/mntpoint";
+}
+else {
+    $private_path = "$cwd/$basedir/mntpoint";
+}
+
+# Set initial filesystem type
+$fs_type = "ext4";
+
+# For list of devices used
+$device_count = 0;
+
+# udisks(8) can cause intermittent failures for some '*context=' tests.
+# To avoid this the udisks(8) daemon is stopped if running, then
+# restarted on exit.
+$udisks2_status = 0;
+
+sub udisks2_stop {
+    if ( -e "/usr/bin/systemctl" ) {
+        $u_status_cmd = "/usr/bin/systemctl status udisks2 >& /dev/null";
+        $u_stop_cmd   = "/usr/bin/systemctl stop udisks2 >& /dev/null";
+    }
+    elsif ( -e "/usr/sbin/service" ) {
+        $u_status_cmd = "/usr/sbin/service udisks2 status >& /dev/null";
+        $u_stop_cmd   = "/usr/sbin/service udisks2 stop >& /dev/null";
+    }
+
+    if ($u_status_cmd) {
+        $result         = system("$u_status_cmd");
+        $udisks2_status = $result >> 8;
+        if ( $udisks2_status eq 0 ) {
+            print "Stopping udisks2 service for these tests.\n";
+            system("$u_stop_cmd");
+            $udisks2_status = 3;
+        }
+        else {
+            $udisks2_status = 4;
+        }
+    }
+}
+
+sub udisks2_restart {
+    if ( $udisks2_status eq 3 ) {
+        print "Restarting udisks2 service.\n";
+        if ( -e "/usr/bin/systemctl" ) {
+            system("/usr/bin/systemctl start udisks2 >& /dev/null");
+        }
+        elsif ( -e "/usr/sbin/service" ) {
+            system("/usr/sbin/service udisks2 start >& /dev/null");
+        }
+    }
+}
+
+sub get_loop_dev {
+    print "Finding free /dev/loop entry\n";
+    $dev = `losetup -f 2>/dev/null`;
+    chomp($dev);
+    if ( $dev eq "" ) {
+        print "losetup failed to obtain /dev/loop entry\n";
+        cleanup();
+        udisks2_restart();
+        exit -1;
+    }
+
+    # Keep list of devices for cleanup later
+    if ( $device_count eq 0 ) {
+        $device_list[$device_count] = $dev;
+        $device_count += 1;
+    }
+    elsif ( $dev ne $device_list[ $device_count - 1 ] ) {
+        $device_list[$device_count] = $dev;
+        $device_count += 1;
+    }
+}
+
+sub attach_dev {
+    print "Attaching $basedir/fstest to $dev\n";
+    $result = system("losetup $dev $basedir/fstest 2>/dev/null");
+    if ( $result != 0 ) {
+        print "Failed to attach $basedir/fstest to $dev\n";
+        cleanup();
+        udisks2_restart();
+        exit -1;
+    }
+}
+
+sub make_fs {
+    my ($mk_type) = @_;
+
+    get_loop_dev();
+
+    if ( $mk_type eq "tmpfs" ) {
+        return;
+    }
+
+    print "Create $basedir/fstest with dd\n";
+    $result = system(
+        "dd if=/dev/zero of=$basedir/fstest bs=1024 count=10240 2>/dev/null");
+    if ( $result != 0 ) {
+        print "dd failed to create fstest\n";
+        udisks2_restart();
+        exit -1;
+    }
+
+    attach_dev();
+
+    print "Make $mk_type filesystem on $dev\n";
+    $result = system("mkfs.$mk_type $dev >& /dev/null");
+    if ( $result != 0 ) {
+        system("losetup -d $dev 2>/dev/null");
+        cleanup();
+        print "mkfs.$mk_type failed to create filesystem on $dev\n";
+        udisks2_restart();
+        exit -1;
+    }
+}
+
+sub mk_mntpoint_1 {
+    system("rm -rf $private_path/mp1 2>/dev/null");
+    system("mkdir -p $private_path/mp1 2>/dev/null");
+}
+
+sub mk_mntpoint_2 {
+    system("rm -rf $private_path/mp2 2>/dev/null");
+    system("mkdir -p $private_path/mp2 2>/dev/null");
+}
+
+sub cleanup {
+    system("rm -rf $basedir/fstest 2>/dev/null");
+    system("rm -rf $basedir/mntpoint 2>/dev/null");
+}
+
+sub cleanup1 {
+    system("losetup -d $dev 2>/dev/null");
+    system("rm -rf $basedir/fstest 2>/dev/null");
+    system("rm -rf $basedir/mntpoint 2>/dev/null");
+}
+
+udisks2_stop();
+
+############### Test setfscreatecon(3) ##########################
+print "Test setfscreatecon(3)\n";
+$result = system
+"runcon -t test_setfscreatecon_t $basedir/fs_relabel $v -n system_u:system_r:test_setfscreatecon_newcon_t:s0";
+ok( $result eq 0 );
+
+$result = system
+"runcon -t test_no_setfscreatecon_t $basedir/fs_relabel $v -n system_u:system_r:test_setfscreatecon_newcon_t:s0 2>&1";
+ok( $result >> 8 eq 13 );
+
+############### Test Basic Mount/Unmount ##########################
+cleanup();
+mk_mntpoint_1();
+make_fs($fs_type);
+$mount_opts1 =
+  "quota,usrquota,grpquota,defcontext=system_u:object_r:test_filesystem_t:s0";
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$mount_opts1\n";
+$result = system(
+"runcon -t test_filesystem_t $basedir/mount -s $dev -t $private_path/mp1 -f $fs_type -o $mount_opts1 $v"
+);
+ok( $result eq 0 );
+
+print "Then remount\n";
+$result = system(
+"runcon -t test_filesystem_t $basedir/mount -r -s $dev -t $private_path/mp1 -f $fs_type -o $mount_opts1 $v"
+);
+ok( $result eq 0 );
+
+print "Running quotacheck(8) to init user/group quota files\n";
+
+# On RHEL-6, there is a type transition to quota_t when running quotacheck
+# as unconfined_t. Using "runcon `id -Z` quotacheck ..." resolves this.
+$result = system("runcon `id -Z` quotacheck -ugF vfsv0 $private_path/mp1");
+ok( $result eq 0 );
+
+print "Toggle User & Group quotas on/off\n";
+$result = system(
+"runcon -t test_filesystem_t $basedir/quotas_test -s $dev -t $private_path/mp1/aquota.user $v"
+);
+ok( $result eq 0 );
+$result = system(
+"runcon -t test_filesystem_t $basedir/quotas_test -s $dev -t $private_path/mp1/aquota.group $v"
+);
+ok( $result eq 0 );
+
+print "Get statfs(2)\n";
+$result =
+  system(
+    "runcon -t test_filesystem_t $basedir/statfs_test -t $basedir/mntpoint $v");
+ok( $result eq 0 );
+
+print "Creating test file $basedir/mntpoint/mp1/test_file\n";
+$result =
+  system(
+"runcon -t test_filesystem_t $basedir/create_file_change_context -t test_filesystem_filecon_t -f $private_path/mp1/test_file $v"
+  );
+ok( $result eq 0 );
+
+if ($test_watch) {
+    print "fanotify(7) test\n";
+    $result = system(
+"runcon -t test_filesystem_t $basedir/fanotify_fs $v -t $basedir/mntpoint/mp1"
+    );
+    ok( $result eq 0 );
+}
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result =
+  system("runcon -t test_filesystem_t $basedir/umount -t $private_path/mp1 $v");
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Test Move Mount ##########################
+make_fs($fs_type);
+$mount_opts2 =
+  "quota,usrquota,grpquota,rootcontext=system_u:object_r:test_filesystem_t:s0";
+system("mkdir -p $private_path 2>/dev/null");
+
+print "Set mount MS_BIND on filesystem\n";
+$result = system(
+"runcon -t test_filesystem_t $basedir/mount -s $private_path -t $private_path -b $v"
+);
+ok( $result eq 0 );
+
+print "Set mount MS_PRIVATE on filesystem\n";
+$result =
+  system("runcon -t test_filesystem_t $basedir/mount -t $private_path -p $v");
+ok( $result eq 0 );
+
+mk_mntpoint_1();
+mk_mntpoint_2();
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$mount_opts2\n";
+$result = system(
+"runcon -t test_filesystem_t $basedir/mount -s $dev -t $private_path/mp1 -f $fs_type -o $mount_opts2 $v"
+);
+ok( $result eq 0 );
+
+print "Set mount MS_MOVE on filesystem\n";
+$result = system(
+"runcon -t test_filesystem_t $basedir/mount -s $private_path/mp1 -t $private_path/mp2 -m  $v"
+);
+ok( $result eq 0 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp2\n";
+$result =
+  system("runcon -t test_filesystem_t $basedir/umount -t $private_path/mp2 $v");
+ok( $result eq 0 );
+
+print "Unmount filesystem from $basedir/mntpoint\n";
+$result =
+  system("runcon -t test_filesystem_t $basedir/umount -t $private_path $v");
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { relabelfrom } ##########################
+# hooks.c may_context_mount_sb_relabel() FILESYSTEM__RELABELFROM
+
+$opts_no_relabelfrom =
+"defcontext=system_u:object_r:test_filesystem_no_relabelfrom_t:s0,fscontext=system_u:object_r:test_filesystem_no_relabelfrom_t:s0";
+mk_mntpoint_1();
+make_fs($fs_type);
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$opts_no_relabelfrom\n";
+$result = system(
+"runcon -t test_filesystem_no_relabelfrom_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_relabelfrom $v 2>&1"
+);
+ok( $result >> 8 eq 13 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { relabelto } ##########################
+# hooks.c may_context_mount_sb_relabel() FILESYSTEM__RELABELTO
+
+$opts_no_relabelto =
+  "fscontext=system_u:object_r:test_filesystem_no_relabelto_t:s0";
+mk_mntpoint_1();
+make_fs($fs_type);
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$opts_no_relabelto\n";
+$result = system(
+"runcon -t test_filesystem_no_relabelto_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_relabelto $v 2>&1"
+);
+ok( $result >> 8 eq 13 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { relabelfrom } ##########################
+# hooks.c may_context_mount_inode_relabel() FILESYSTEM__RELABELFROM
+
+$opts_no_relabelfrom =
+  "rootcontext=system_u:object_r:test_filesystem_no_relabelfrom_t:s0";
+mk_mntpoint_1();
+make_fs($fs_type);
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$opts_no_relabelfrom\n";
+$result = system(
+"runcon -t test_filesystem_no_relabelfrom_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_relabelfrom $v 2>&1"
+);
+ok( $result >> 8 eq 13 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { associate } ##########################
+# hooks.c may_context_mount_inode_relabel() FILESYSTEM__ASSOCIATE
+
+$opts_no_associate =
+"defcontext=system_u:object_r:test_filesystem_no_associate_t:s0,fscontext=system_u:object_r:test_filesystem_no_associate_t:s0";
+mk_mntpoint_1();
+make_fs($fs_type);
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$opts_no_associate\n";
+$result = system(
+"runcon -t test_filesystem_no_associate_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_associate $v 2>&1"
+);
+ok( $result >> 8 eq 13 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { associate } ##########################
+# hooks.c may_create() FILESYSTEM__ASSOCIATE
+cleanup();
+mk_mntpoint_1();
+make_fs($fs_type);
+$opts_no_associate_file =
+  "fscontext=system_u:object_r:test_filesystem_no_associate_file_t:s0";
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$opts_no_associate_file\n";
+$result = system(
+"runcon -t test_filesystem_no_associate_file_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_associate_file $v"
+);
+ok( $result eq 0 );
+
+print "Creating test file $basedir/mntpoint/mp1/test_file\n";
+$result =
+  system(
+"runcon -t test_filesystem_no_associate_file_t $basedir/create_file_change_context -t unconfined_t -f $basedir/mntpoint/mp1/test_file $v 2>&1"
+  );
+ok( $result >> 8 eq 13 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result =
+  system(
+"runcon -t test_filesystem_no_associate_file_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+  );
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { quotamod } ##########################
+# hooks.c selinux_quotactl() FILESYSTEM__QUOTAMOD
+
+$opts_no_quotamod =
+"quota,usrquota,grpquota,fscontext=system_u:object_r:test_filesystem_no_quotamod_t:s0";
+mk_mntpoint_1();
+make_fs($fs_type);
+system("mkdir -p $private_path 2>/dev/null");
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$opts_no_quotamod\n";
+$result = system(
+"runcon -t test_filesystem_no_quotamod_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_quotamod $v 2>&1"
+);
+ok( $result eq 0 );
+
+# No need to run quotacheck(8) as never gets far enough to read quota file
+print "Toggle User & Group quotas on/off\n";    # Must have full path
+$result = system(
+"runcon -t test_filesystem_no_quotamod_t $basedir/quotas_test -s $dev -t $private_path/mp1/aquota.user $v 2>&1"
+);
+ok( $result >> 8 eq 13 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result = system(
+"runcon -t test_filesystem_no_quotamod_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+);
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { quotaget } ##########################
+# hooks.c selinux_quotactl() FILESYSTEM__QUOTAGET
+
+$opts_no_quotaget =
+"quota,usrquota,grpquota,context=system_u:object_r:test_filesystem_no_quotaget_t:s0";
+mk_mntpoint_1();
+make_fs($fs_type);
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$opts_no_quotaget\n";
+$result = system(
+"runcon -t test_filesystem_no_quotaget_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_quotaget $v"
+);
+ok( $result eq 0 );
+
+print "Running quotacheck(8) to init user/group quota files\n";
+$result = system("runcon `id -Z` quotacheck -ugF vfsv0 $private_path/mp1");
+ok( $result eq 0 );
+
+print "Toggle User & Group quotas on/off\n";    # Must have full path
+$result = system(
+"runcon -t test_filesystem_no_quotaget_t $basedir/quotas_test -s $dev -t $private_path/mp1/aquota.user $v 2>&1"
+);
+ok( $result >> 8 eq 13 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result = system(
+"runcon -t test_filesystem_no_quotaget_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+);
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { mount } ##########################
+# hooks.c selinux_sb_kern_mount() FILESYSTEM__MOUNT
+
+$opts_no_mount = "rootcontext=system_u:object_r:test_filesystem_no_mount_t:s0";
+mk_mntpoint_1();
+make_fs($fs_type);
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$opts_no_mount\n";
+$result = system(
+"runcon -t test_filesystem_no_mount_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_mount $v 2>&1"
+);
+ok( $result >> 8 eq 13 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { getattr } ##########################
+# hooks.c selinux_sb_statfs() FILESYSTEM__GETATTR
+
+$opts_no_getattr =
+  "rootcontext=system_u:object_r:test_filesystem_no_getattr_t:s0";
+mk_mntpoint_1();
+make_fs($fs_type);
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$opts_no_getattr\n";
+$result = system(
+"runcon -t test_filesystem_no_getattr_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_getattr $v"
+);
+ok( $result eq 0 );
+
+$result = system(
+"runcon -t test_filesystem_no_getattr_t $basedir/statfs_test -t $basedir/mntpoint $v 2>&1"
+);
+ok( $result >> 8 eq 13 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result = system(
+"runcon -t test_filesystem_no_getattr_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+);
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { remount } ##########################
+# hooks.c selinux_mount() FILESYSTEM__REMOUNT
+
+$opts_no_remount =
+  "rootcontext=system_u:object_r:test_filesystem_no_remount_t:s0";
+mk_mntpoint_1();
+make_fs($fs_type);
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$opts_no_remount\n";
+$result = system(
+"runcon -t test_filesystem_no_remount_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_remount $v"
+);
+ok( $result eq 0 );
+
+print "Then remount\n";
+$result = system(
+"runcon -t test_filesystem_no_remount_t $basedir/mount -r -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_remount $v 2>&1"
+);
+ok( $result >> 8 eq 13 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result = system(
+"runcon -t test_filesystem_no_remount_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+);
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { unmount } ##########################
+# hooks.c selinux_umount() FILESYSTEM__UNMOUNT
+
+$opts_no_unmount =
+  "rootcontext=system_u:object_r:test_filesystem_no_unmount_t:s0";
+mk_mntpoint_1();
+make_fs($fs_type);
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$opts_no_unmount\n";
+$result = system(
+"runcon -t test_filesystem_no_unmount_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_unmount $v"
+);
+ok( $result eq 0 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result = system(
+"runcon -t test_filesystem_no_unmount_t $basedir/umount -t $basedir/mntpoint/mp1 $v 2>&1"
+);
+ok( $result >> 8 eq 13 );
+
+# Make sure it does get unmounted
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result =
+  system(
+    "runcon -t test_filesystem_t $basedir/umount -t $basedir/mntpoint/mp1 $v");
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { associate }  ##########################
+# hooks.c selinux_inode_setxattr() FILESYSTEM__ASSOCIATE
+cleanup();
+mk_mntpoint_1();
+make_fs($fs_type);
+$opts_no_associate_file =
+"defcontext=system_u:object_r:test_filesystem_no_associate_file_t:s0,fscontext=system_u:object_r:test_filesystem_no_associate_file_t:s0";
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$opts_no_associate_file\n";
+$result = system(
+"runcon -t test_filesystem_no_associate_file_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_associate_file $v"
+);
+ok( $result eq 0 );
+
+print "Creating test file $basedir/mntpoint/mp1/test_file\n";
+$result =
+  system(
+"runcon -t test_filesystem_no_associate_file_t $basedir/create_file_change_context -t unconfined_t -f $basedir/mntpoint/mp1/test_file $v 2>&1"
+  );
+ok( $result >> 8 eq 13 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result =
+  system(
+"runcon -t test_filesystem_no_associate_file_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+  );
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+############### Deny filesystem { watch }  ##########################
+# hooks.c selinux_path_notify() FILESYSTEM__WATCH
+if ($test_watch) {
+    cleanup();
+    mk_mntpoint_1();
+    make_fs($fs_type);
+    $opts_no_watch = "context=system_u:object_r:test_filesystem_no_watch_t:s0";
+
+    print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+    print "Using mount options:\n\t$opts_no_watch\n";
+    $result = system(
+"runcon -t test_filesystem_no_watch_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_watch $v"
+    );
+    ok( $result eq 0 );
+
+    print "test_fanotify\n";
+    $result = system(
+"runcon -t test_filesystem_no_watch_t $basedir/fanotify_fs $v -t $basedir/mntpoint/mp1 2>&1"
+    );
+    ok( $result >> 8 eq 13 );
+
+    print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+    $result = system(
+"runcon -t test_filesystem_no_watch_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+    );
+    ok( $result eq 0 );
+
+    print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+    cleanup1();
+}
+
+##########################################################################
+# context     - Useful when mounting filesystems that do not support extended
+#               attributes.
+#   Tested by - Creating a filesystem that has xattrs set to a different value,
+#               then mount with context= and confirm that the files have that
+#               context as well as any newly created files (even if fscreate
+#               was set to something else), and that setfilecon/setxattr() on
+#               files within the mount fails with errno EOPNOTSUPP.
+##########################################################################
+cleanup();
+mk_mntpoint_1();
+make_fs($fs_type);
+
+# Mount with xttrs to create a file with specific context.
+$context1_opts = "defcontext=system_u:object_r:test_filesystem_context_t:s0";
+
+print "Testing 'context=' mount option\n";
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$context1_opts\n";
+$result = system(
+"runcon -t test_filesystem_context_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $context1_opts $v"
+);
+ok( $result eq 0 );
+
+# Create file with 'test_filesystem_filecon_t' context
+print "Creating test file $basedir/mntpoint/mp1/test_file\n";
+$result =
+  system(
+"runcon -t test_filesystem_context_t $basedir/create_file_change_context -t test_filesystem_filecon_t -f $private_path/mp1/test_file $v"
+  );
+ok( $result eq 0 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result = system(
+"runcon -t test_filesystem_context_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+);
+ok( $result eq 0 );
+
+# Need to free the loop device, then get new dev one and attach
+system("losetup -d $dev 2>/dev/null");
+get_loop_dev();
+attach_dev();
+
+# Mount again with no xttr support
+$context2_opts = "context=system_u:object_r:test_filesystem_context_t:s0";
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$context2_opts\n";
+$result = system(
+"runcon -t test_filesystem_context_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $context2_opts $v"
+);
+ok( $result eq 0 );
+
+# Now check the context on file is system_u:object_r:test_filesystem_context_t:s0
+print "Check test file context $basedir/mntpoint/mp1/test_file\n";
+$result =
+  system(
+"runcon -t test_filesystem_context_t $basedir/check_file_context -f $private_path/mp1/test_file -e system_u:object_r:test_filesystem_context_t:s0 $v"
+  );
+ok( $result eq 0 );
+
+# Then create a file with 'test_filesystem_filecon_t' context, this should fail with EOPNOTSUPP
+print "Creating test file $basedir/mntpoint/mp1/test_file\n";
+$result =
+  system(
+"runcon -t test_filesystem_context_t $basedir/create_file_change_context -t test_filesystem_filecon_t -f $private_path/mp1/test_file $v 2>/dev/null"
+  );
+ok( $result >> 8 eq 95 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result =
+  system(
+"runcon -t test_filesystem_context_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+  );
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+##########################################################################
+# rootcontext - Explicitly label the root inode of the filesystem being
+#               mounted before that filesystem or inode becomes visible
+#               to userspace.
+#   Tested by - Set mountpoint to unlabeled_t and then check that the
+#               context of the root directory matches rootcontext= after
+#               the mount operation.
+##########################################################################
+cleanup();
+mk_mntpoint_1();
+make_fs($fs_type);
+$root_opts = "rootcontext=system_u:object_r:test_filesystem_context_t:s0";
+
+print "Testing 'rootcontext=' mount option\n";
+
+# Reset mountpoint to 'unlabeled_t' so it is different to any other possible test values.
+print "Resetting MP to unlabeled_t $basedir/mntpoint/mp1\n";
+$result =
+  system(
+"runcon -t test_filesystem_context_t $basedir/check_mount_context -r -m $basedir/mntpoint/mp1 $v"
+  );
+ok( $result eq 0 );
+
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$root_opts\n";
+$result = system(
+"runcon -t test_filesystem_context_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $root_opts $v"
+);
+ok( $result eq 0 );
+
+# Now check the mountpoint is the 'rootcontext=' value
+print "Check MP context $basedir/mntpoint/mp1\n";
+$result =
+  system(
+"runcon -t test_filesystem_context_t $basedir/check_mount_context -m $basedir/mntpoint/mp1 -e system_u:object_r:test_filesystem_context_t:s0 $v"
+  );
+ok( $result eq 0 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result = system(
+"runcon -t test_filesystem_context_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+);
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+##########################################################################
+# defcontext  - Set default security context for unlabeled files.
+#               This overrides the value set for unlabeled files in policy
+#               and requires a filesystem that supports xattr labeling.
+#   Tested by - Create filesystem that has files w/o xattrs and then confirm
+#               that they are mapped to the specified defcontext upon mount,
+#               where defcontext differs from the policy default.
+##########################################################################
+cleanup();
+mk_mntpoint_1();
+make_fs($fs_type);
+
+$test_opts = "context=system_u:object_r:test_filesystem_context_t:s0";
+
+print "Testing 'defcontext=' mount option\n";
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$test_opts\n";
+$result = system(
+"runcon -t test_filesystem_context_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $test_opts $v"
+);
+ok( $result eq 0 );
+
+# Create file, its context will be system_u:object_r:test_filesystem_context_t:s0 from $test_opts
+print "Creating test file $basedir/mntpoint/mp1/test_file\n";
+$result =
+  system(
+"runcon -u system_u -t test_filesystem_fscontext_t $basedir/create_file -f $basedir/mntpoint/mp1/test_file $v"
+  );
+ok( $result eq 0 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result = system(
+"runcon -t test_filesystem_context_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+);
+ok( $result eq 0 );
+
+# Need to free the loop device, then get new dev one and attach
+system("losetup -d $dev 2>/dev/null");
+get_loop_dev();
+attach_dev();
+
+# Mount again with defcontext=
+$defcontext_opts = "defcontext=system_u:object_r:test_filesystem_filecon_t:s0";
+print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$defcontext_opts\n";
+$result = system(
+"runcon -t test_filesystem_context_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $defcontext_opts $v"
+);
+ok( $result eq 0 );
+
+# Now check the file context is now system_u:object_r:test_filesystem_filecon_t:s0
+print "Check test file context $basedir/mntpoint/mp1/test_file\n";
+$result =
+  system(
+"runcon -t test_filesystem_context_t $basedir/check_file_context -f $basedir/mntpoint/mp1/test_file -e system_u:object_r:test_filesystem_filecon_t:s0 $v"
+  );
+ok( $result eq 0 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result =
+  system(
+"runcon -t test_filesystem_context_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+  );
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+##########################################################################
+# fscontext   - Sets the overarching filesystem label to a specific security
+#               context. This filesystem label is separate from the individual
+#               labels on the files.
+#   Tested by - Mount a tmpfs (fs_use_trans) filesystem with fscontext= and
+#               then create a file within it, checking its context.
+##########################################################################
+$fs_type = "tmpfs";
+cleanup();
+mk_mntpoint_1();
+make_fs($fs_type);
+$fscontext_opts =
+"fscontext=system_u:object_r:test_filesystem_fscontext_t:s0,size=10M,mode=0770";
+
+print "Testing 'fscontext=' mount option\n";
+print "Mount tmpfs filesystem on $basedir/mntpoint/mp1\n";
+print "Using mount options:\n\t$fscontext_opts\n";
+$result = system(
+"runcon -t test_filesystem_fscontext_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $fscontext_opts $v"
+);
+ok( $result eq 0 );
+
+print "Creating test file $basedir/mntpoint/mp1/test_file\n";
+$result =
+  system(
+"runcon -t test_filesystem_fscontext_t $basedir/create_file_change_context -t test_filesystem_filecon_t -f $private_path/mp1/test_file $v"
+  );
+ok( $result eq 0 );
+
+print "Unmount filesystem from $basedir/mntpoint/mp1\n";
+$result =
+  system(
+"runcon -t test_filesystem_fscontext_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+  );
+ok( $result eq 0 );
+
+print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+cleanup1();
+
+# Cleanup any attached /dev/loop entries
+foreach my $n (@device_list) {
+    system("$basedir/grim_reaper $n 2>/dev/null");
+}
+
+udisks2_restart();
+
+exit;
diff --git a/tests/filesystem/umount.c b/tests/filesystem/umount.c
new file mode 100644
index 0000000..4a20448
--- /dev/null
+++ b/tests/filesystem/umount.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <sys/mount.h>
+#include <selinux/selinux.h>
+
+static void print_usage(char *progname)
+{
+	fprintf(stderr,
+		"usage:  %s [-v] [-t]\n"
+		"Where:\n\t"
+		"-t  Target path\n\t"
+		"-v  Print information.\n", progname);
+	exit(-1);
+}
+
+#define WAIT_COUNT 60
+#define USLEEP_TIME 100000
+
+int main(int argc, char *argv[])
+{
+	char *context, *tgt = NULL;
+	int opt, result, i, save_err;
+	bool verbose = false;
+
+	while ((opt = getopt(argc, argv, "t:v")) != -1) {
+		switch (opt) {
+		case 't':
+			tgt = optarg;
+			break;
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			print_usage(argv[0]);
+		}
+	}
+
+	if (!tgt)
+		print_usage(argv[0]);
+
+	if (verbose) {
+		result = getcon(&context);
+		if (result < 0) {
+			fprintf(stderr, "Failed to obtain process context\n");
+			exit(-1);
+		}
+		printf("Process context:\n\t%s\n", context);
+		free(context);
+	}
+
+	/*
+	 * umount(2) will sometimes return EBUSY when other tasks are
+	 * checking mounts so wait around before bailing out.
+	 */
+	for (i = 0; i < WAIT_COUNT; i++) {
+		result = umount(tgt);
+		save_err = errno;
+		if (!result) {
+			if (verbose)
+				printf("Unmounted: %s\n", tgt);
+
+			return 0;
+		}
+
+		if (verbose && save_err == EBUSY)
+			printf("umount(2) returned EBUSY %d times\n", i + 1);
+
+		if (save_err != EBUSY) {
+			fprintf(stderr, "Failed umount(2): %s\n",
+				strerror(save_err));
+			return save_err;
+		}
+		usleep(USLEEP_TIME);
+	}
+
+	fprintf(stderr, "Failed to umount(2) after %d retries with: %s\n",
+		WAIT_COUNT, strerror(save_err));
+
+	return save_err;
+}
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-09 15:07 ` [PATCH V2 1/1] " Richard Haines
@ 2020-01-09 17:14   ` Stephen Smalley
  2020-01-09 17:40     ` Richard Haines
  2020-01-09 17:19   ` Stephen Smalley
  2020-01-09 17:46   ` Stephen Smalley
  2 siblings, 1 reply; 19+ messages in thread
From: Stephen Smalley @ 2020-01-09 17:14 UTC (permalink / raw)
  To: Richard Haines, selinux; +Cc: omosnace

On 1/9/20 10:07 AM, Richard Haines wrote:
> Test filesystem permissions and setfscreatecon(3).
> 
>  From kernels 5.5 filesystem { watch } is also tested.
> 
> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> ---

> diff --git a/tests/filesystem/fs_relabel.c b/tests/filesystem/fs_relabel.c
> new file mode 100644
> index 0000000..25b1781
> --- /dev/null
> +++ b/tests/filesystem/fs_relabel.c
> @@ -0,0 +1,72 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <stdbool.h>
> +#include <linux/unistd.h>
> +#include <selinux/selinux.h>
> +
> +static void print_usage(char *progname)
> +{
> +	fprintf(stderr,
> +		"usage:  %s [-v] -n\n"
> +		"Where:\n\t"
> +		"-n  New fs context\n\t"
> +		"-v  Print information.\n", progname);
> +	exit(-1);
> +}
> +
> +int main(int argc, char **argv)
> +{
> +	int opt, result, save_err;
> +	char *context, *fscreate_con, *newcon = NULL;
> +	bool verbose = false;
> +
> +	while ((opt = getopt(argc, argv, "n:v")) != -1) {
> +		switch (opt) {
> +		case 'n':
> +			newcon = optarg;
> +			break;
> +		case 'v':
> +			verbose = true;
> +			break;
> +		default:
> +			print_usage(argv[0]);
> +		}
> +	}
> +
> +	if (!newcon)
> +		print_usage(argv[0]);
> +
> +	if (verbose) {
> +		result = getcon(&context);
> +		if (result < 0) {
> +			fprintf(stderr, "Failed to obtain process context\n");
> +			exit(-1);
> +		}
> +		printf("Process context:\n\t%s\n", context);
> +		free(context);
> +	}
> +
> +	result = setfscreatecon(newcon);
> +	save_err = errno;
> +	if (result < 0) {
> +		fprintf(stderr, "Failed setfscreatecon(3): %s\n",
> +			strerror(errno));
> +		return save_err;
> +	}
> +
> +	result = getfscreatecon(&fscreate_con);
> +	if (result < 0) {
> +		fprintf(stderr, "Failed getfscreatecon(3): %s\n",
> +			strerror(errno));
> +		exit(-1);
> +	}
> +	if (verbose)
> +		printf("New fscreate context: %s\n", fscreate_con);
> +
> +	free(fscreate_con);
> +	return 0;
> +}

I'm a little confused by this test.  setfscreatecon() is normally 
performed prior to performing some file creation using creat() or 
open(O_CREAT), mkdir(), symlink(), etc and the expected behavior is that 
the newly created file/directory/link/... will have the specified 
security context.  I didn't see an explicit test that setfscreatecon() 
followed by one or more file creations yields the expected context on 
the new files, and I don't think we have an explicit test of this 
functionality in the testsuite currently.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-09 15:07 ` [PATCH V2 1/1] " Richard Haines
  2020-01-09 17:14   ` Stephen Smalley
@ 2020-01-09 17:19   ` Stephen Smalley
  2020-01-09 17:45     ` Richard Haines
  2020-01-10 18:09     ` Richard Haines
  2020-01-09 17:46   ` Stephen Smalley
  2 siblings, 2 replies; 19+ messages in thread
From: Stephen Smalley @ 2020-01-09 17:19 UTC (permalink / raw)
  To: Richard Haines, selinux; +Cc: omosnace

On 1/9/20 10:07 AM, Richard Haines wrote:
> Test filesystem permissions and setfscreatecon(3).
> 
>  From kernels 5.5 filesystem { watch } is also tested.
> 
> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> ---

> diff --git a/policy/test_filesystem.te b/policy/test_filesystem.te
> new file mode 100644
> index 0000000..2eee1fc
> --- /dev/null
> +++ b/policy/test_filesystem.te
> @@ -0,0 +1,324 @@
> +#
> +######### Test filesystem permissions policy module ##########
> +#
> +attribute filesystemdomain;
> +
> +#################### Create a test file context ######################
> +type test_filesystem_filecon_t;
> +unconfined_runs_test(test_filesystem_filecon_t)
> +
> +################# Test all functions ##########################
> +type test_filesystem_t;
> +domain_type(test_filesystem_t)
> +unconfined_runs_test(test_filesystem_t)
> +typeattribute test_filesystem_t testdomain;
> +typeattribute test_filesystem_t filesystemdomain;
> +
> +allow test_filesystem_t self:capability { sys_admin };
> +allow test_filesystem_t self:filesystem { mount remount quotamod relabelfrom relabelto unmount quotaget };
> +allow test_filesystem_t self:dir { mounton add_name write };
> +allow test_filesystem_t test_file_t:dir { mounton write remove_name rmdir };
> +# Create test file
> +allow test_filesystem_t self:dir { add_name write };
> +allow test_filesystem_t self:file { create relabelfrom relabelto };
> +
> +fs_mount_all_fs(test_filesystem_t)
> +fs_remount_all_fs(test_filesystem_t)
> +fs_unmount_all_fs(test_filesystem_t)
> +fs_relabelfrom_all_fs(test_filesystem_t)
> +fs_get_xattr_fs_quotas(test_filesystem_t)
> +files_search_all(test_filesystem_t)
> +# Required for mount opts "rootcontext=system_u:object_r:test_filesystem_t:s0";
> +fs_associate(test_filesystem_t)
> +fs_getattr_xattr_fs(test_filesystem_t)
> +
> +# For running quotacheck(8)
> +files_type(test_filesystem_t)
> +# Update quotas
> +fs_set_all_quotas(test_filesystem_t)
> +allow test_filesystem_t self:file { quotaon };
> +# Create test file and change context:
> +fs_associate(test_filesystem_filecon_t)
> +allow test_filesystem_t test_filesystem_filecon_t:file { open read getattr relabelto write };
> +dontaudit test_filesystem_t kernel_t:process { setsched };

Why do you need these dontaudit statements?  It seems like a kernel bug 
if something is triggering a setsched permission check on the kernel_t 
domain?  Something the kernel module is doing during initialization?


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-09 17:14   ` Stephen Smalley
@ 2020-01-09 17:40     ` Richard Haines
  0 siblings, 0 replies; 19+ messages in thread
From: Richard Haines @ 2020-01-09 17:40 UTC (permalink / raw)
  To: Stephen Smalley, selinux; +Cc: omosnace

On Thu, 2020-01-09 at 12:14 -0500, Stephen Smalley wrote:
> On 1/9/20 10:07 AM, Richard Haines wrote:
> > Test filesystem permissions and setfscreatecon(3).
> > 
> >  From kernels 5.5 filesystem { watch } is also tested.
> > 
> > Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> > ---
> > diff --git a/tests/filesystem/fs_relabel.c
> > b/tests/filesystem/fs_relabel.c
> > new file mode 100644
> > index 0000000..25b1781
> > --- /dev/null
> > +++ b/tests/filesystem/fs_relabel.c
> > @@ -0,0 +1,72 @@
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <unistd.h>
> > +#include <errno.h>
> > +#include <fcntl.h>
> > +#include <stdbool.h>
> > +#include <linux/unistd.h>
> > +#include <selinux/selinux.h>
> > +
> > +static void print_usage(char *progname)
> > +{
> > +	fprintf(stderr,
> > +		"usage:  %s [-v] -n\n"
> > +		"Where:\n\t"
> > +		"-n  New fs context\n\t"
> > +		"-v  Print information.\n", progname);
> > +	exit(-1);
> > +}
> > +
> > +int main(int argc, char **argv)
> > +{
> > +	int opt, result, save_err;
> > +	char *context, *fscreate_con, *newcon = NULL;
> > +	bool verbose = false;
> > +
> > +	while ((opt = getopt(argc, argv, "n:v")) != -1) {
> > +		switch (opt) {
> > +		case 'n':
> > +			newcon = optarg;
> > +			break;
> > +		case 'v':
> > +			verbose = true;
> > +			break;
> > +		default:
> > +			print_usage(argv[0]);
> > +		}
> > +	}
> > +
> > +	if (!newcon)
> > +		print_usage(argv[0]);
> > +
> > +	if (verbose) {
> > +		result = getcon(&context);
> > +		if (result < 0) {
> > +			fprintf(stderr, "Failed to obtain process
> > context\n");
> > +			exit(-1);
> > +		}
> > +		printf("Process context:\n\t%s\n", context);
> > +		free(context);
> > +	}
> > +
> > +	result = setfscreatecon(newcon);
> > +	save_err = errno;
> > +	if (result < 0) {
> > +		fprintf(stderr, "Failed setfscreatecon(3): %s\n",
> > +			strerror(errno));
> > +		return save_err;
> > +	}
> > +
> > +	result = getfscreatecon(&fscreate_con);
> > +	if (result < 0) {
> > +		fprintf(stderr, "Failed getfscreatecon(3): %s\n",
> > +			strerror(errno));
> > +		exit(-1);
> > +	}
> > +	if (verbose)
> > +		printf("New fscreate context: %s\n", fscreate_con);
> > +
> > +	free(fscreate_con);
> > +	return 0;
> > +}
> 
> I'm a little confused by this test.  setfscreatecon() is normally 
> performed prior to performing some file creation using creat() or 
> open(O_CREAT), mkdir(), symlink(), etc and the expected behavior is
> that 
> the newly created file/directory/link/... will have the specified 
> security context.  I didn't see an explicit test that
> setfscreatecon() 
> followed by one or more file creations yields the expected context
> on 
> the new files, and I don't think we have an explicit test of this 
> functionality in the testsuite currently.

I'll fix in next version (This only tested whether the permission was
allowed or not).

> 
> 
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-09 17:19   ` Stephen Smalley
@ 2020-01-09 17:45     ` Richard Haines
  2020-01-10 18:09     ` Richard Haines
  1 sibling, 0 replies; 19+ messages in thread
From: Richard Haines @ 2020-01-09 17:45 UTC (permalink / raw)
  To: Stephen Smalley, selinux; +Cc: omosnace

On Thu, 2020-01-09 at 12:19 -0500, Stephen Smalley wrote:
> On 1/9/20 10:07 AM, Richard Haines wrote:
> > Test filesystem permissions and setfscreatecon(3).
> > 
> >  From kernels 5.5 filesystem { watch } is also tested.
> > 
> > Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> > ---
> > diff --git a/policy/test_filesystem.te b/policy/test_filesystem.te
> > new file mode 100644
> > index 0000000..2eee1fc
> > --- /dev/null
> > +++ b/policy/test_filesystem.te
> > @@ -0,0 +1,324 @@
> > +#
> > +######### Test filesystem permissions policy module ##########
> > +#
> > +attribute filesystemdomain;
> > +
> > +#################### Create a test file context
> > ######################
> > +type test_filesystem_filecon_t;
> > +unconfined_runs_test(test_filesystem_filecon_t)
> > +
> > +################# Test all functions ##########################
> > +type test_filesystem_t;
> > +domain_type(test_filesystem_t)
> > +unconfined_runs_test(test_filesystem_t)
> > +typeattribute test_filesystem_t testdomain;
> > +typeattribute test_filesystem_t filesystemdomain;
> > +
> > +allow test_filesystem_t self:capability { sys_admin };
> > +allow test_filesystem_t self:filesystem { mount remount quotamod
> > relabelfrom relabelto unmount quotaget };
> > +allow test_filesystem_t self:dir { mounton add_name write };
> > +allow test_filesystem_t test_file_t:dir { mounton write
> > remove_name rmdir };
> > +# Create test file
> > +allow test_filesystem_t self:dir { add_name write };
> > +allow test_filesystem_t self:file { create relabelfrom relabelto
> > };
> > +
> > +fs_mount_all_fs(test_filesystem_t)
> > +fs_remount_all_fs(test_filesystem_t)
> > +fs_unmount_all_fs(test_filesystem_t)
> > +fs_relabelfrom_all_fs(test_filesystem_t)
> > +fs_get_xattr_fs_quotas(test_filesystem_t)
> > +files_search_all(test_filesystem_t)
> > +# Required for mount opts
> > "rootcontext=system_u:object_r:test_filesystem_t:s0";
> > +fs_associate(test_filesystem_t)
> > +fs_getattr_xattr_fs(test_filesystem_t)
> > +
> > +# For running quotacheck(8)
> > +files_type(test_filesystem_t)
> > +# Update quotas
> > +fs_set_all_quotas(test_filesystem_t)
> > +allow test_filesystem_t self:file { quotaon };
> > +# Create test file and change context:
> > +fs_associate(test_filesystem_filecon_t)
> > +allow test_filesystem_t test_filesystem_filecon_t:file { open read
> > getattr relabelto write };
> > +dontaudit test_filesystem_t kernel_t:process { setsched };
> 
> Why do you need these dontaudit statements?  It seems like a kernel
> bug 
> if something is triggering a setsched permission check on the
> kernel_t 
> domain?  Something the kernel module is doing during initialization?
> 

I only added these to have a clean log output. As I'm (not knowingly)
using anything that requires it. I'll investigate further.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-09 15:07 ` [PATCH V2 1/1] " Richard Haines
  2020-01-09 17:14   ` Stephen Smalley
  2020-01-09 17:19   ` Stephen Smalley
@ 2020-01-09 17:46   ` Stephen Smalley
  2020-01-09 17:51     ` Richard Haines
  2 siblings, 1 reply; 19+ messages in thread
From: Stephen Smalley @ 2020-01-09 17:46 UTC (permalink / raw)
  To: Richard Haines, selinux; +Cc: omosnace

On 1/9/20 10:07 AM, Richard Haines wrote:
> Test filesystem permissions and setfscreatecon(3).
> 
>  From kernels 5.5 filesystem { watch } is also tested.
> 
> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> ---

> diff --git a/policy/test_filesystem.te b/policy/test_filesystem.te
> new file mode 100644
> index 0000000..2eee1fc
> --- /dev/null
> +++ b/policy/test_filesystem.te
<snip>
> +#################### Deny filesystem { quotamod } ######################
> +type test_filesystem_no_quotamod_t;
> +domain_type(test_filesystem_no_quotamod_t)
> +unconfined_runs_test(test_filesystem_no_quotamod_t)
> +typeattribute test_filesystem_no_quotamod_t testdomain;
> +typeattribute test_filesystem_no_quotamod_t filesystemdomain;
> +
> +allow test_filesystem_no_quotamod_t self:capability { sys_admin };
> +allow test_filesystem_no_quotamod_t self:filesystem { quotaget relabelto mount unmount};
> +fs_mount_all_fs(test_filesystem_no_quotamod_t)
> +fs_relabelfrom_all_fs(test_filesystem_no_quotamod_t)
> +fs_associate(test_filesystem_no_quotamod_t)
> +# Required as $private_path to quota files
> +files_search_all(test_filesystem_no_quotamod_t)
> +allow test_filesystem_no_quotamod_t self:dir { mounton };
> +allow test_filesystem_no_quotamod_t test_file_t:dir { mounton write remove_name rmdir };
> +dontaudit test_filesystem_no_quotamod_t kernel_t:process { setsched };
> +
> +#################### Deny filesystem { quotaget } ######################
> +type test_filesystem_no_quotaget_t;
> +domain_type(test_filesystem_no_quotaget_t)
> +unconfined_runs_test(test_filesystem_no_quotaget_t)
> +typeattribute test_filesystem_no_quotaget_t testdomain;
> +typeattribute test_filesystem_no_quotaget_t filesystemdomain;
> +
> +allow test_filesystem_no_quotaget_t self:capability { sys_admin };
> +allow test_filesystem_no_quotaget_t self:filesystem { quotamod relabelto mount unmount relabelfrom };
> +allow test_filesystem_no_quotaget_t self:dir { mounton };
> +allow test_filesystem_no_quotaget_t test_file_t:dir { mounton write remove_name rmdir };
> +allow test_filesystem_no_quotaget_t self:file { quotaon };
> +fs_mount_all_fs(test_filesystem_no_quotaget_t)
> +fs_relabelfrom_all_fs(test_filesystem_no_quotaget_t)
> +fs_associate(test_filesystem_no_quotaget_t)
> +# Required as $private_path to quota files
> +files_search_all(test_filesystem_no_quotaget_t)
> +# For running quotacheck(8)
> +files_type(test_filesystem_no_quotaget_t)
> +dontaudit test_filesystem_no_quotaget_t kernel_t:process { setsched };
> +

I'd recommend adding a test of quotaon as well.  It isn't technically a 
"filesystem" permission but you are already exercising the check as part 
of testing the other quota permissions and we don't yet have a test of 
it.  Then we'll be able to fully close 
https://github.com/SELinuxProject/selinux-testsuite/issues/26 when this 
gets merged.

Similarly, if you add a type_transition rule to your test policy and 
test that it is applied, we will be able to fully close 
https://github.com/SELinuxProject/selinux-testsuite/issues/22 along with
https://github.com/SELinuxProject/selinux-testsuite/issues/20.

Three for the price of one!



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-09 17:46   ` Stephen Smalley
@ 2020-01-09 17:51     ` Richard Haines
  0 siblings, 0 replies; 19+ messages in thread
From: Richard Haines @ 2020-01-09 17:51 UTC (permalink / raw)
  To: Stephen Smalley, selinux; +Cc: omosnace

On Thu, 2020-01-09 at 12:46 -0500, Stephen Smalley wrote:
> On 1/9/20 10:07 AM, Richard Haines wrote:
> > Test filesystem permissions and setfscreatecon(3).
> > 
> >  From kernels 5.5 filesystem { watch } is also tested.
> > 
> > Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> > ---
> > diff --git a/policy/test_filesystem.te b/policy/test_filesystem.te
> > new file mode 100644
> > index 0000000..2eee1fc
> > --- /dev/null
> > +++ b/policy/test_filesystem.te
> <snip>
> > +#################### Deny filesystem { quotamod }
> > ######################
> > +type test_filesystem_no_quotamod_t;
> > +domain_type(test_filesystem_no_quotamod_t)
> > +unconfined_runs_test(test_filesystem_no_quotamod_t)
> > +typeattribute test_filesystem_no_quotamod_t testdomain;
> > +typeattribute test_filesystem_no_quotamod_t filesystemdomain;
> > +
> > +allow test_filesystem_no_quotamod_t self:capability { sys_admin };
> > +allow test_filesystem_no_quotamod_t self:filesystem { quotaget
> > relabelto mount unmount};
> > +fs_mount_all_fs(test_filesystem_no_quotamod_t)
> > +fs_relabelfrom_all_fs(test_filesystem_no_quotamod_t)
> > +fs_associate(test_filesystem_no_quotamod_t)
> > +# Required as $private_path to quota files
> > +files_search_all(test_filesystem_no_quotamod_t)
> > +allow test_filesystem_no_quotamod_t self:dir { mounton };
> > +allow test_filesystem_no_quotamod_t test_file_t:dir { mounton
> > write remove_name rmdir };
> > +dontaudit test_filesystem_no_quotamod_t kernel_t:process {
> > setsched };
> > +
> > +#################### Deny filesystem { quotaget }
> > ######################
> > +type test_filesystem_no_quotaget_t;
> > +domain_type(test_filesystem_no_quotaget_t)
> > +unconfined_runs_test(test_filesystem_no_quotaget_t)
> > +typeattribute test_filesystem_no_quotaget_t testdomain;
> > +typeattribute test_filesystem_no_quotaget_t filesystemdomain;
> > +
> > +allow test_filesystem_no_quotaget_t self:capability { sys_admin };
> > +allow test_filesystem_no_quotaget_t self:filesystem { quotamod
> > relabelto mount unmount relabelfrom };
> > +allow test_filesystem_no_quotaget_t self:dir { mounton };
> > +allow test_filesystem_no_quotaget_t test_file_t:dir { mounton
> > write remove_name rmdir };
> > +allow test_filesystem_no_quotaget_t self:file { quotaon };
> > +fs_mount_all_fs(test_filesystem_no_quotaget_t)
> > +fs_relabelfrom_all_fs(test_filesystem_no_quotaget_t)
> > +fs_associate(test_filesystem_no_quotaget_t)
> > +# Required as $private_path to quota files
> > +files_search_all(test_filesystem_no_quotaget_t)
> > +# For running quotacheck(8)
> > +files_type(test_filesystem_no_quotaget_t)
> > +dontaudit test_filesystem_no_quotaget_t kernel_t:process {
> > setsched };
> > +
> 
> I'd recommend adding a test of quotaon as well.  It isn't technically
> a 
> "filesystem" permission but you are already exercising the check as
> part 
> of testing the other quota permissions and we don't yet have a test
> of 
> it.  Then we'll be able to fully close 
> https://github.com/SELinuxProject/selinux-testsuite/issues/26 when
> this 
> gets merged.
> 
> Similarly, if you add a type_transition rule to your test policy and 
> test that it is applied, we will be able to fully close 
> https://github.com/SELinuxProject/selinux-testsuite/issues/22 along
> with
> https://github.com/SELinuxProject/selinux-testsuite/issues/20.
> 
> Three for the price of one!

Okay, I'll add these next.
> 
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 0/1] selinux-testsuite: Add filesystem tests
  2020-01-09 15:07 [PATCH V2 0/1] selinux-testsuite: Add filesystem tests Richard Haines
  2020-01-09 15:07 ` [PATCH V2 1/1] " Richard Haines
@ 2020-01-09 18:04 ` Stephen Smalley
  2020-01-09 20:36   ` Richard Haines
  1 sibling, 1 reply; 19+ messages in thread
From: Stephen Smalley @ 2020-01-09 18:04 UTC (permalink / raw)
  To: Richard Haines, selinux; +Cc: omosnace

On 1/9/20 10:07 AM, Richard Haines wrote:
> These tests should cover all the areas in selinux/hooks.c that touch
> the 'filesystem' class. Each hooks.c function is listed in the 'test'
> script as there are some permissions that are checked in multiple places.
> 
> Tested on Fedora 31 and Rawhide (5.5 for the new watch perm).
> 
> V2 Changes:
> 1) If udisks(8) daemon is running, stop then restart after tests. The tests
>     run faster and stops the annoying habit of adding mounts to the 'files'
>     app on the desktop. Supports /usr/bin/systemctl or /usr/sbin/service
>     More importantly it stops interferance with the '*context=' tests as it
>     can cause intermittent failures. Tested by running 'test' in a continuous
>     loop with udisks enabled, and then again disabled.
>     Loop 200 times, with udisks failed between 1 to 70 iterations, without
>     udisks, no failures.

Wondering why udisks is causing failures - that seems like another bug.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 0/1] selinux-testsuite: Add filesystem tests
  2020-01-09 18:04 ` [PATCH V2 0/1] " Stephen Smalley
@ 2020-01-09 20:36   ` Richard Haines
  2020-01-09 21:01     ` Ondrej Mosnacek
  0 siblings, 1 reply; 19+ messages in thread
From: Richard Haines @ 2020-01-09 20:36 UTC (permalink / raw)
  To: Stephen Smalley, selinux; +Cc: omosnace

On Thu, 2020-01-09 at 13:04 -0500, Stephen Smalley wrote:
> On 1/9/20 10:07 AM, Richard Haines wrote:
> > These tests should cover all the areas in selinux/hooks.c that
> > touch
> > the 'filesystem' class. Each hooks.c function is listed in the
> > 'test'
> > script as there are some permissions that are checked in multiple
> > places.
> > 
> > Tested on Fedora 31 and Rawhide (5.5 for the new watch perm).
> > 
> > V2 Changes:
> > 1) If udisks(8) daemon is running, stop then restart after tests.
> > The tests
> >     run faster and stops the annoying habit of adding mounts to the
> > 'files'
> >     app on the desktop. Supports /usr/bin/systemctl or
> > /usr/sbin/service
> >     More importantly it stops interferance with the '*context='
> > tests as it
> >     can cause intermittent failures. Tested by running 'test' in a
> > continuous
> >     loop with udisks enabled, and then again disabled.
> >     Loop 200 times, with udisks failed between 1 to 70 iterations,
> > without
> >     udisks, no failures.
> 
> Wondering why udisks is causing failures - that seems like another
> bug.

With udisk2 enabled, 99% of the time the 'rootcontext=' test fails (the
1% is 'defcontext='). However if I run this test on its own, it does
not fail. If I add the 'context=' test before and run, the
'rootcontext=' will fail at some point.

If I add a short delay as shown in the 'context=' sequence, the fault
does not occur:
-- Start --
system("losetup -d $dev 2>/dev/null");
system("sleep 0.01");
get_loop_dev();
attach_dev();

# Mount again with no xttr support
$context2_opts =
"context=system_u:object_r:test_filesystem_context_t:s0";
-- End --

It could be udisk2 has a timing problem as the losetup(8) man page '-d' 
entry reads:
Note that since Linux v3.7 kernel uses "lazy  device destruction". The
detach operation does not return EBUSY error anymore if device is
actively used by system, but it  is  marked by autoclear flag and
destroyed later.

But then again it could be something else !!!!



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 0/1] selinux-testsuite: Add filesystem tests
  2020-01-09 20:36   ` Richard Haines
@ 2020-01-09 21:01     ` Ondrej Mosnacek
  2020-01-10 14:28       ` Richard Haines
  0 siblings, 1 reply; 19+ messages in thread
From: Ondrej Mosnacek @ 2020-01-09 21:01 UTC (permalink / raw)
  To: Richard Haines; +Cc: Stephen Smalley, SElinux list

On Thu, Jan 9, 2020 at 9:36 PM Richard Haines
<richard_c_haines@btinternet.com> wrote:
> On Thu, 2020-01-09 at 13:04 -0500, Stephen Smalley wrote:
> > On 1/9/20 10:07 AM, Richard Haines wrote:
> > > These tests should cover all the areas in selinux/hooks.c that
> > > touch
> > > the 'filesystem' class. Each hooks.c function is listed in the
> > > 'test'
> > > script as there are some permissions that are checked in multiple
> > > places.
> > >
> > > Tested on Fedora 31 and Rawhide (5.5 for the new watch perm).
> > >
> > > V2 Changes:
> > > 1) If udisks(8) daemon is running, stop then restart after tests.
> > > The tests
> > >     run faster and stops the annoying habit of adding mounts to the
> > > 'files'
> > >     app on the desktop. Supports /usr/bin/systemctl or
> > > /usr/sbin/service
> > >     More importantly it stops interferance with the '*context='
> > > tests as it
> > >     can cause intermittent failures. Tested by running 'test' in a
> > > continuous
> > >     loop with udisks enabled, and then again disabled.
> > >     Loop 200 times, with udisks failed between 1 to 70 iterations,
> > > without
> > >     udisks, no failures.
> >
> > Wondering why udisks is causing failures - that seems like another
> > bug.
>
> With udisk2 enabled, 99% of the time the 'rootcontext=' test fails (the
> 1% is 'defcontext='). However if I run this test on its own, it does
> not fail. If I add the 'context=' test before and run, the
> 'rootcontext=' will fail at some point.
>
> If I add a short delay as shown in the 'context=' sequence, the fault
> does not occur:
> -- Start --
> system("losetup -d $dev 2>/dev/null");
> system("sleep 0.01");
> get_loop_dev();
> attach_dev();

Can you try putting `udevadm settle` instead of the sleep there? I
remember having some issues with udev race conditions a long time ago
and I think that helped. (But I'm not sure at all if that's the right
fix...)

>
> # Mount again with no xttr support
> $context2_opts =
> "context=system_u:object_r:test_filesystem_context_t:s0";
> -- End --
>
> It could be udisk2 has a timing problem as the losetup(8) man page '-d'
> entry reads:
> Note that since Linux v3.7 kernel uses "lazy  device destruction". The
> detach operation does not return EBUSY error anymore if device is
> actively used by system, but it  is  marked by autoclear flag and
> destroyed later.
>
> But then again it could be something else !!!!
>
>

-- 
Ondrej Mosnacek <omosnace at redhat dot com>
Software Engineer, Security Technologies
Red Hat, Inc.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 0/1] selinux-testsuite: Add filesystem tests
  2020-01-09 21:01     ` Ondrej Mosnacek
@ 2020-01-10 14:28       ` Richard Haines
  0 siblings, 0 replies; 19+ messages in thread
From: Richard Haines @ 2020-01-10 14:28 UTC (permalink / raw)
  To: Ondrej Mosnacek; +Cc: Stephen Smalley, SElinux list

On Thu, 2020-01-09 at 22:01 +0100, Ondrej Mosnacek wrote:
> On Thu, Jan 9, 2020 at 9:36 PM Richard Haines
> <richard_c_haines@btinternet.com> wrote:
> > On Thu, 2020-01-09 at 13:04 -0500, Stephen Smalley wrote:
> > > On 1/9/20 10:07 AM, Richard Haines wrote:
> > > > These tests should cover all the areas in selinux/hooks.c that
> > > > touch
> > > > the 'filesystem' class. Each hooks.c function is listed in the
> > > > 'test'
> > > > script as there are some permissions that are checked in
> > > > multiple
> > > > places.
> > > > 
> > > > Tested on Fedora 31 and Rawhide (5.5 for the new watch perm).
> > > > 
> > > > V2 Changes:
> > > > 1) If udisks(8) daemon is running, stop then restart after
> > > > tests.
> > > > The tests
> > > >     run faster and stops the annoying habit of adding mounts to
> > > > the
> > > > 'files'
> > > >     app on the desktop. Supports /usr/bin/systemctl or
> > > > /usr/sbin/service
> > > >     More importantly it stops interferance with the '*context='
> > > > tests as it
> > > >     can cause intermittent failures. Tested by running 'test'
> > > > in a
> > > > continuous
> > > >     loop with udisks enabled, and then again disabled.
> > > >     Loop 200 times, with udisks failed between 1 to 70
> > > > iterations,
> > > > without
> > > >     udisks, no failures.
> > > 
> > > Wondering why udisks is causing failures - that seems like
> > > another
> > > bug.
> > 
> > With udisk2 enabled, 99% of the time the 'rootcontext=' test fails
> > (the
> > 1% is 'defcontext='). However if I run this test on its own, it
> > does
> > not fail. If I add the 'context=' test before and run, the
> > 'rootcontext=' will fail at some point.
> > 
> > If I add a short delay as shown in the 'context=' sequence, the
> > fault
> > does not occur:
> > -- Start --
> > system("losetup -d $dev 2>/dev/null");
> > system("sleep 0.01");
> > get_loop_dev();
> > attach_dev();
> 
> Can you try putting `udevadm settle` instead of the sleep there? I
> remember having some issues with udev race conditions a long time ago
> and I think that helped. (But I'm not sure at all if that's the right
> fix...)

Thanks - I had to add this to a couple of places and worked okay for
200 interations on Rawhide.

On the next patch version would you like the
udisks2_stop()/udisks2_restart() functions removed, left as is or set
as an option for the test when run locally ??

> 
> > # Mount again with no xttr support
> > $context2_opts =
> > "context=system_u:object_r:test_filesystem_context_t:s0";
> > -- End --
> > 
> > It could be udisk2 has a timing problem as the losetup(8) man page
> > '-d'
> > entry reads:
> > Note that since Linux v3.7 kernel uses "lazy  device destruction".
> > The
> > detach operation does not return EBUSY error anymore if device is
> > actively used by system, but it  is  marked by autoclear flag and
> > destroyed later.
> > 
> > But then again it could be something else !!!!
> > 
> > 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-09 17:19   ` Stephen Smalley
  2020-01-09 17:45     ` Richard Haines
@ 2020-01-10 18:09     ` Richard Haines
  2020-01-10 18:18       ` Stephen Smalley
  1 sibling, 1 reply; 19+ messages in thread
From: Richard Haines @ 2020-01-10 18:09 UTC (permalink / raw)
  To: Stephen Smalley, selinux; +Cc: omosnace

On Thu, 2020-01-09 at 12:19 -0500, Stephen Smalley wrote:
> On 1/9/20 10:07 AM, Richard Haines wrote:
> > Test filesystem permissions and setfscreatecon(3).
> > 
> >  From kernels 5.5 filesystem { watch } is also tested.
> > 
> > Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> > ---
> > diff --git a/policy/test_filesystem.te b/policy/test_filesystem.te
> > new file mode 100644
> > index 0000000..2eee1fc
> > --- /dev/null
> > +++ b/policy/test_filesystem.te
> > @@ -0,0 +1,324 @@
> > +#
> > +######### Test filesystem permissions policy module ##########
> > +#
> > +attribute filesystemdomain;
> > +
> > +#################### Create a test file context
> > ######################
> > +type test_filesystem_filecon_t;
> > +unconfined_runs_test(test_filesystem_filecon_t)
> > +
> > +################# Test all functions ##########################
> > +type test_filesystem_t;
> > +domain_type(test_filesystem_t)
> > +unconfined_runs_test(test_filesystem_t)
> > +typeattribute test_filesystem_t testdomain;
> > +typeattribute test_filesystem_t filesystemdomain;
> > +
> > +allow test_filesystem_t self:capability { sys_admin };
> > +allow test_filesystem_t self:filesystem { mount remount quotamod
> > relabelfrom relabelto unmount quotaget };
> > +allow test_filesystem_t self:dir { mounton add_name write };
> > +allow test_filesystem_t test_file_t:dir { mounton write
> > remove_name rmdir };
> > +# Create test file
> > +allow test_filesystem_t self:dir { add_name write };
> > +allow test_filesystem_t self:file { create relabelfrom relabelto
> > };
> > +
> > +fs_mount_all_fs(test_filesystem_t)
> > +fs_remount_all_fs(test_filesystem_t)
> > +fs_unmount_all_fs(test_filesystem_t)
> > +fs_relabelfrom_all_fs(test_filesystem_t)
> > +fs_get_xattr_fs_quotas(test_filesystem_t)
> > +files_search_all(test_filesystem_t)
> > +# Required for mount opts
> > "rootcontext=system_u:object_r:test_filesystem_t:s0";
> > +fs_associate(test_filesystem_t)
> > +fs_getattr_xattr_fs(test_filesystem_t)
> > +
> > +# For running quotacheck(8)
> > +files_type(test_filesystem_t)
> > +# Update quotas
> > +fs_set_all_quotas(test_filesystem_t)
> > +allow test_filesystem_t self:file { quotaon };
> > +# Create test file and change context:
> > +fs_associate(test_filesystem_filecon_t)
> > +allow test_filesystem_t test_filesystem_filecon_t:file { open read
> > getattr relabelto write };
> > +dontaudit test_filesystem_t kernel_t:process { setsched };
> 
> Why do you need these dontaudit statements?  It seems like a kernel
> bug 
> if something is triggering a setsched permission check on the
> kernel_t 
> domain?  Something the kernel module is doing during initialization?
> 

I've tracked this down to them all being called from block/ioprio.c
with: security_task_setioprio(task, ioprio) -> selinux_task_setioprio

Why the SECCLASS_PROCESS, PROCESS__SETSCHED I've no idea. The following
also use SET/GETSCHED permission:

selinux_task_getioprio, selinux_task_setnice, selinux_task_movememory



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-10 18:09     ` Richard Haines
@ 2020-01-10 18:18       ` Stephen Smalley
  2020-01-12 16:04         ` Richard Haines
  0 siblings, 1 reply; 19+ messages in thread
From: Stephen Smalley @ 2020-01-10 18:18 UTC (permalink / raw)
  To: Richard Haines, selinux; +Cc: omosnace

On 1/10/20 1:09 PM, Richard Haines wrote:
> On Thu, 2020-01-09 at 12:19 -0500, Stephen Smalley wrote:
>> On 1/9/20 10:07 AM, Richard Haines wrote:
>>> Test filesystem permissions and setfscreatecon(3).
>>>
>>>   From kernels 5.5 filesystem { watch } is also tested.
>>>
>>> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
>>> ---
>>> diff --git a/policy/test_filesystem.te b/policy/test_filesystem.te
>>> new file mode 100644
>>> index 0000000..2eee1fc
>>> --- /dev/null
>>> +++ b/policy/test_filesystem.te
>>> @@ -0,0 +1,324 @@
>>> +#
>>> +######### Test filesystem permissions policy module ##########
>>> +#
>>> +attribute filesystemdomain;
>>> +
>>> +#################### Create a test file context
>>> ######################
>>> +type test_filesystem_filecon_t;
>>> +unconfined_runs_test(test_filesystem_filecon_t)
>>> +
>>> +################# Test all functions ##########################
>>> +type test_filesystem_t;
>>> +domain_type(test_filesystem_t)
>>> +unconfined_runs_test(test_filesystem_t)
>>> +typeattribute test_filesystem_t testdomain;
>>> +typeattribute test_filesystem_t filesystemdomain;
>>> +
>>> +allow test_filesystem_t self:capability { sys_admin };
>>> +allow test_filesystem_t self:filesystem { mount remount quotamod
>>> relabelfrom relabelto unmount quotaget };
>>> +allow test_filesystem_t self:dir { mounton add_name write };
>>> +allow test_filesystem_t test_file_t:dir { mounton write
>>> remove_name rmdir };
>>> +# Create test file
>>> +allow test_filesystem_t self:dir { add_name write };
>>> +allow test_filesystem_t self:file { create relabelfrom relabelto
>>> };
>>> +
>>> +fs_mount_all_fs(test_filesystem_t)
>>> +fs_remount_all_fs(test_filesystem_t)
>>> +fs_unmount_all_fs(test_filesystem_t)
>>> +fs_relabelfrom_all_fs(test_filesystem_t)
>>> +fs_get_xattr_fs_quotas(test_filesystem_t)
>>> +files_search_all(test_filesystem_t)
>>> +# Required for mount opts
>>> "rootcontext=system_u:object_r:test_filesystem_t:s0";
>>> +fs_associate(test_filesystem_t)
>>> +fs_getattr_xattr_fs(test_filesystem_t)
>>> +
>>> +# For running quotacheck(8)
>>> +files_type(test_filesystem_t)
>>> +# Update quotas
>>> +fs_set_all_quotas(test_filesystem_t)
>>> +allow test_filesystem_t self:file { quotaon };
>>> +# Create test file and change context:
>>> +fs_associate(test_filesystem_filecon_t)
>>> +allow test_filesystem_t test_filesystem_filecon_t:file { open read
>>> getattr relabelto write };
>>> +dontaudit test_filesystem_t kernel_t:process { setsched };
>>
>> Why do you need these dontaudit statements?  It seems like a kernel
>> bug
>> if something is triggering a setsched permission check on the
>> kernel_t
>> domain?  Something the kernel module is doing during initialization?
>>
> 
> I've tracked this down to them all being called from block/ioprio.c
> with: security_task_setioprio(task, ioprio) -> selinux_task_setioprio
> 
> Why the SECCLASS_PROCESS, PROCESS__SETSCHED I've no idea. The following
> also use SET/GETSCHED permission:
> 
> selinux_task_getioprio, selinux_task_setnice, selinux_task_movememory

The confusing bit is that it is between test_filesystem_t and kernel_t. 
If the process was setting its own ioprio, then I'd expect to see the 
denial between test_filesystem_t and test_filesystem_t aka self.  If the 
process inserted a kernel module and the module initializer spawned a 
kernel thread that set its ioprio, I would expect it to be kernel_t to 
kernel_t.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-10 18:18       ` Stephen Smalley
@ 2020-01-12 16:04         ` Richard Haines
  2020-01-13 13:52           ` Stephen Smalley
  0 siblings, 1 reply; 19+ messages in thread
From: Richard Haines @ 2020-01-12 16:04 UTC (permalink / raw)
  To: Stephen Smalley, selinux; +Cc: omosnace

On Fri, 2020-01-10 at 13:18 -0500, Stephen Smalley wrote:
> On 1/10/20 1:09 PM, Richard Haines wrote:
> > On Thu, 2020-01-09 at 12:19 -0500, Stephen Smalley wrote:
> > > On 1/9/20 10:07 AM, Richard Haines wrote:
> > > > Test filesystem permissions and setfscreatecon(3).
> > > > 
> > > >   From kernels 5.5 filesystem { watch } is also tested.
> > > > 
> > > > Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> > > > ---
> > > > diff --git a/policy/test_filesystem.te
> > > > b/policy/test_filesystem.te
> > > > new file mode 100644
> > > > index 0000000..2eee1fc
> > > > --- /dev/null
> > > > +++ b/policy/test_filesystem.te
> > > > @@ -0,0 +1,324 @@
> > > > +#
> > > > +######### Test filesystem permissions policy module ##########
> > > > +#
> > > > +attribute filesystemdomain;
> > > > +
> > > > +#################### Create a test file context
> > > > ######################
> > > > +type test_filesystem_filecon_t;
> > > > +unconfined_runs_test(test_filesystem_filecon_t)
> > > > +
> > > > +################# Test all functions
> > > > ##########################
> > > > +type test_filesystem_t;
> > > > +domain_type(test_filesystem_t)
> > > > +unconfined_runs_test(test_filesystem_t)
> > > > +typeattribute test_filesystem_t testdomain;
> > > > +typeattribute test_filesystem_t filesystemdomain;
> > > > +
> > > > +allow test_filesystem_t self:capability { sys_admin };
> > > > +allow test_filesystem_t self:filesystem { mount remount
> > > > quotamod
> > > > relabelfrom relabelto unmount quotaget };
> > > > +allow test_filesystem_t self:dir { mounton add_name write };
> > > > +allow test_filesystem_t test_file_t:dir { mounton write
> > > > remove_name rmdir };
> > > > +# Create test file
> > > > +allow test_filesystem_t self:dir { add_name write };
> > > > +allow test_filesystem_t self:file { create relabelfrom
> > > > relabelto
> > > > };
> > > > +
> > > > +fs_mount_all_fs(test_filesystem_t)
> > > > +fs_remount_all_fs(test_filesystem_t)
> > > > +fs_unmount_all_fs(test_filesystem_t)
> > > > +fs_relabelfrom_all_fs(test_filesystem_t)
> > > > +fs_get_xattr_fs_quotas(test_filesystem_t)
> > > > +files_search_all(test_filesystem_t)
> > > > +# Required for mount opts
> > > > "rootcontext=system_u:object_r:test_filesystem_t:s0";
> > > > +fs_associate(test_filesystem_t)
> > > > +fs_getattr_xattr_fs(test_filesystem_t)
> > > > +
> > > > +# For running quotacheck(8)
> > > > +files_type(test_filesystem_t)
> > > > +# Update quotas
> > > > +fs_set_all_quotas(test_filesystem_t)
> > > > +allow test_filesystem_t self:file { quotaon };
> > > > +# Create test file and change context:
> > > > +fs_associate(test_filesystem_filecon_t)
> > > > +allow test_filesystem_t test_filesystem_filecon_t:file { open
> > > > read
> > > > getattr relabelto write };
> > > > +dontaudit test_filesystem_t kernel_t:process { setsched };
> > > 
> > > Why do you need these dontaudit statements?  It seems like a
> > > kernel
> > > bug
> > > if something is triggering a setsched permission check on the
> > > kernel_t
> > > domain?  Something the kernel module is doing during
> > > initialization?
> > > 
> > 
> > I've tracked this down to them all being called from block/ioprio.c
> > with: security_task_setioprio(task, ioprio) ->
> > selinux_task_setioprio
> > 
> > Why the SECCLASS_PROCESS, PROCESS__SETSCHED I've no idea. The
> > following
> > also use SET/GETSCHED permission:
> > 
> > selinux_task_getioprio, selinux_task_setnice,
> > selinux_task_movememory
> 
> The confusing bit is that it is between test_filesystem_t and
> kernel_t. 
> If the process was setting its own ioprio, then I'd expect to see
> the 
> denial between test_filesystem_t and test_filesystem_t aka self.  If
> the 
> process inserted a kernel module and the module initializer spawned
> a 
> kernel thread that set its ioprio, I would expect it to be kernel_t
> to 
> kernel_t.

Some more info on who calls set_task_ioprio:

fs/ext4/super.c calls 'set_task_ioprio' in two places using:
    set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
The return codes are not checked. This code was added 11 years ago.

fs/btrfs/reada.c also calls 'set_task_ioprio' in two places using:
    set_task_ioprio(current, BTRFS_IOPRIO_READA);
The return codes are not checked.

As can be seen the ext4 module does not use 'current'. I have patched
kernel 5.5-rc5 to use 'current' and it now works as you expected. Also
the kernel_t:process { setsched } rules can be removed.
As the problem will exist for some time, I've added to the test policy:
    kernel_dontaudit_setsched(filesystemdomain)

It appears that most of the refpolicy modules do the same.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-12 16:04         ` Richard Haines
@ 2020-01-13 13:52           ` Stephen Smalley
  2020-01-13 14:07             ` Stephen Smalley
  0 siblings, 1 reply; 19+ messages in thread
From: Stephen Smalley @ 2020-01-13 13:52 UTC (permalink / raw)
  To: Richard Haines, selinux; +Cc: omosnace, Paul Moore

On 1/12/20 11:04 AM, Richard Haines wrote:
> On Fri, 2020-01-10 at 13:18 -0500, Stephen Smalley wrote:
>> On 1/10/20 1:09 PM, Richard Haines wrote:
>>> On Thu, 2020-01-09 at 12:19 -0500, Stephen Smalley wrote:
>>>> On 1/9/20 10:07 AM, Richard Haines wrote:
>>>>> Test filesystem permissions and setfscreatecon(3).
>>>>>
>>>>>    From kernels 5.5 filesystem { watch } is also tested.
>>>>>
>>>>> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
>>>>> ---
>>>>> diff --git a/policy/test_filesystem.te
>>>>> b/policy/test_filesystem.te
>>>>> new file mode 100644
>>>>> index 0000000..2eee1fc
>>>>> --- /dev/null
>>>>> +++ b/policy/test_filesystem.te
>>>>> @@ -0,0 +1,324 @@
>>>>> +#
>>>>> +######### Test filesystem permissions policy module ##########
>>>>> +#
>>>>> +attribute filesystemdomain;
>>>>> +
>>>>> +#################### Create a test file context
>>>>> ######################
>>>>> +type test_filesystem_filecon_t;
>>>>> +unconfined_runs_test(test_filesystem_filecon_t)
>>>>> +
>>>>> +################# Test all functions
>>>>> ##########################
>>>>> +type test_filesystem_t;
>>>>> +domain_type(test_filesystem_t)
>>>>> +unconfined_runs_test(test_filesystem_t)
>>>>> +typeattribute test_filesystem_t testdomain;
>>>>> +typeattribute test_filesystem_t filesystemdomain;
>>>>> +
>>>>> +allow test_filesystem_t self:capability { sys_admin };
>>>>> +allow test_filesystem_t self:filesystem { mount remount
>>>>> quotamod
>>>>> relabelfrom relabelto unmount quotaget };
>>>>> +allow test_filesystem_t self:dir { mounton add_name write };
>>>>> +allow test_filesystem_t test_file_t:dir { mounton write
>>>>> remove_name rmdir };
>>>>> +# Create test file
>>>>> +allow test_filesystem_t self:dir { add_name write };
>>>>> +allow test_filesystem_t self:file { create relabelfrom
>>>>> relabelto
>>>>> };
>>>>> +
>>>>> +fs_mount_all_fs(test_filesystem_t)
>>>>> +fs_remount_all_fs(test_filesystem_t)
>>>>> +fs_unmount_all_fs(test_filesystem_t)
>>>>> +fs_relabelfrom_all_fs(test_filesystem_t)
>>>>> +fs_get_xattr_fs_quotas(test_filesystem_t)
>>>>> +files_search_all(test_filesystem_t)
>>>>> +# Required for mount opts
>>>>> "rootcontext=system_u:object_r:test_filesystem_t:s0";
>>>>> +fs_associate(test_filesystem_t)
>>>>> +fs_getattr_xattr_fs(test_filesystem_t)
>>>>> +
>>>>> +# For running quotacheck(8)
>>>>> +files_type(test_filesystem_t)
>>>>> +# Update quotas
>>>>> +fs_set_all_quotas(test_filesystem_t)
>>>>> +allow test_filesystem_t self:file { quotaon };
>>>>> +# Create test file and change context:
>>>>> +fs_associate(test_filesystem_filecon_t)
>>>>> +allow test_filesystem_t test_filesystem_filecon_t:file { open
>>>>> read
>>>>> getattr relabelto write };
>>>>> +dontaudit test_filesystem_t kernel_t:process { setsched };
>>>>
>>>> Why do you need these dontaudit statements?  It seems like a
>>>> kernel
>>>> bug
>>>> if something is triggering a setsched permission check on the
>>>> kernel_t
>>>> domain?  Something the kernel module is doing during
>>>> initialization?
>>>>
>>>
>>> I've tracked this down to them all being called from block/ioprio.c
>>> with: security_task_setioprio(task, ioprio) ->
>>> selinux_task_setioprio
>>>
>>> Why the SECCLASS_PROCESS, PROCESS__SETSCHED I've no idea. The
>>> following
>>> also use SET/GETSCHED permission:
>>>
>>> selinux_task_getioprio, selinux_task_setnice,
>>> selinux_task_movememory
>>
>> The confusing bit is that it is between test_filesystem_t and
>> kernel_t.
>> If the process was setting its own ioprio, then I'd expect to see
>> the
>> denial between test_filesystem_t and test_filesystem_t aka self.  If
>> the
>> process inserted a kernel module and the module initializer spawned
>> a
>> kernel thread that set its ioprio, I would expect it to be kernel_t
>> to
>> kernel_t.
> 
> Some more info on who calls set_task_ioprio:
> 
> fs/ext4/super.c calls 'set_task_ioprio' in two places using:
>      set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
> The return codes are not checked. This code was added 11 years ago.
> 
> fs/btrfs/reada.c also calls 'set_task_ioprio' in two places using:
>      set_task_ioprio(current, BTRFS_IOPRIO_READA);
> The return codes are not checked.
> 
> As can be seen the ext4 module does not use 'current'. I have patched
> kernel 5.5-rc5 to use 'current' and it now works as you expected. Also
> the kernel_t:process { setsched } rules can be removed.
> As the problem will exist for some time, I've added to the test policy:
>      kernel_dontaudit_setsched(filesystemdomain)
> 
> It appears that most of the refpolicy modules do the same.

This seems like a kernel bug to me. I assume that these filesystems 
expect the I/O priority to be always set in these cases irrespective of 
the permissions of the current process.  Either they should be using 
some internal helper function ala a new set_task_ioprio_noperm() that 
skips permission checking or they should be temporarily overriding their 
cred to the init cred before doing this.  Probably a topic for 
linux-fsdevel and/or the respective per-filesystem mailing lists.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-13 13:52           ` Stephen Smalley
@ 2020-01-13 14:07             ` Stephen Smalley
  2020-01-13 18:00               ` Richard Haines
  0 siblings, 1 reply; 19+ messages in thread
From: Stephen Smalley @ 2020-01-13 14:07 UTC (permalink / raw)
  To: Richard Haines, selinux; +Cc: omosnace, Paul Moore

On 1/13/20 8:52 AM, Stephen Smalley wrote:
> On 1/12/20 11:04 AM, Richard Haines wrote:
>> On Fri, 2020-01-10 at 13:18 -0500, Stephen Smalley wrote:
>>> On 1/10/20 1:09 PM, Richard Haines wrote:
>>>> On Thu, 2020-01-09 at 12:19 -0500, Stephen Smalley wrote:
>>>>> On 1/9/20 10:07 AM, Richard Haines wrote:
>>>>>> Test filesystem permissions and setfscreatecon(3).
>>>>>>
>>>>>>    From kernels 5.5 filesystem { watch } is also tested.
>>>>>>
>>>>>> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
>>>>>> ---
>>>>>> diff --git a/policy/test_filesystem.te
>>>>>> b/policy/test_filesystem.te
>>>>>> new file mode 100644
>>>>>> index 0000000..2eee1fc
>>>>>> --- /dev/null
>>>>>> +++ b/policy/test_filesystem.te
>>>>>> @@ -0,0 +1,324 @@
>>>>>> +#
>>>>>> +######### Test filesystem permissions policy module ##########
>>>>>> +#
>>>>>> +attribute filesystemdomain;
>>>>>> +
>>>>>> +#################### Create a test file context
>>>>>> ######################
>>>>>> +type test_filesystem_filecon_t;
>>>>>> +unconfined_runs_test(test_filesystem_filecon_t)
>>>>>> +
>>>>>> +################# Test all functions
>>>>>> ##########################
>>>>>> +type test_filesystem_t;
>>>>>> +domain_type(test_filesystem_t)
>>>>>> +unconfined_runs_test(test_filesystem_t)
>>>>>> +typeattribute test_filesystem_t testdomain;
>>>>>> +typeattribute test_filesystem_t filesystemdomain;
>>>>>> +
>>>>>> +allow test_filesystem_t self:capability { sys_admin };
>>>>>> +allow test_filesystem_t self:filesystem { mount remount
>>>>>> quotamod
>>>>>> relabelfrom relabelto unmount quotaget };
>>>>>> +allow test_filesystem_t self:dir { mounton add_name write };
>>>>>> +allow test_filesystem_t test_file_t:dir { mounton write
>>>>>> remove_name rmdir };
>>>>>> +# Create test file
>>>>>> +allow test_filesystem_t self:dir { add_name write };
>>>>>> +allow test_filesystem_t self:file { create relabelfrom
>>>>>> relabelto
>>>>>> };
>>>>>> +
>>>>>> +fs_mount_all_fs(test_filesystem_t)
>>>>>> +fs_remount_all_fs(test_filesystem_t)
>>>>>> +fs_unmount_all_fs(test_filesystem_t)
>>>>>> +fs_relabelfrom_all_fs(test_filesystem_t)
>>>>>> +fs_get_xattr_fs_quotas(test_filesystem_t)
>>>>>> +files_search_all(test_filesystem_t)
>>>>>> +# Required for mount opts
>>>>>> "rootcontext=system_u:object_r:test_filesystem_t:s0";
>>>>>> +fs_associate(test_filesystem_t)
>>>>>> +fs_getattr_xattr_fs(test_filesystem_t)
>>>>>> +
>>>>>> +# For running quotacheck(8)
>>>>>> +files_type(test_filesystem_t)
>>>>>> +# Update quotas
>>>>>> +fs_set_all_quotas(test_filesystem_t)
>>>>>> +allow test_filesystem_t self:file { quotaon };
>>>>>> +# Create test file and change context:
>>>>>> +fs_associate(test_filesystem_filecon_t)
>>>>>> +allow test_filesystem_t test_filesystem_filecon_t:file { open
>>>>>> read
>>>>>> getattr relabelto write };
>>>>>> +dontaudit test_filesystem_t kernel_t:process { setsched };
>>>>>
>>>>> Why do you need these dontaudit statements?  It seems like a
>>>>> kernel
>>>>> bug
>>>>> if something is triggering a setsched permission check on the
>>>>> kernel_t
>>>>> domain?  Something the kernel module is doing during
>>>>> initialization?
>>>>>
>>>>
>>>> I've tracked this down to them all being called from block/ioprio.c
>>>> with: security_task_setioprio(task, ioprio) ->
>>>> selinux_task_setioprio
>>>>
>>>> Why the SECCLASS_PROCESS, PROCESS__SETSCHED I've no idea. The
>>>> following
>>>> also use SET/GETSCHED permission:
>>>>
>>>> selinux_task_getioprio, selinux_task_setnice,
>>>> selinux_task_movememory
>>>
>>> The confusing bit is that it is between test_filesystem_t and
>>> kernel_t.
>>> If the process was setting its own ioprio, then I'd expect to see
>>> the
>>> denial between test_filesystem_t and test_filesystem_t aka self.  If
>>> the
>>> process inserted a kernel module and the module initializer spawned
>>> a
>>> kernel thread that set its ioprio, I would expect it to be kernel_t
>>> to
>>> kernel_t.
>>
>> Some more info on who calls set_task_ioprio:
>>
>> fs/ext4/super.c calls 'set_task_ioprio' in two places using:
>>      set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
>> The return codes are not checked. This code was added 11 years ago.
>>
>> fs/btrfs/reada.c also calls 'set_task_ioprio' in two places using:
>>      set_task_ioprio(current, BTRFS_IOPRIO_READA);
>> The return codes are not checked.
>>
>> As can be seen the ext4 module does not use 'current'. I have patched
>> kernel 5.5-rc5 to use 'current' and it now works as you expected. Also
>> the kernel_t:process { setsched } rules can be removed.
>> As the problem will exist for some time, I've added to the test policy:
>>      kernel_dontaudit_setsched(filesystemdomain)
>>
>> It appears that most of the refpolicy modules do the same.
> 
> This seems like a kernel bug to me. I assume that these filesystems 
> expect the I/O priority to be always set in these cases irrespective of 
> the permissions of the current process.  Either they should be using 
> some internal helper function ala a new set_task_ioprio_noperm() that 
> skips permission checking or they should be temporarily overriding their 
> cred to the init cred before doing this.  Probably a topic for 
> linux-fsdevel and/or the respective per-filesystem mailing lists.

Also, looks like kernel_dontaudit_setsched() isn't defined by upstream 
refpolicy so you'll need the usual ifdefery in test_policy.if to allow 
this to build against refpolicy to appease travis-ci.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-13 14:07             ` Stephen Smalley
@ 2020-01-13 18:00               ` Richard Haines
  2020-01-13 18:54                 ` Stephen Smalley
  0 siblings, 1 reply; 19+ messages in thread
From: Richard Haines @ 2020-01-13 18:00 UTC (permalink / raw)
  To: Stephen Smalley, selinux; +Cc: omosnace, Paul Moore

On Mon, 2020-01-13 at 09:07 -0500, Stephen Smalley wrote:
> On 1/13/20 8:52 AM, Stephen Smalley wrote:
> > On 1/12/20 11:04 AM, Richard Haines wrote:
> > > On Fri, 2020-01-10 at 13:18 -0500, Stephen Smalley wrote:
> > > > On 1/10/20 1:09 PM, Richard Haines wrote:
> > > > > On Thu, 2020-01-09 at 12:19 -0500, Stephen Smalley wrote:
> > > > > > On 1/9/20 10:07 AM, Richard Haines wrote:
> > > > > > > Test filesystem permissions and setfscreatecon(3).
> > > > > > > 
> > > > > > >    From kernels 5.5 filesystem { watch } is also tested.
> > > > > > > 
> > > > > > > Signed-off-by: Richard Haines <
> > > > > > > richard_c_haines@btinternet.com>
> > > > > > > ---
> > > > > > > diff --git a/policy/test_filesystem.te
> > > > > > > b/policy/test_filesystem.te
> > > > > > > new file mode 100644
> > > > > > > index 0000000..2eee1fc
> > > > > > > --- /dev/null
> > > > > > > +++ b/policy/test_filesystem.te
> > > > > > > @@ -0,0 +1,324 @@
> > > > > > > +#
> > > > > > > +######### Test filesystem permissions policy module
> > > > > > > ##########
> > > > > > > +#
> > > > > > > +attribute filesystemdomain;
> > > > > > > +
> > > > > > > +#################### Create a test file context
> > > > > > > ######################
> > > > > > > +type test_filesystem_filecon_t;
> > > > > > > +unconfined_runs_test(test_filesystem_filecon_t)
> > > > > > > +
> > > > > > > +################# Test all functions
> > > > > > > ##########################
> > > > > > > +type test_filesystem_t;
> > > > > > > +domain_type(test_filesystem_t)
> > > > > > > +unconfined_runs_test(test_filesystem_t)
> > > > > > > +typeattribute test_filesystem_t testdomain;
> > > > > > > +typeattribute test_filesystem_t filesystemdomain;
> > > > > > > +
> > > > > > > +allow test_filesystem_t self:capability { sys_admin };
> > > > > > > +allow test_filesystem_t self:filesystem { mount remount
> > > > > > > quotamod
> > > > > > > relabelfrom relabelto unmount quotaget };
> > > > > > > +allow test_filesystem_t self:dir { mounton add_name
> > > > > > > write };
> > > > > > > +allow test_filesystem_t test_file_t:dir { mounton write
> > > > > > > remove_name rmdir };
> > > > > > > +# Create test file
> > > > > > > +allow test_filesystem_t self:dir { add_name write };
> > > > > > > +allow test_filesystem_t self:file { create relabelfrom
> > > > > > > relabelto
> > > > > > > };
> > > > > > > +
> > > > > > > +fs_mount_all_fs(test_filesystem_t)
> > > > > > > +fs_remount_all_fs(test_filesystem_t)
> > > > > > > +fs_unmount_all_fs(test_filesystem_t)
> > > > > > > +fs_relabelfrom_all_fs(test_filesystem_t)
> > > > > > > +fs_get_xattr_fs_quotas(test_filesystem_t)
> > > > > > > +files_search_all(test_filesystem_t)
> > > > > > > +# Required for mount opts
> > > > > > > "rootcontext=system_u:object_r:test_filesystem_t:s0";
> > > > > > > +fs_associate(test_filesystem_t)
> > > > > > > +fs_getattr_xattr_fs(test_filesystem_t)
> > > > > > > +
> > > > > > > +# For running quotacheck(8)
> > > > > > > +files_type(test_filesystem_t)
> > > > > > > +# Update quotas
> > > > > > > +fs_set_all_quotas(test_filesystem_t)
> > > > > > > +allow test_filesystem_t self:file { quotaon };
> > > > > > > +# Create test file and change context:
> > > > > > > +fs_associate(test_filesystem_filecon_t)
> > > > > > > +allow test_filesystem_t test_filesystem_filecon_t:file {
> > > > > > > open
> > > > > > > read
> > > > > > > getattr relabelto write };
> > > > > > > +dontaudit test_filesystem_t kernel_t:process { setsched
> > > > > > > };
> > > > > > 
> > > > > > Why do you need these dontaudit statements?  It seems like
> > > > > > a
> > > > > > kernel
> > > > > > bug
> > > > > > if something is triggering a setsched permission check on
> > > > > > the
> > > > > > kernel_t
> > > > > > domain?  Something the kernel module is doing during
> > > > > > initialization?
> > > > > > 
> > > > > 
> > > > > I've tracked this down to them all being called from
> > > > > block/ioprio.c
> > > > > with: security_task_setioprio(task, ioprio) ->
> > > > > selinux_task_setioprio
> > > > > 
> > > > > Why the SECCLASS_PROCESS, PROCESS__SETSCHED I've no idea. The
> > > > > following
> > > > > also use SET/GETSCHED permission:
> > > > > 
> > > > > selinux_task_getioprio, selinux_task_setnice,
> > > > > selinux_task_movememory
> > > > 
> > > > The confusing bit is that it is between test_filesystem_t and
> > > > kernel_t.
> > > > If the process was setting its own ioprio, then I'd expect to
> > > > see
> > > > the
> > > > denial between test_filesystem_t and test_filesystem_t aka
> > > > self.  If
> > > > the
> > > > process inserted a kernel module and the module initializer
> > > > spawned
> > > > a
> > > > kernel thread that set its ioprio, I would expect it to be
> > > > kernel_t
> > > > to
> > > > kernel_t.
> > > 
> > > Some more info on who calls set_task_ioprio:
> > > 
> > > fs/ext4/super.c calls 'set_task_ioprio' in two places using:
> > >      set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
> > > The return codes are not checked. This code was added 11 years
> > > ago.
> > > 
> > > fs/btrfs/reada.c also calls 'set_task_ioprio' in two places
> > > using:
> > >      set_task_ioprio(current, BTRFS_IOPRIO_READA);
> > > The return codes are not checked.
> > > 
> > > As can be seen the ext4 module does not use 'current'. I have
> > > patched
> > > kernel 5.5-rc5 to use 'current' and it now works as you expected.
> > > Also
> > > the kernel_t:process { setsched } rules can be removed.
> > > As the problem will exist for some time, I've added to the test
> > > policy:
> > >      kernel_dontaudit_setsched(filesystemdomain)
> > > 
> > > It appears that most of the refpolicy modules do the same.
> > 
> > This seems like a kernel bug to me. I assume that these
> > filesystems 
> > expect the I/O priority to be always set in these cases
> > irrespective of 
> > the permissions of the current process.  Either they should be
> > using 
> > some internal helper function ala a new set_task_ioprio_noperm()
> > that 
> > skips permission checking or they should be temporarily overriding
> > their 
> > cred to the init cred before doing this.  Probably a topic for 
> > linux-fsdevel and/or the respective per-filesystem mailing lists.
> 
> Also, looks like kernel_dontaudit_setsched() isn't defined by
> upstream 
> refpolicy so you'll need the usual ifdefery in test_policy.if to
> allow 
> this to build against refpolicy to appease travis-ci.
> 

I'll change this to domain_setpriority_all_domains() in V4 as that is
in both Fedora and Ref Policy.

> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 1/1] selinux-testsuite: Add filesystem tests
  2020-01-13 18:00               ` Richard Haines
@ 2020-01-13 18:54                 ` Stephen Smalley
  0 siblings, 0 replies; 19+ messages in thread
From: Stephen Smalley @ 2020-01-13 18:54 UTC (permalink / raw)
  To: Richard Haines, selinux; +Cc: omosnace, Paul Moore

On 1/13/20 1:00 PM, Richard Haines wrote:
> On Mon, 2020-01-13 at 09:07 -0500, Stephen Smalley wrote:
>> On 1/13/20 8:52 AM, Stephen Smalley wrote:
>>> On 1/12/20 11:04 AM, Richard Haines wrote:
>>>> On Fri, 2020-01-10 at 13:18 -0500, Stephen Smalley wrote:
>>>>> On 1/10/20 1:09 PM, Richard Haines wrote:
>>>>>> On Thu, 2020-01-09 at 12:19 -0500, Stephen Smalley wrote:
>>>>>>> On 1/9/20 10:07 AM, Richard Haines wrote:
>>>>>>>> Test filesystem permissions and setfscreatecon(3).
>>>>>>>>
>>>>>>>>     From kernels 5.5 filesystem { watch } is also tested.
>>>>>>>>
>>>>>>>> Signed-off-by: Richard Haines <
>>>>>>>> richard_c_haines@btinternet.com>
>>>>>>>> ---
>>>>>>>> diff --git a/policy/test_filesystem.te
>>>>>>>> b/policy/test_filesystem.te
>>>>>>>> new file mode 100644
>>>>>>>> index 0000000..2eee1fc
>>>>>>>> --- /dev/null
>>>>>>>> +++ b/policy/test_filesystem.te
>>>>>>>> @@ -0,0 +1,324 @@
>>>>>>>> +#
>>>>>>>> +######### Test filesystem permissions policy module
>>>>>>>> ##########
>>>>>>>> +#
>>>>>>>> +attribute filesystemdomain;
>>>>>>>> +
>>>>>>>> +#################### Create a test file context
>>>>>>>> ######################
>>>>>>>> +type test_filesystem_filecon_t;
>>>>>>>> +unconfined_runs_test(test_filesystem_filecon_t)
>>>>>>>> +
>>>>>>>> +################# Test all functions
>>>>>>>> ##########################
>>>>>>>> +type test_filesystem_t;
>>>>>>>> +domain_type(test_filesystem_t)
>>>>>>>> +unconfined_runs_test(test_filesystem_t)
>>>>>>>> +typeattribute test_filesystem_t testdomain;
>>>>>>>> +typeattribute test_filesystem_t filesystemdomain;
>>>>>>>> +
>>>>>>>> +allow test_filesystem_t self:capability { sys_admin };
>>>>>>>> +allow test_filesystem_t self:filesystem { mount remount
>>>>>>>> quotamod
>>>>>>>> relabelfrom relabelto unmount quotaget };
>>>>>>>> +allow test_filesystem_t self:dir { mounton add_name
>>>>>>>> write };
>>>>>>>> +allow test_filesystem_t test_file_t:dir { mounton write
>>>>>>>> remove_name rmdir };
>>>>>>>> +# Create test file
>>>>>>>> +allow test_filesystem_t self:dir { add_name write };
>>>>>>>> +allow test_filesystem_t self:file { create relabelfrom
>>>>>>>> relabelto
>>>>>>>> };
>>>>>>>> +
>>>>>>>> +fs_mount_all_fs(test_filesystem_t)
>>>>>>>> +fs_remount_all_fs(test_filesystem_t)
>>>>>>>> +fs_unmount_all_fs(test_filesystem_t)
>>>>>>>> +fs_relabelfrom_all_fs(test_filesystem_t)
>>>>>>>> +fs_get_xattr_fs_quotas(test_filesystem_t)
>>>>>>>> +files_search_all(test_filesystem_t)
>>>>>>>> +# Required for mount opts
>>>>>>>> "rootcontext=system_u:object_r:test_filesystem_t:s0";
>>>>>>>> +fs_associate(test_filesystem_t)
>>>>>>>> +fs_getattr_xattr_fs(test_filesystem_t)
>>>>>>>> +
>>>>>>>> +# For running quotacheck(8)
>>>>>>>> +files_type(test_filesystem_t)
>>>>>>>> +# Update quotas
>>>>>>>> +fs_set_all_quotas(test_filesystem_t)
>>>>>>>> +allow test_filesystem_t self:file { quotaon };
>>>>>>>> +# Create test file and change context:
>>>>>>>> +fs_associate(test_filesystem_filecon_t)
>>>>>>>> +allow test_filesystem_t test_filesystem_filecon_t:file {
>>>>>>>> open
>>>>>>>> read
>>>>>>>> getattr relabelto write };
>>>>>>>> +dontaudit test_filesystem_t kernel_t:process { setsched
>>>>>>>> };
>>>>>>>
>>>>>>> Why do you need these dontaudit statements?  It seems like
>>>>>>> a
>>>>>>> kernel
>>>>>>> bug
>>>>>>> if something is triggering a setsched permission check on
>>>>>>> the
>>>>>>> kernel_t
>>>>>>> domain?  Something the kernel module is doing during
>>>>>>> initialization?
>>>>>>>
>>>>>>
>>>>>> I've tracked this down to them all being called from
>>>>>> block/ioprio.c
>>>>>> with: security_task_setioprio(task, ioprio) ->
>>>>>> selinux_task_setioprio
>>>>>>
>>>>>> Why the SECCLASS_PROCESS, PROCESS__SETSCHED I've no idea. The
>>>>>> following
>>>>>> also use SET/GETSCHED permission:
>>>>>>
>>>>>> selinux_task_getioprio, selinux_task_setnice,
>>>>>> selinux_task_movememory
>>>>>
>>>>> The confusing bit is that it is between test_filesystem_t and
>>>>> kernel_t.
>>>>> If the process was setting its own ioprio, then I'd expect to
>>>>> see
>>>>> the
>>>>> denial between test_filesystem_t and test_filesystem_t aka
>>>>> self.  If
>>>>> the
>>>>> process inserted a kernel module and the module initializer
>>>>> spawned
>>>>> a
>>>>> kernel thread that set its ioprio, I would expect it to be
>>>>> kernel_t
>>>>> to
>>>>> kernel_t.
>>>>
>>>> Some more info on who calls set_task_ioprio:
>>>>
>>>> fs/ext4/super.c calls 'set_task_ioprio' in two places using:
>>>>       set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
>>>> The return codes are not checked. This code was added 11 years
>>>> ago.
>>>>
>>>> fs/btrfs/reada.c also calls 'set_task_ioprio' in two places
>>>> using:
>>>>       set_task_ioprio(current, BTRFS_IOPRIO_READA);
>>>> The return codes are not checked.
>>>>
>>>> As can be seen the ext4 module does not use 'current'. I have
>>>> patched
>>>> kernel 5.5-rc5 to use 'current' and it now works as you expected.
>>>> Also
>>>> the kernel_t:process { setsched } rules can be removed.
>>>> As the problem will exist for some time, I've added to the test
>>>> policy:
>>>>       kernel_dontaudit_setsched(filesystemdomain)
>>>>
>>>> It appears that most of the refpolicy modules do the same.
>>>
>>> This seems like a kernel bug to me. I assume that these
>>> filesystems
>>> expect the I/O priority to be always set in these cases
>>> irrespective of
>>> the permissions of the current process.  Either they should be
>>> using
>>> some internal helper function ala a new set_task_ioprio_noperm()
>>> that
>>> skips permission checking or they should be temporarily overriding
>>> their
>>> cred to the init cred before doing this.  Probably a topic for
>>> linux-fsdevel and/or the respective per-filesystem mailing lists.
>>
>> Also, looks like kernel_dontaudit_setsched() isn't defined by
>> upstream
>> refpolicy so you'll need the usual ifdefery in test_policy.if to
>> allow
>> this to build against refpolicy to appease travis-ci.
>>
> 
> I'll change this to domain_setpriority_all_domains() in V4 as that is
> in both Fedora and Ref Policy.

That would likely break the task_setscheduler test.  Try 
kernel_setsched() instead, or if that fails, just use an ifdef as we do 
for other interfaces that don't exist in refpolicy.



^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2020-01-13 18:53 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-09 15:07 [PATCH V2 0/1] selinux-testsuite: Add filesystem tests Richard Haines
2020-01-09 15:07 ` [PATCH V2 1/1] " Richard Haines
2020-01-09 17:14   ` Stephen Smalley
2020-01-09 17:40     ` Richard Haines
2020-01-09 17:19   ` Stephen Smalley
2020-01-09 17:45     ` Richard Haines
2020-01-10 18:09     ` Richard Haines
2020-01-10 18:18       ` Stephen Smalley
2020-01-12 16:04         ` Richard Haines
2020-01-13 13:52           ` Stephen Smalley
2020-01-13 14:07             ` Stephen Smalley
2020-01-13 18:00               ` Richard Haines
2020-01-13 18:54                 ` Stephen Smalley
2020-01-09 17:46   ` Stephen Smalley
2020-01-09 17:51     ` Richard Haines
2020-01-09 18:04 ` [PATCH V2 0/1] " Stephen Smalley
2020-01-09 20:36   ` Richard Haines
2020-01-09 21:01     ` Ondrej Mosnacek
2020-01-10 14:28       ` Richard Haines

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.