1 Overview 1 Overview 2 ======== 2 ======== 3 3 4 For general security related questions of perf 4 For general security related questions of perf_event_open() syscall usage, 5 performance monitoring and observability opera 5 performance monitoring and observability operations by Perf see here: 6 https://www.kernel.org/doc/html/latest/admin-g 6 https://www.kernel.org/doc/html/latest/admin-guide/perf-security.html 7 7 8 Enabling LSM based mandatory access control (M 8 Enabling LSM based mandatory access control (MAC) to perf_event_open() syscall 9 ============================================== 9 ============================================================================== 10 10 11 LSM hooks for mandatory access control for per 11 LSM hooks for mandatory access control for perf_event_open() syscall can be 12 used starting from Linux v5.3. Below are the s 12 used starting from Linux v5.3. Below are the steps to extend Fedora (v31) with 13 Targeted policy with perf_event_open() access 13 Targeted policy with perf_event_open() access control capabilities: 14 14 15 1. Download selinux-policy SRPM package (e.g. 15 1. 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 16 and install it so rpmbuild directory would exist in the current working directory: 17 17 18 # rpm -Uhv selinux-policy-3.14.4-48.fc31.sr 18 # rpm -Uhv selinux-policy-3.14.4-48.fc31.src.rpm 19 19 20 2. Get into rpmbuild/SPECS directory and unpac 20 2. Get into rpmbuild/SPECS directory and unpack the source code: 21 21 22 # rpmbuild -bp selinux-policy.spec 22 # rpmbuild -bp selinux-policy.spec 23 23 24 3. Place patch below at rpmbuild/BUILD/selinux 24 3. Place patch below at rpmbuild/BUILD/selinux-policy-b86eaaf4dbcf2d51dd4432df7185c0eaf3cbcc02 25 directory and apply it: 25 directory and apply it: 26 26 27 # patch -p1 < selinux-policy-perf-events-pe 27 # patch -p1 < selinux-policy-perf-events-perfmon.patch 28 patching file policy/flask/access_vectors 28 patching file policy/flask/access_vectors 29 patching file policy/flask/security_classes 29 patching file policy/flask/security_classes 30 # cat selinux-policy-perf-events-perfmon.pa 30 # cat selinux-policy-perf-events-perfmon.patch 31 diff -Nura a/policy/flask/access_vectors b/pol 31 diff -Nura a/policy/flask/access_vectors b/policy/flask/access_vectors 32 --- a/policy/flask/access_vectors 2020-0 32 --- a/policy/flask/access_vectors 2020-02-04 18:19:53.000000000 +0300 33 +++ b/policy/flask/access_vectors 2020-0 33 +++ b/policy/flask/access_vectors 2020-02-28 23:37:25.000000000 +0300 34 @@ -174,6 +174,7 @@ 34 @@ -174,6 +174,7 @@ 35 wake_alarm 35 wake_alarm 36 block_suspend 36 block_suspend 37 audit_read 37 audit_read 38 + perfmon 38 + perfmon 39 } 39 } 40 40 41 # 41 # 42 @@ -1099,3 +1100,15 @@ 42 @@ -1099,3 +1100,15 @@ 43 43 44 class xdp_socket 44 class xdp_socket 45 inherits socket 45 inherits socket 46 + 46 + 47 +class perf_event 47 +class perf_event 48 +{ 48 +{ 49 + open 49 + open 50 + cpu 50 + cpu 51 + kernel 51 + kernel 52 + tracepoint 52 + tracepoint 53 + read 53 + read 54 + write 54 + write 55 +} 55 +} 56 + 56 + 57 + 57 + 58 diff -Nura a/policy/flask/security_classes b/p 58 diff -Nura a/policy/flask/security_classes b/policy/flask/security_classes 59 --- a/policy/flask/security_classes 2020-0 59 --- a/policy/flask/security_classes 2020-02-04 18:19:53.000000000 +0300 60 +++ b/policy/flask/security_classes 2020-0 60 +++ b/policy/flask/security_classes 2020-02-28 21:35:17.000000000 +0300 61 @@ -200,4 +200,6 @@ 61 @@ -200,4 +200,6 @@ 62 62 63 class xdp_socket 63 class xdp_socket 64 64 65 +class perf_event 65 +class perf_event 66 + 66 + 67 # FLASK 67 # FLASK 68 68 69 4. Get into rpmbuild/SPECS directory and build 69 4. Get into rpmbuild/SPECS directory and build policy packages from patched sources: 70 70 71 # rpmbuild --noclean --noprep -ba selinux-p 71 # rpmbuild --noclean --noprep -ba selinux-policy.spec 72 72 73 so you have this: 73 so you have this: 74 74 75 # ls -alh rpmbuild/RPMS/noarch/ 75 # ls -alh rpmbuild/RPMS/noarch/ 76 total 33M 76 total 33M 77 drwxr-xr-x. 2 root root 4.0K Mar 20 12:16 . 77 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 . 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 s 79 -rw-r--r--. 1 root root 112K Mar 20 12:16 selinux-policy-3.14.4-48.fc31.noarch.rpm 80 -rw-r--r--. 1 root root 1.2M Mar 20 12:17 s 80 -rw-r--r--. 1 root root 1.2M Mar 20 12:17 selinux-policy-devel-3.14.4-48.fc31.noarch.rpm 81 -rw-r--r--. 1 root root 2.3M Mar 20 12:17 s 81 -rw-r--r--. 1 root root 2.3M Mar 20 12:17 selinux-policy-doc-3.14.4-48.fc31.noarch.rpm 82 -rw-r--r--. 1 root root 12M Mar 20 12:17 s 82 -rw-r--r--. 1 root root 12M Mar 20 12:17 selinux-policy-minimum-3.14.4-48.fc31.noarch.rpm 83 -rw-r--r--. 1 root root 4.5M Mar 20 12:16 s 83 -rw-r--r--. 1 root root 4.5M Mar 20 12:16 selinux-policy-mls-3.14.4-48.fc31.noarch.rpm 84 -rw-r--r--. 1 root root 111K Mar 20 12:16 s 84 -rw-r--r--. 1 root root 111K Mar 20 12:16 selinux-policy-sandbox-3.14.4-48.fc31.noarch.rpm 85 -rw-r--r--. 1 root root 14M Mar 20 12:17 s 85 -rw-r--r--. 1 root root 14M Mar 20 12:17 selinux-policy-targeted-3.14.4-48.fc31.noarch.rpm 86 86 87 5. Install SELinux packages from Fedora repo, 87 5. Install SELinux packages from Fedora repo, if not already done so, and 88 update with the patched rpms above: 88 update with the patched rpms above: 89 89 90 # rpm -Uhv rpmbuild/RPMS/noarch/selinux-pol 90 # rpm -Uhv rpmbuild/RPMS/noarch/selinux-policy-* 91 91 92 6. Enable SELinux Permissive mode for Targeted 92 6. Enable SELinux Permissive mode for Targeted policy, if not already done so: 93 93 94 # cat /etc/selinux/config 94 # cat /etc/selinux/config 95 95 96 # This file controls the state of SELinux o 96 # This file controls the state of SELinux on the system. 97 # SELINUX= can take one of these three valu 97 # SELINUX= can take one of these three values: 98 # enforcing - SELinux security policy i 98 # enforcing - SELinux security policy is enforced. 99 # permissive - SELinux prints warnings 99 # permissive - SELinux prints warnings instead of enforcing. 100 # disabled - No SELinux policy is loade 100 # disabled - No SELinux policy is loaded. 101 SELINUX=permissive 101 SELINUX=permissive 102 # SELINUXTYPE= can take one of these three 102 # SELINUXTYPE= can take one of these three values: 103 # targeted - Targeted processes are pro 103 # targeted - Targeted processes are protected, 104 # minimum - Modification of targeted po 104 # minimum - Modification of targeted policy. Only selected processes are protected. 105 # mls - Multi Level Security protection 105 # mls - Multi Level Security protection. 106 SELINUXTYPE=targeted 106 SELINUXTYPE=targeted 107 107 108 7. Enable filesystem SELinux labeling at the n 108 7. Enable filesystem SELinux labeling at the next reboot: 109 109 110 # touch /.autorelabel 110 # touch /.autorelabel 111 111 112 8. Reboot machine and it will label filesystem 112 8. Reboot machine and it will label filesystems and load Targeted policy into the kernel; 113 113 114 9. Login and check that dmesg output doesn't m 114 9. Login and check that dmesg output doesn't mention that perf_event class is unknown to SELinux subsystem; 115 115 116 10. Check that SELinux is enabled and in Permi 116 10. Check that SELinux is enabled and in Permissive mode 117 117 118 # getenforce 118 # getenforce 119 Permissive 119 Permissive 120 120 121 11. Turn SELinux into Enforcing mode: 121 11. Turn SELinux into Enforcing mode: 122 122 123 # setenforce 1 123 # setenforce 1 124 # getenforce 124 # getenforce 125 Enforcing 125 Enforcing 126 126 127 Opening access to perf_event_open() syscall on 127 Opening access to perf_event_open() syscall on Fedora with SELinux 128 ============================================== 128 ================================================================== 129 129 130 Access to performance monitoring and observabi 130 Access to performance monitoring and observability operations by Perf 131 can be limited for superuser or CAP_PERFMON or 131 can be limited for superuser or CAP_PERFMON or CAP_SYS_ADMIN privileged 132 processes. MAC policy settings (e.g. SELinux) 132 processes. MAC policy settings (e.g. SELinux) can be loaded into the kernel 133 and prevent unauthorized access to perf_event_ 133 and prevent unauthorized access to perf_event_open() syscall. In such case 134 Perf tool provides a message similar to the on 134 Perf tool provides a message similar to the one below: 135 135 136 # perf stat 136 # perf stat 137 Error: 137 Error: 138 Access to performance monitoring and observ 138 Access to performance monitoring and observability operations is limited. 139 Enforced MAC policy settings (SELinux) can 139 Enforced MAC policy settings (SELinux) can limit access to performance 140 monitoring and observability operations. In 140 monitoring and observability operations. Inspect system audit records for 141 more perf_event access control information 141 more perf_event access control information and adjusting the policy. 142 Consider adjusting /proc/sys/kernel/perf_ev 142 Consider adjusting /proc/sys/kernel/perf_event_paranoid setting to open 143 access to performance monitoring and observ 143 access to performance monitoring and observability operations for users 144 without CAP_PERFMON or CAP_SYS_ADMIN Linux 144 without CAP_PERFMON or CAP_SYS_ADMIN Linux capability. 145 perf_event_paranoid setting is -1: 145 perf_event_paranoid setting is -1: 146 -1: Allow use of (almost) all events by a 146 -1: Allow use of (almost) all events by all users 147 Ignore mlock limit after perf_event_m 147 Ignore mlock limit after perf_event_mlock_kb without CAP_IPC_LOCK 148 >= 0: Disallow raw and ftrace function trac 148 >= 0: Disallow raw and ftrace function tracepoint access 149 >= 1: Disallow CPU event access 149 >= 1: Disallow CPU event access 150 >= 2: Disallow kernel profiling 150 >= 2: Disallow kernel profiling 151 To make the adjusted perf_event_paranoid se 151 To make the adjusted perf_event_paranoid setting permanent preserve it 152 in /etc/sysctl.conf (e.g. kernel.perf_event 152 in /etc/sysctl.conf (e.g. kernel.perf_event_paranoid = <setting>) 153 153 154 To make sure that access is limited by MAC pol 154 To make sure that access is limited by MAC policy settings inspect system 155 audit records using journalctl command or /var 155 audit records using journalctl command or /var/log/audit/audit.log so the 156 output would contain AVC denied records relate 156 output would contain AVC denied records related to perf_event: 157 157 158 # journalctl --reverse --no-pager | grep pe 158 # journalctl --reverse --no-pager | grep perf_event 159 159 160 python3[1318099]: SELinux is preventing per 160 python3[1318099]: SELinux is preventing perf from open access on the perf_event labeled unconfined_t. 161 If yo 161 If you believe that perf should be allowed open access on perf_event labeled unconfined_t by default. 162 setroubleshoot[1318099]: SELinux is prevent 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-3bc2074935de 163 audit[1318098]: AVC avc: denied { open } 163 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=0 164 164 165 In order to open access to perf_event_open() s 165 In order to open access to perf_event_open() syscall MAC policy settings can 166 require to be extended. On SELinux system this 166 require to be extended. On SELinux system this can be done by loading a special 167 policy module extending base policy settings. 167 policy module extending base policy settings. Perf related policy module can 168 be generated using the system audit records ab 168 be generated using the system audit records about blocking perf_event access. 169 Run the command below to generate my-perf.te p 169 Run the command below to generate my-perf.te policy extension file with 170 perf_event related rules: 170 perf_event related rules: 171 171 172 # ausearch -c 'perf' --raw | audit2allow -M 172 # ausearch -c 'perf' --raw | audit2allow -M my-perf && cat my-perf.te 173 173 174 module my-perf 1.0; 174 module my-perf 1.0; 175 175 176 require { 176 require { 177 type unconfined_t; 177 type unconfined_t; 178 class perf_event { cpu kernel open rea 178 class perf_event { cpu kernel open read tracepoint write }; 179 } 179 } 180 180 181 #============= unconfined_t ============== 181 #============= unconfined_t ============== 182 allow unconfined_t self:perf_event { cpu ke 182 allow unconfined_t self:perf_event { cpu kernel open read tracepoint write }; 183 183 184 Now compile, pack and load my-perf.pp extensio 184 Now compile, pack and load my-perf.pp extension module into the kernel: 185 185 186 # checkmodule -M -m -o my-perf.mod my-perf. 186 # checkmodule -M -m -o my-perf.mod my-perf.te 187 # semodule_package -o my-perf.pp -m my-perf 187 # semodule_package -o my-perf.pp -m my-perf.mod 188 # semodule -X 300 -i my-perf.pp 188 # semodule -X 300 -i my-perf.pp 189 189 190 After all those taken steps above access to pe 190 After all those taken steps above access to perf_event_open() syscall should 191 now be allowed by the policy settings. Check a 191 now be allowed by the policy settings. Check access running Perf like this: 192 192 193 # perf stat 193 # perf stat 194 ^C 194 ^C 195 Performance counter stats for 'system wide' 195 Performance counter stats for 'system wide': 196 196 197 36,387.41 msec cpu-clock 197 36,387.41 msec cpu-clock # 7.999 CPUs utilized 198 2,629 context-switches 198 2,629 context-switches # 0.072 K/sec 199 57 cpu-migrations 199 57 cpu-migrations # 0.002 K/sec 200 1 page-faults 200 1 page-faults # 0.000 K/sec 201 263,721,559 cycles 201 263,721,559 cycles # 0.007 GHz 202 175,746,713 instructions 202 175,746,713 instructions # 0.67 insn per cycle 203 19,628,798 branches 203 19,628,798 branches # 0.539 M/sec 204 1,259,201 branch-misses 204 1,259,201 branch-misses # 6.42% of all branches 205 205 206 4.549061439 seconds time elapsed 206 4.549061439 seconds time elapsed 207 207 208 The generated perf-event.pp related policy ext 208 The generated perf-event.pp related policy extension module can be removed 209 from the kernel using this command: 209 from the kernel using this command: 210 210 211 # semodule -X 300 -r my-perf 211 # semodule -X 300 -r my-perf 212 212 213 Alternatively the module can be temporarily di 213 Alternatively the module can be temporarily disabled and enabled back using 214 these two commands: 214 these two commands: 215 215 216 # semodule -d my-perf 216 # semodule -d my-perf 217 # semodule -e my-perf 217 # semodule -e my-perf 218 218 219 If something went wrong 219 If something went wrong 220 ======================= 220 ======================= 221 221 222 To turn SELinux into Permissive mode: 222 To turn SELinux into Permissive mode: 223 # setenforce 0 223 # setenforce 0 224 224 225 To fully disable SELinux during kernel boot [3 225 To fully disable SELinux during kernel boot [3] set kernel command line parameter selinux=0 226 226 227 To remove SELinux labeling from local filesyst 227 To remove SELinux labeling from local filesystems: 228 # find / -mount -print0 | xargs -0 setfattr 228 # find / -mount -print0 | xargs -0 setfattr -h -x security.selinux 229 229 230 To fully turn SELinux off a machine set SELINU 230 To fully turn SELinux off a machine set SELINUX=disabled at /etc/selinux/config file and reboot; 231 231 232 Links 232 Links 233 ===== 233 ===== 234 234 235 [1] https://download-ib01.fedoraproject.org/pu 235 [1] https://download-ib01.fedoraproject.org/pub/fedora/linux/updates/31/Everything/SRPMS/Packages/s/selinux-policy-3.14.4-49.fc31.src.rpm 236 [2] https://docs.fedoraproject.org/en-US/Fedor 236 [2] https://docs.fedoraproject.org/en-US/Fedora/11/html/Security-Enhanced_Linux/sect-Security-Enhanced_Linux-Working_with_SELinux-Enabling_and_Disabling_SELinux.html 237 [3] https://danwalsh.livejournal.com/10972.htm 237 [3] https://danwalsh.livejournal.com/10972.html
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.