diff mbox series

[2/4] support perf_event_paranoid=3

Message ID 20220614102029.13006-2-cgzones@googlemail.com (mailing list archive)
State Superseded
Headers show
Series [1/4] support Dash as default shell | expand

Commit Message

Christian Göttsche June 14, 2022, 10:20 a.m. UTC
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@googlemail.com>
---
 policy/test_perf_event.te | 29 +++++++++++++++++++++++------
 tests/perf_event/test     | 39 ++++++++++++++++++++++++++++-----------
 2 files changed, 51 insertions(+), 17 deletions(-)

Comments

Ondrej Mosnacek June 14, 2022, 1:14 p.m. UTC | #1
On Tue, Jun 14, 2022 at 12:20 PM Christian Göttsche
<cgzones@googlemail.com> wrote:
> 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@googlemail.com>
> ---
>  policy/test_perf_event.te | 29 +++++++++++++++++++++++------
>  tests/perf_event/test     | 39 ++++++++++++++++++++++++++++-----------
>  2 files changed, 51 insertions(+), 17 deletions(-)

Could we rather temporarily set the sysctl to 2 if it's 3 rather than
adapting to the Debian's downstream patch? The testsuite already does
a lot of various temporary system-wide tweaks, so I don't think it's
worth adding all this complexity just to avoid touching the sysctl.

And actually if we are already going to touch it, we could iterate
through all the normal values (0-2) and check that each works as
expected w.r.t. CAP_PERFMON (but I'll leave it up to you if you want
to implement that or not).
diff mbox series

Patch

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 =