238 lines · plain
1Overview2========3 4For general security related questions of perf_event_open() syscall usage,5performance monitoring and observability operations by Perf see here:6https://www.kernel.org/doc/html/latest/admin-guide/perf-security.html7 8Enabling LSM based mandatory access control (MAC) to perf_event_open() syscall9==============================================================================10 11LSM hooks for mandatory access control for perf_event_open() syscall can be12used starting from Linux v5.3. Below are the steps to extend Fedora (v31) with13Targeted policy with perf_event_open() access control capabilities:14 151. Download selinux-policy SRPM package (e.g. selinux-policy-3.14.4-48.fc31.src.rpm on FC31)16 and install it so rpmbuild directory would exist in the current working directory:17 18 # rpm -Uhv selinux-policy-3.14.4-48.fc31.src.rpm19 202. Get into rpmbuild/SPECS directory and unpack the source code:21 22 # rpmbuild -bp selinux-policy.spec23 243. Place patch below at rpmbuild/BUILD/selinux-policy-b86eaaf4dbcf2d51dd4432df7185c0eaf3cbcc0225 directory and apply it:26 27 # patch -p1 < selinux-policy-perf-events-perfmon.patch28 patching file policy/flask/access_vectors29 patching file policy/flask/security_classes30 # cat selinux-policy-perf-events-perfmon.patch31diff -Nura a/policy/flask/access_vectors b/policy/flask/access_vectors32--- a/policy/flask/access_vectors 2020-02-04 18:19:53.000000000 +030033+++ b/policy/flask/access_vectors 2020-02-28 23:37:25.000000000 +030034@@ -174,6 +174,7 @@35 wake_alarm36 block_suspend37 audit_read38+ perfmon39 }40 41 #42@@ -1099,3 +1100,15 @@43 44 class xdp_socket45 inherits socket46+47+class perf_event48+{49+ open50+ cpu51+ kernel52+ tracepoint53+ read54+ write55+}56+57+58diff -Nura a/policy/flask/security_classes b/policy/flask/security_classes59--- a/policy/flask/security_classes 2020-02-04 18:19:53.000000000 +030060+++ b/policy/flask/security_classes 2020-02-28 21:35:17.000000000 +030061@@ -200,4 +200,6 @@62 63 class xdp_socket64 65+class perf_event66+67 # FLASK68 694. Get into rpmbuild/SPECS directory and build policy packages from patched sources:70 71 # rpmbuild --noclean --noprep -ba selinux-policy.spec72 73 so you have this:74 75 # ls -alh rpmbuild/RPMS/noarch/76 total 33M77 drwxr-xr-x. 2 root root 4.0K Mar 20 12:16 .78 drwxr-xr-x. 3 root root 4.0K Mar 20 12:16 ..79 -rw-r--r--. 1 root root 112K Mar 20 12:16 selinux-policy-3.14.4-48.fc31.noarch.rpm80 -rw-r--r--. 1 root root 1.2M Mar 20 12:17 selinux-policy-devel-3.14.4-48.fc31.noarch.rpm81 -rw-r--r--. 1 root root 2.3M Mar 20 12:17 selinux-policy-doc-3.14.4-48.fc31.noarch.rpm82 -rw-r--r--. 1 root root 12M Mar 20 12:17 selinux-policy-minimum-3.14.4-48.fc31.noarch.rpm83 -rw-r--r--. 1 root root 4.5M Mar 20 12:16 selinux-policy-mls-3.14.4-48.fc31.noarch.rpm84 -rw-r--r--. 1 root root 111K Mar 20 12:16 selinux-policy-sandbox-3.14.4-48.fc31.noarch.rpm85 -rw-r--r--. 1 root root 14M Mar 20 12:17 selinux-policy-targeted-3.14.4-48.fc31.noarch.rpm86 875. Install SELinux packages from Fedora repo, if not already done so, and88 update with the patched rpms above:89 90 # rpm -Uhv rpmbuild/RPMS/noarch/selinux-policy-*91 926. Enable SELinux Permissive mode for Targeted policy, if not already done so:93 94 # cat /etc/selinux/config95 96 # This file controls the state of SELinux on the system.97 # SELINUX= can take one of these three values:98 # enforcing - SELinux security policy is enforced.99 # permissive - SELinux prints warnings instead of enforcing.100 # disabled - No SELinux policy is loaded.101 SELINUX=permissive102 # SELINUXTYPE= can take one of these three values:103 # targeted - Targeted processes are protected,104 # minimum - Modification of targeted policy. Only selected processes are protected.105 # mls - Multi Level Security protection.106 SELINUXTYPE=targeted107 1087. Enable filesystem SELinux labeling at the next reboot:109 110 # touch /.autorelabel111 1128. Reboot machine and it will label filesystems and load Targeted policy into the kernel;113 1149. Login and check that dmesg output doesn't mention that perf_event class is unknown to SELinux subsystem;115 11610. Check that SELinux is enabled and in Permissive mode117 118 # getenforce119 Permissive120 12111. Turn SELinux into Enforcing mode:122 123 # setenforce 1124 # getenforce125 Enforcing126 127Opening access to perf_event_open() syscall on Fedora with SELinux128==================================================================129 130Access to performance monitoring and observability operations by Perf131can be limited for superuser or CAP_PERFMON or CAP_SYS_ADMIN privileged132processes. MAC policy settings (e.g. SELinux) can be loaded into the kernel133and prevent unauthorized access to perf_event_open() syscall. In such case134Perf tool provides a message similar to the one below:135 136 # perf stat137 Error:138 Access to performance monitoring and observability operations is limited.139 Enforced MAC policy settings (SELinux) can limit access to performance140 monitoring and observability operations. Inspect system audit records for141 more perf_event access control information and adjusting the policy.142 Consider adjusting /proc/sys/kernel/perf_event_paranoid setting to open143 access to performance monitoring and observability operations for users144 without CAP_PERFMON or CAP_SYS_ADMIN Linux capability.145 perf_event_paranoid setting is -1:146 -1: Allow use of (almost) all events by all users147 Ignore mlock limit after perf_event_mlock_kb without CAP_IPC_LOCK148 >= 0: Disallow raw and ftrace function tracepoint access149 >= 1: Disallow CPU event access150 >= 2: Disallow kernel profiling151 To make the adjusted perf_event_paranoid setting permanent preserve it152 in /etc/sysctl.conf (e.g. kernel.perf_event_paranoid = <setting>)153 154To make sure that access is limited by MAC policy settings inspect system155audit records using journalctl command or /var/log/audit/audit.log so the156output would contain AVC denied records related to perf_event:157 158 # journalctl --reverse --no-pager | grep perf_event159 160 python3[1318099]: SELinux is preventing perf from open access on the perf_event labeled unconfined_t.161 If you believe that perf should be allowed open access on perf_event labeled unconfined_t by default.162 setroubleshoot[1318099]: SELinux is preventing perf from open access on the perf_event labeled unconfined_t. For complete SELinux messages run: sealert -l 4595ce5b-e58f-462c-9d86-3bc2074935de163 audit[1318098]: AVC avc: denied { open } for pid=1318098 comm="perf" scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=perf_event permissive=0164 165In order to open access to perf_event_open() syscall MAC policy settings can166require to be extended. On SELinux system this can be done by loading a special167policy module extending base policy settings. Perf related policy module can168be generated using the system audit records about blocking perf_event access.169Run the command below to generate my-perf.te policy extension file with170perf_event related rules:171 172 # ausearch -c 'perf' --raw | audit2allow -M my-perf && cat my-perf.te173 174 module my-perf 1.0;175 176 require {177 type unconfined_t;178 class perf_event { cpu kernel open read tracepoint write };179 }180 181 #============= unconfined_t ==============182 allow unconfined_t self:perf_event { cpu kernel open read tracepoint write };183 184Now compile, pack and load my-perf.pp extension module into the kernel:185 186 # checkmodule -M -m -o my-perf.mod my-perf.te187 # semodule_package -o my-perf.pp -m my-perf.mod188 # semodule -X 300 -i my-perf.pp189 190After all those taken steps above access to perf_event_open() syscall should191now be allowed by the policy settings. Check access running Perf like this:192 193 # perf stat194 ^C195 Performance counter stats for 'system wide':196 197 36,387.41 msec cpu-clock # 7.999 CPUs utilized198 2,629 context-switches # 0.072 K/sec199 57 cpu-migrations # 0.002 K/sec200 1 page-faults # 0.000 K/sec201 263,721,559 cycles # 0.007 GHz202 175,746,713 instructions # 0.67 insn per cycle203 19,628,798 branches # 0.539 M/sec204 1,259,201 branch-misses # 6.42% of all branches205 206 4.549061439 seconds time elapsed207 208The generated perf-event.pp related policy extension module can be removed209from the kernel using this command:210 211 # semodule -X 300 -r my-perf212 213Alternatively the module can be temporarily disabled and enabled back using214these two commands:215 216 # semodule -d my-perf217 # semodule -e my-perf218 219If something went wrong220=======================221 222To turn SELinux into Permissive mode:223 # setenforce 0224 225To fully disable SELinux during kernel boot [3] set kernel command line parameter selinux=0226 227To remove SELinux labeling from local filesystems:228 # find / -mount -print0 | xargs -0 setfattr -h -x security.selinux229 230To fully turn SELinux off a machine set SELINUX=disabled at /etc/selinux/config file and reboot;231 232Links233=====234 235[1] https://download-ib01.fedoraproject.org/pub/fedora/linux/updates/31/Everything/SRPMS/Packages/s/selinux-policy-3.14.4-49.fc31.src.rpm236[2] https://docs.fedoraproject.org/en-US/Fedora/11/html/Security-Enhanced_Linux/sect-Security-Enhanced_Linux-Working_with_SELinux-Enabling_and_Disabling_SELinux.html237[3] https://danwalsh.livejournal.com/10972.html238