@@ -118,6 +118,9 @@ ifeq ($(shell grep -q filesystem $(POLDEV)/include/support/all_perms.spt && echo
TARGETS += test_filesystem.te
ifeq ($(shell [ $(MOD_POL_VERS) -ge 11 -a $(POL_VERS) -ge 25 ] && echo true),true)
TARGETS += test_filesystem_name_trans.te
+ifeq ($(shell grep -q all_file_perms.*watch $(POLDEV)/include/support/all_perms.spt && echo true),true)
+TARGETS+= test_filesystem_notify.te
+endif
endif
endif
@@ -292,21 +292,6 @@ dontaudit unconfined_t test_filesystem_filecon_t:file { getattr read };
allow test_filesystem_inode_setxattr_no_associate_t unconfined_t:dir { add_name write };
allow test_filesystem_inode_setxattr_no_associate_t unconfined_t:file { create relabelfrom relabelto };
-#################### Deny filesystem { watch } ######################
-# hooks.c selinux_path_notify() 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 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)
-
################# Test process { setfscreate } #############
type test_setfscreatecon_t;
domain_type(test_setfscreatecon_t)
new file mode 100644
@@ -0,0 +1,60 @@
+#
+######### Test filesystem fanotify(7) policy module ##########
+#
+
+################# Test all functions ##########################
+# For fanotify tests
+allow test_filesystem_t self:filesystem { watch };
+# Until 'fs_watch_all_fs(test_filesystem_t)' in Policy use:
+gen_require(`
+ type fs_t;
+')
+allow test_filesystem_t fs_t:filesystem { watch };
+allow test_filesystem_t test_filesystem_file_t:dir { watch_sb watch_mount };
+
+#################### Deny filesystem { watch } ######################
+# hooks.c selinux_path_notify() 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 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)
+
+#################### Deny file { watch_sb } ######################
+# hooks.c selinux_path_notify() FILE__WATCH_SB
+type test_filesystem_no_watch_sb_t;
+domain_type(test_filesystem_no_watch_sb_t)
+unconfined_runs_test(test_filesystem_no_watch_sb_t)
+typeattribute test_filesystem_no_watch_sb_t testdomain;
+typeattribute test_filesystem_no_watch_sb_t filesystemdomain;
+
+allow test_filesystem_no_watch_sb_t self:capability { sys_admin };
+allow test_filesystem_no_watch_sb_t self:filesystem { watch associate relabelto mount unmount relabelfrom };
+allow test_filesystem_no_watch_sb_t test_file_t:dir { mounton write remove_name rmdir };
+
+fs_mount_all_fs(test_filesystem_no_watch_sb_t)
+fs_relabelfrom_all_fs(test_filesystem_no_watch_sb_t)
+fs_associate(test_filesystem_no_watch_sb_t)
+
+#################### Deny file { watch_mount } ######################
+# hooks.c selinux_path_notify() FILE__WATCH_MOUNT
+type test_filesystem_no_watch_mount_t;
+domain_type(test_filesystem_no_watch_mount_t)
+unconfined_runs_test(test_filesystem_no_watch_mount_t)
+typeattribute test_filesystem_no_watch_mount_t testdomain;
+typeattribute test_filesystem_no_watch_mount_t filesystemdomain;
+
+allow test_filesystem_no_watch_mount_t self:capability { sys_admin };
+allow test_filesystem_no_watch_mount_t self:filesystem { watch associate relabelto mount unmount relabelfrom };
+allow test_filesystem_no_watch_mount_t test_file_t:dir { mounton write remove_name rmdir };
+
+fs_mount_all_fs(test_filesystem_no_watch_mount_t)
+fs_relabelfrom_all_fs(test_filesystem_no_watch_mount_t)
+fs_associate(test_filesystem_no_watch_mount_t)
@@ -8,16 +8,16 @@ sub check_config {
$tst_count = 0;
- # From kernel 5.5 support for fanotify(7) with filesystem { watch }
+ # From kernel 5.4 support for fanotify(7) LSM hooks
$kvercur = `uname -r`;
chomp($kvercur);
- $kverminstream = "5.5";
+ $kverminstream = "5.4";
$watch = 0;
$result = `$base/../kvercmp $kvercur $kverminstream`;
if ( $result > 0 && -e $fanotify_fs ) {
$watch = 1;
- $tst_count += 4;
+ $tst_count += 11;
}
$name_trans = 0;
@@ -11,29 +11,38 @@
#ifndef FAN_MARK_FILESYSTEM
#define FAN_MARK_FILESYSTEM 0x00000100
#endif
+#ifndef FAN_MARK_MOUNT
+#define FAN_MARK_MOUNT 0x00000010
+#endif
static void print_usage(char *progname)
{
fprintf(stderr,
- "usage: %s -t path [-v]\n"
+ "usage: %s -t path [-m] [-v]\n"
"Where:\n\t"
"-t Target mount point to mark\n\t"
+ "-m Set flag to FAN_MARK_MOUNT, default is FAN_MARK_FILESYSTEM\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 mask = FAN_OPEN, flags;
int fd, result, opt, save_err;
char *context, *tgt = NULL;
bool verbose = false;
- while ((opt = getopt(argc, argv, "t:v")) != -1) {
+ flags = 0;
+
+ while ((opt = getopt(argc, argv, "t:mv")) != -1) {
switch (opt) {
case 't':
tgt = optarg;
break;
+ case 'm':
+ flags = FAN_MARK_ADD | FAN_MARK_MOUNT;
+ break;
case 'v':
verbose = true;
break;
@@ -42,6 +51,9 @@ int main(int argc, char *argv[])
}
}
+ if (!flags)
+ flags = FAN_MARK_ADD | FAN_MARK_FILESYSTEM;
+
if (!tgt)
print_usage(argv[0]);
@@ -148,11 +148,17 @@ if ($test_name_trans) {
}
if ($test_watch) {
- print "fanotify(7) test\n";
+ print "fanotify(7) test - FAN_MARK_FILESYSTEM\n";
$result = system(
"runcon -t test_filesystem_t $basedir/fanotify_fs $v -t $basedir/mntpoint/mp1"
);
ok( $result eq 0 );
+
+ print "fanotify(7) test - FAN_MARK_MOUNT\n";
+ $result = system(
+"runcon -t test_filesystem_t $basedir/fanotify_fs $v -m -t $basedir/mntpoint/mp1"
+ );
+ ok( $result eq 0 );
}
print "Unmount filesystem from $basedir/mntpoint/mp1\n";
@@ -556,9 +562,9 @@ ok( $result eq 0 );
print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
cleanup1( $basedir, $dev );
-############### Deny filesystem { watch } ##########################
-# hooks.c selinux_path_notify() FILESYSTEM__WATCH
if ($test_watch) {
+ ############### Deny filesystem { watch } ##########################
+ # hooks.c selinux_path_notify() FILESYSTEM__WATCH
mk_mntpoint_1($private_path);
( $dev, $device_count ) = get_loop_dev( \@device_list, $device_count );
make_fs( $fs_type, $dev, $basedir );
@@ -571,7 +577,7 @@ if ($test_watch) {
);
ok( $result eq 0 );
- print "test_fanotify\n";
+ print "fanotify(7) test - FAN_MARK_FILESYSTEM\n";
$result = system(
"runcon -t test_filesystem_no_watch_t $basedir/fanotify_fs $v -t $basedir/mntpoint/mp1 2>&1"
);
@@ -585,6 +591,66 @@ if ($test_watch) {
print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
cleanup1( $basedir, $dev );
+
+ ############### Deny file { watch_sb } ##########################
+ # hooks.c selinux_path_notify() FILE__WATCH_SB
+ mk_mntpoint_1($private_path);
+ ( $dev, $device_count ) = get_loop_dev( \@device_list, $device_count );
+ make_fs( $fs_type, $dev, $basedir );
+ $opts_no_watch_sb =
+ "context=system_u:object_r:test_filesystem_no_watch_sb_t:s0";
+
+ print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+ print "Using mount options:\n\t$opts_no_watch_sb\n";
+ $result = system(
+"runcon -t test_filesystem_no_watch_sb_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_watch_sb $v"
+ );
+ ok( $result eq 0 );
+
+ print "fanotify(7) test - FAN_MARK_FILESYSTEM\n";
+ $result = system(
+"runcon -t test_filesystem_no_watch_sb_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_sb_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+ );
+ ok( $result eq 0 );
+
+ print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+ cleanup1( $basedir, $dev );
+
+ ############### Deny file { watch_mount } ##########################
+ # hooks.c selinux_path_notify() FILE__WATCH_MOUNT
+ mk_mntpoint_1($private_path);
+ ( $dev, $device_count ) = get_loop_dev( \@device_list, $device_count );
+ make_fs( $fs_type, $dev, $basedir );
+ $opts_no_watch_mount =
+ "context=system_u:object_r:test_filesystem_no_watch_mount_t:s0";
+
+ print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+ print "Using mount options:\n\t$opts_no_watch_mount\n";
+ $result = system(
+"runcon -t test_filesystem_no_watch_mount_t $basedir/mount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_watch_mount $v"
+ );
+ ok( $result eq 0 );
+
+ print "fanotify(7) test - FAN_MARK_MOUNT\n";
+ $result = system(
+"runcon -t test_filesystem_no_watch_mount_t $basedir/fanotify_fs $v -m -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_mount_t $basedir/umount -t $basedir/mntpoint/mp1 $v"
+ );
+ ok( $result eq 0 );
+
+ print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+ cleanup1( $basedir, $dev );
}
##########################################################################
@@ -118,11 +118,17 @@ if ($test_name_trans) {
}
if ($test_watch) {
- print "fanotify(7) test\n";
+ print "fanotify(7) test - FAN_MARK_FILESYSTEM\n";
$result = system(
"runcon -t test_filesystem_t $filesystem_dir/fanotify_fs $v -t $basedir/mntpoint/mp1"
);
ok( $result eq 0 );
+
+ print "fanotify(7) test - FAN_MARK_MOUNT\n";
+ $result = system(
+"runcon -t test_filesystem_t $filesystem_dir/fanotify_fs $v -m -t $basedir/mntpoint/mp1"
+ );
+ ok( $result eq 0 );
}
print "Unmount filesystem from $basedir/mntpoint/mp1\n";
@@ -564,9 +570,9 @@ ok( $result eq 0 );
print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
cleanup1( $basedir, $dev );
-############### Deny filesystem { watch } ##########################
-# hooks.c selinux_path_notify() FILESYSTEM__WATCH
if ($test_watch) {
+ ############### Deny filesystem { watch } ##########################
+ # hooks.c selinux_path_notify() FILESYSTEM__WATCH
mk_mntpoint_1("$basedir/mntpoint");
( $dev, $device_count ) = get_loop_dev( \@device_list, $device_count );
make_fs( $fs_type, $dev, $basedir );
@@ -579,7 +585,7 @@ if ($test_watch) {
);
ok( $result eq 0 );
- print "test_fanotify\n";
+ print "fanotify(7) test - FAN_MARK_FILESYSTEM\n";
$result = system(
"runcon -t test_filesystem_no_watch_t $filesystem_dir/fanotify_fs $v -t $basedir/mntpoint/mp1 2>&1"
);
@@ -593,6 +599,66 @@ if ($test_watch) {
print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
cleanup1( $basedir, $dev );
+
+ ############### Deny file { watch_sb } ##########################
+ # hooks.c selinux_path_notify() FILE__WATCH_SB
+ mk_mntpoint_1("$basedir/mntpoint");
+ ( $dev, $device_count ) = get_loop_dev( \@device_list, $device_count );
+ make_fs( $fs_type, $dev, $basedir );
+ $opts_no_watch_sb =
+ "context=system_u:object_r:test_filesystem_no_watch_sb_t:s0";
+
+ print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+ print "Using mount options:\n\t$opts_no_watch_sb\n";
+ $result = system(
+"runcon -t test_filesystem_no_watch_sb_t $basedir/fsmount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_watch_sb $v"
+ );
+ ok( $result eq 0 );
+
+ print "fanotify(7) test - FAN_MARK_FILESYSTEM\n";
+ $result = system(
+"runcon -t test_filesystem_no_watch_sb_t $filesystem_dir/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_sb_t $filesystem_dir/umount -t $basedir/mntpoint/mp1 $v"
+ );
+ ok( $result eq 0 );
+
+ print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+ cleanup1( $basedir, $dev );
+
+ ############### Deny file { watch_mount } ##########################
+ # hooks.c selinux_path_notify() FILE__WATCH_MOUNT
+ mk_mntpoint_1("$basedir/mntpoint");
+ ( $dev, $device_count ) = get_loop_dev( \@device_list, $device_count );
+ make_fs( $fs_type, $dev, $basedir );
+ $opts_no_watch_mount =
+ "context=system_u:object_r:test_filesystem_no_watch_mount_t:s0";
+
+ print "Mount $fs_type filesystem on $basedir/mntpoint/mp1\n";
+ print "Using mount options:\n\t$opts_no_watch_mount\n";
+ $result = system(
+"runcon -t test_filesystem_no_watch_mount_t $basedir/fsmount -s $dev -t $basedir/mntpoint/mp1 -f $fs_type -o $opts_no_watch_mount $v"
+ );
+ ok( $result eq 0 );
+
+ print "fanotify(7) test - FAN_MARK_MOUNT\n";
+ $result = system(
+"runcon -t test_filesystem_no_watch_mount_t $filesystem_dir/fanotify_fs $v -m -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_mount_t $filesystem_dir/umount -t $basedir/mntpoint/mp1 $v"
+ );
+ ok( $result eq 0 );
+
+ print "Removing: $dev $basedir/mntpoint $basedir/fstest\n";
+ cleanup1( $basedir, $dev );
}
##########################################################################
Test watch_sb and watch_mount permissions. The policy is contained in test_filesystem_notify.te as it can then be built if the policy supports the permissions. Signed-off-by: Richard Haines <richard_c_haines@btinternet.com> --- policy/Makefile | 3 ++ policy/test_filesystem.te | 15 ------- policy/test_filesystem_notify.te | 60 ++++++++++++++++++++++++++ tests/filesystem/Filesystem.pm | 6 +-- tests/filesystem/fanotify_fs.c | 18 ++++++-- tests/filesystem/test | 74 ++++++++++++++++++++++++++++++-- tests/fs_filesystem/test | 74 ++++++++++++++++++++++++++++++-- 7 files changed, 221 insertions(+), 29 deletions(-) create mode 100644 policy/test_filesystem_notify.te