Debian uses a downstream patch[1] to allow further restriction of perf_event_open, which requires CAP_SYS_ADMIN for all perf_event_open(2) operations. [1]: https://salsa.debian.org/kernel-team/linux/-/blob/debian/5.17.3-1/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx> --- policy/test_perf_event.te | 29 +++++++++++++++++++++++------ tests/perf_event/test | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/policy/test_perf_event.te b/policy/test_perf_event.te index fb05120..dc2b49f 100644 --- a/policy/test_perf_event.te +++ b/policy/test_perf_event.te @@ -10,18 +10,29 @@ unconfined_runs_test(test_perf_t) typeattribute test_perf_t testdomain; typeattribute test_perf_t perfdomain; +allow test_perf_t self:capability { sys_admin }; allow test_perf_t self:capability2 { perfmon }; allow test_perf_t self:perf_event { open cpu kernel tracepoint read write }; allow_lockdown_confidentiality(test_perf_t) ################# Deny capability2 { perfmon } ########################## -type test_perf_no_cap_t; -domain_type(test_perf_no_cap_t) -unconfined_runs_test(test_perf_no_cap_t) -typeattribute test_perf_no_cap_t testdomain; -typeattribute test_perf_no_cap_t perfdomain; +type test_perf_no_cap_perfmon_t; +domain_type(test_perf_no_cap_perfmon_t) +unconfined_runs_test(test_perf_no_cap_perfmon_t) +typeattribute test_perf_no_cap_perfmon_t testdomain; +typeattribute test_perf_no_cap_perfmon_t perfdomain; -allow test_perf_no_cap_t self:perf_event { open cpu kernel tracepoint read write }; +allow test_perf_no_cap_perfmon_t self:perf_event { open cpu kernel tracepoint read write }; + +################# Deny capability { sys_admin } ########################## +type test_perf_no_cap_sysadmin_t; +domain_type(test_perf_no_cap_sysadmin_t) +unconfined_runs_test(test_perf_no_cap_sysadmin_t) +typeattribute test_perf_no_cap_sysadmin_t testdomain; +typeattribute test_perf_no_cap_sysadmin_t perfdomain; + +allow test_perf_no_cap_sysadmin_t self:capability2 { perfmon }; +allow test_perf_no_cap_sysadmin_t self:perf_event { open cpu kernel tracepoint read write }; ################# Deny perf_event { open } ########################## type test_perf_no_open_t; @@ -30,6 +41,7 @@ unconfined_runs_test(test_perf_no_open_t) typeattribute test_perf_no_open_t testdomain; typeattribute test_perf_no_open_t perfdomain; +allow test_perf_no_open_t self:capability { sys_admin }; allow test_perf_no_open_t self:capability2 { perfmon }; allow test_perf_no_open_t self:perf_event { cpu kernel tracepoint read write }; @@ -40,6 +52,7 @@ unconfined_runs_test(test_perf_no_cpu_t) typeattribute test_perf_no_cpu_t testdomain; typeattribute test_perf_no_cpu_t perfdomain; +allow test_perf_no_cpu_t self:capability { sys_admin }; allow test_perf_no_cpu_t self:capability2 { perfmon }; allow test_perf_no_cpu_t self:perf_event { open kernel tracepoint read write }; allow_lockdown_confidentiality(test_perf_no_cpu_t) @@ -51,6 +64,7 @@ unconfined_runs_test(test_perf_no_kernel_t) typeattribute test_perf_no_kernel_t testdomain; typeattribute test_perf_no_kernel_t perfdomain; +allow test_perf_no_kernel_t self:capability { sys_admin }; allow test_perf_no_kernel_t self:capability2 { perfmon }; allow test_perf_no_kernel_t self:perf_event { open cpu tracepoint read write }; @@ -61,6 +75,7 @@ unconfined_runs_test(test_perf_no_tracepoint_t) typeattribute test_perf_no_tracepoint_t testdomain; typeattribute test_perf_no_tracepoint_t perfdomain; +allow test_perf_no_tracepoint_t self:capability { sys_admin }; allow test_perf_no_tracepoint_t self:capability2 { perfmon }; allow test_perf_no_tracepoint_t self:perf_event { open cpu kernel read write }; allow_lockdown_confidentiality(test_perf_no_tracepoint_t) @@ -72,6 +87,7 @@ unconfined_runs_test(test_perf_no_read_t) typeattribute test_perf_no_read_t testdomain; typeattribute test_perf_no_read_t perfdomain; +allow test_perf_no_read_t self:capability { sys_admin }; allow test_perf_no_read_t self:capability2 { perfmon }; allow test_perf_no_read_t self:perf_event { open cpu kernel tracepoint write }; allow_lockdown_confidentiality(test_perf_no_read_t) @@ -83,6 +99,7 @@ unconfined_runs_test(test_perf_no_write_t) typeattribute test_perf_no_write_t testdomain; typeattribute test_perf_no_write_t perfdomain; +allow test_perf_no_write_t self:capability { sys_admin }; allow test_perf_no_write_t self:capability2 { perfmon }; allow test_perf_no_write_t self:perf_event { open cpu kernel tracepoint read }; allow_lockdown_confidentiality(test_perf_no_write_t) diff --git a/tests/perf_event/test b/tests/perf_event/test index c336477..5aacdf9 100755 --- a/tests/perf_event/test +++ b/tests/perf_event/test @@ -5,8 +5,8 @@ BEGIN { $basedir = $0; $basedir =~ s|(.*)/[^/]*|$1|; - $test_count = 8; - $capability = 0; + $cap_perfmon = 0; + $cap_sysadmin = 0; # allow info to be shown during tests $v = $ARGV[0]; @@ -22,8 +22,10 @@ BEGIN { $level = `cat /proc/sys/kernel/perf_event_paranoid`; chomp($level); if ( $level >= 2 ) { # These tests require CAP_PERFMON - $test_count += 1; - $capability = 1; + $cap_perfmon = 1; + } + if ( $level >= 3 ) { # These tests require CAP_SYS_ADMIN + $cap_sysadmin = 1; } if ( $v eq "-v" ) { @@ -32,12 +34,15 @@ BEGIN { print "\tNot paranoid\n"; } elsif ( $level eq 0 ) { - print "\tDisallow raw tracepoint/ftrace without CAP_SYS_ADMIN\n"; + print "\tDisallow raw tracepoint/ftrace without CAP_PERFMON\n"; } elsif ( $level eq 1 ) { - print "\tDisallow CPU event access without CAP_SYS_ADMIN\n"; + print "\tDisallow CPU event access without CAP_PERFMON\n"; } elsif ( $level eq 2 ) { + print "\tDisallow kernel profiling without CAP_PERFMON\n"; + } + elsif ( $level eq 3 ) { print "\tDisallow kernel profiling without CAP_SYS_ADMIN\n"; } else { @@ -45,7 +50,7 @@ BEGIN { } } - plan tests => $test_count; + plan tests => 10; } # find some CPU that is online @@ -67,13 +72,25 @@ print "Test perf_event\n"; $result = system "runcon -t test_perf_t $basedir/perf_event $v $cpu $event_id"; ok( $result eq 0 ); -if ($capability) { +# Deny capability { perfmon } - EACCES perf_event_open(2) if perf_event_paranoid >= 2 +$result = system +"runcon -t test_perf_no_cap_perfmon_t $basedir/perf_event $v $cpu $event_id 2>&1"; +if ($cap_perfmon) { + ok( $result >> 8 eq 1 ); +} +else { + ok( $result eq 0 ); +} - # Deny capability { perfmon } - EACCES perf_event_open(2) - $result = system - "runcon -t test_perf_no_cap_t $basedir/perf_event $v $cpu $event_id 2>&1"; +# Deny capability { sys_admin } - EACCES perf_event_open(2) if perf_event_paranoid >= 3 +$result = system +"runcon -t test_perf_no_cap_sysadmin_t $basedir/perf_event $v $cpu $event_id 2>&1"; +if ($cap_sysadmin) { ok( $result >> 8 eq 1 ); } +else { + ok( $result eq 0 ); +} # Deny perf_event { open } - EACCES perf_event_open(2) $result = -- 2.36.1