The system policy interfaces for things that require lockdown permissions will likely grant those permissions, too, so we need to open-code them. Thus, use tracefs/debugfs access to test lockdown, as the interfaces for these are easier to open-code. With this patch, the lockdown test passes with latest Fedora policy in Rawhide. Signed-off-by: Ondrej Mosnacek <omosnace@xxxxxxxxxx> --- defconfig | 5 +++++ policy/test_lockdown.te | 16 ++++++++-------- policy/test_policy.if | 17 +++++++++++++++++ tests/lockdown/test | 21 +++++++++++++-------- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/defconfig b/defconfig index 46eb673..ca7a877 100644 --- a/defconfig +++ b/defconfig @@ -117,3 +117,8 @@ CONFIG_VFAT_FS=m # They are not required for SELinux operation itself. CONFIG_WATCH_QUEUE=y CONFIG_KEY_NOTIFICATIONS=y + +# Test lockdown permissions (via tracefs and debugfs). +# This is not required for SELinux operation itself. +CONFIG_TRACING=y +CONFIG_DEBUG_FS=y diff --git a/policy/test_lockdown.te b/policy/test_lockdown.te index a7a4b6b..1ec985e 100644 --- a/policy/test_lockdown.te +++ b/policy/test_lockdown.te @@ -12,8 +12,8 @@ unconfined_runs_test(test_lockdown_all_t) typeattribute test_lockdown_all_t lockdowndomain; typeattribute test_lockdown_all_t testdomain; -dev_read_raw_memory(test_lockdown_all_t) -kernel_read_core_if(test_lockdown_all_t) +testsuite_read_debugfs_nolockdown(test_lockdown_all_t) +testsuite_read_tracefs_nolockdown(test_lockdown_all_t) corecmd_bin_entry_type(test_lockdown_all_t) allow test_lockdown_all_t self:lockdown integrity; allow test_lockdown_all_t self:lockdown confidentiality; @@ -25,8 +25,8 @@ unconfined_runs_test(test_lockdown_integrity_t) typeattribute test_lockdown_integrity_t lockdowndomain; typeattribute test_lockdown_integrity_t testdomain; -dev_read_raw_memory(test_lockdown_integrity_t) -kernel_read_core_if(test_lockdown_integrity_t) +testsuite_read_debugfs_nolockdown(test_lockdown_integrity_t) +testsuite_read_tracefs_nolockdown(test_lockdown_integrity_t) corecmd_bin_entry_type(test_lockdown_integrity_t) allow test_lockdown_integrity_t self:lockdown integrity; @@ -37,8 +37,8 @@ unconfined_runs_test(test_lockdown_confidentiality_t) typeattribute test_lockdown_confidentiality_t lockdowndomain; typeattribute test_lockdown_confidentiality_t testdomain; -dev_read_raw_memory(test_lockdown_confidentiality_t) -kernel_read_core_if(test_lockdown_confidentiality_t) +testsuite_read_debugfs_nolockdown(test_lockdown_confidentiality_t) +testsuite_read_tracefs_nolockdown(test_lockdown_confidentiality_t) corecmd_bin_entry_type(test_lockdown_confidentiality_t) allow test_lockdown_confidentiality_t self:lockdown confidentiality; @@ -49,6 +49,6 @@ unconfined_runs_test(test_lockdown_none_t) typeattribute test_lockdown_none_t lockdowndomain; typeattribute test_lockdown_none_t testdomain; -dev_read_raw_memory(test_lockdown_none_t) -kernel_read_core_if(test_lockdown_none_t) +testsuite_read_debugfs_nolockdown(test_lockdown_none_t) +testsuite_read_tracefs_nolockdown(test_lockdown_none_t) corecmd_bin_entry_type(test_lockdown_none_t) diff --git a/policy/test_policy.if b/policy/test_policy.if index e3c01c8..7023e30 100644 --- a/policy/test_policy.if +++ b/policy/test_policy.if @@ -87,3 +87,20 @@ interface(`userdom_search_admin_dir', ` ifdef(`kernel_request_load_module', `', ` dnl interface(`kernel_request_load_module', `') ') + +# We need to open-code these interfaces, because the system-provided ones will +# likely grant the lockdown permissions we want to test. +interface(`testsuite_read_debugfs_nolockdown',` + gen_require(` + type debugfs_t; + ') + + read_files_pattern($1, debugfs_t, debugfs_t) +') +interface(`testsuite_read_tracefs_nolockdown',` + gen_require(` + type tracefs_t; + ') + + read_files_pattern($1, tracefs_t, tracefs_t) +') diff --git a/tests/lockdown/test b/tests/lockdown/test index 0b81cb1..6694a4c 100755 --- a/tests/lockdown/test +++ b/tests/lockdown/test @@ -3,40 +3,45 @@ use Test; BEGIN { plan tests => 8 } +$integrity_cmd = "head -c 1 /sys/kernel/debug/sched_features"; +$confidentiality_cmd = "head -c 1 /sys/kernel/debug/tracing/tracing_on"; + # everything is allowed $result = - system "runcon -t test_lockdown_all_t -- head /dev/mem > /dev/null 2>&1"; + system "runcon -t test_lockdown_all_t -- $integrity_cmd > /dev/null 2>&1"; ok( $result, 0 ); $result = - system "runcon -t test_lockdown_all_t -- head /proc/kcore > /dev/null 2>&1"; + system + "runcon -t test_lockdown_all_t -- $confidentiality_cmd > /dev/null 2>&1"; ok( $result, 0 ); # only integrity operations allowed $result = system - "runcon -t test_lockdown_integrity_t -- head /dev/mem > /dev/null 2>&1"; + "runcon -t test_lockdown_integrity_t -- $integrity_cmd > /dev/null 2>&1"; ok( $result, 0 ); $result = system - "runcon -t test_lockdown_integrity_t -- head /proc/kcore > /dev/null 2>&1"; +"runcon -t test_lockdown_integrity_t -- $confidentiality_cmd > /dev/null 2>&1"; ok($result); # only confidentiality operations allowed $result = system - "runcon -t test_lockdown_confidentiality_t -- head /dev/mem > /dev/null 2>&1"; +"runcon -t test_lockdown_confidentiality_t -- $integrity_cmd > /dev/null 2>&1"; ok($result); $result = system -"runcon -t test_lockdown_confidentiality_t -- head /proc/kcore > /dev/null 2>&1"; +"runcon -t test_lockdown_confidentiality_t -- $confidentiality_cmd > /dev/null 2>&1"; ok( $result, 0 ); # nothing is allowed $result = - system "runcon -t test_lockdown_none_t -- head /dev/mem > /dev/null 2>&1"; + system "runcon -t test_lockdown_none_t -- $integrity_cmd > /dev/null 2>&1"; ok($result); $result = - system "runcon -t test_lockdown_none_t -- head /proc/kcore > /dev/null 2>&1"; + system + "runcon -t test_lockdown_none_t -- $confidentiality_cmd > /dev/null 2>&1"; ok($result); exit; -- 2.29.2