162306a36Sopenharmony_ciOverview
262306a36Sopenharmony_ci========
362306a36Sopenharmony_ci
462306a36Sopenharmony_ciFor general security related questions of perf_event_open() syscall usage,
562306a36Sopenharmony_ciperformance monitoring and observability operations by Perf see here:
662306a36Sopenharmony_cihttps://www.kernel.org/doc/html/latest/admin-guide/perf-security.html
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciEnabling LSM based mandatory access control (MAC) to perf_event_open() syscall
962306a36Sopenharmony_ci==============================================================================
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciLSM hooks for mandatory access control for perf_event_open() syscall can be
1262306a36Sopenharmony_ciused starting from Linux v5.3. Below are the steps to extend Fedora (v31) with
1362306a36Sopenharmony_ciTargeted policy with perf_event_open() access control capabilities:
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci1. Download selinux-policy SRPM package (e.g. selinux-policy-3.14.4-48.fc31.src.rpm on FC31)
1662306a36Sopenharmony_ci   and install it so rpmbuild directory would exist in the current working directory:
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci   # rpm -Uhv selinux-policy-3.14.4-48.fc31.src.rpm
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci2. Get into rpmbuild/SPECS directory and unpack the source code:
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci   # rpmbuild -bp selinux-policy.spec
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci3. Place patch below at rpmbuild/BUILD/selinux-policy-b86eaaf4dbcf2d51dd4432df7185c0eaf3cbcc02
2562306a36Sopenharmony_ci   directory and apply it:
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci   # patch -p1 < selinux-policy-perf-events-perfmon.patch
2862306a36Sopenharmony_ci   patching file policy/flask/access_vectors
2962306a36Sopenharmony_ci   patching file policy/flask/security_classes
3062306a36Sopenharmony_ci   # cat selinux-policy-perf-events-perfmon.patch
3162306a36Sopenharmony_cidiff -Nura a/policy/flask/access_vectors b/policy/flask/access_vectors
3262306a36Sopenharmony_ci--- a/policy/flask/access_vectors	2020-02-04 18:19:53.000000000 +0300
3362306a36Sopenharmony_ci+++ b/policy/flask/access_vectors	2020-02-28 23:37:25.000000000 +0300
3462306a36Sopenharmony_ci@@ -174,6 +174,7 @@
3562306a36Sopenharmony_ci 	wake_alarm
3662306a36Sopenharmony_ci 	block_suspend
3762306a36Sopenharmony_ci 	audit_read
3862306a36Sopenharmony_ci+	perfmon
3962306a36Sopenharmony_ci }
4062306a36Sopenharmony_ci 
4162306a36Sopenharmony_ci #
4262306a36Sopenharmony_ci@@ -1099,3 +1100,15 @@
4362306a36Sopenharmony_ci 
4462306a36Sopenharmony_ci class xdp_socket
4562306a36Sopenharmony_ci inherits socket
4662306a36Sopenharmony_ci+
4762306a36Sopenharmony_ci+class perf_event
4862306a36Sopenharmony_ci+{
4962306a36Sopenharmony_ci+	open
5062306a36Sopenharmony_ci+	cpu
5162306a36Sopenharmony_ci+	kernel
5262306a36Sopenharmony_ci+	tracepoint
5362306a36Sopenharmony_ci+	read
5462306a36Sopenharmony_ci+	write
5562306a36Sopenharmony_ci+}
5662306a36Sopenharmony_ci+
5762306a36Sopenharmony_ci+
5862306a36Sopenharmony_cidiff -Nura a/policy/flask/security_classes b/policy/flask/security_classes
5962306a36Sopenharmony_ci--- a/policy/flask/security_classes	2020-02-04 18:19:53.000000000 +0300
6062306a36Sopenharmony_ci+++ b/policy/flask/security_classes	2020-02-28 21:35:17.000000000 +0300
6162306a36Sopenharmony_ci@@ -200,4 +200,6 @@
6262306a36Sopenharmony_ci 
6362306a36Sopenharmony_ci class xdp_socket
6462306a36Sopenharmony_ci 
6562306a36Sopenharmony_ci+class perf_event
6662306a36Sopenharmony_ci+
6762306a36Sopenharmony_ci # FLASK
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci4. Get into rpmbuild/SPECS directory and build policy packages from patched sources:
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci   # rpmbuild --noclean --noprep -ba selinux-policy.spec
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci   so you have this:
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci   # ls -alh rpmbuild/RPMS/noarch/
7662306a36Sopenharmony_ci   total 33M
7762306a36Sopenharmony_ci   drwxr-xr-x. 2 root root 4.0K Mar 20 12:16 .
7862306a36Sopenharmony_ci   drwxr-xr-x. 3 root root 4.0K Mar 20 12:16 ..
7962306a36Sopenharmony_ci   -rw-r--r--. 1 root root 112K Mar 20 12:16 selinux-policy-3.14.4-48.fc31.noarch.rpm
8062306a36Sopenharmony_ci   -rw-r--r--. 1 root root 1.2M Mar 20 12:17 selinux-policy-devel-3.14.4-48.fc31.noarch.rpm
8162306a36Sopenharmony_ci   -rw-r--r--. 1 root root 2.3M Mar 20 12:17 selinux-policy-doc-3.14.4-48.fc31.noarch.rpm
8262306a36Sopenharmony_ci   -rw-r--r--. 1 root root  12M Mar 20 12:17 selinux-policy-minimum-3.14.4-48.fc31.noarch.rpm
8362306a36Sopenharmony_ci   -rw-r--r--. 1 root root 4.5M Mar 20 12:16 selinux-policy-mls-3.14.4-48.fc31.noarch.rpm
8462306a36Sopenharmony_ci   -rw-r--r--. 1 root root 111K Mar 20 12:16 selinux-policy-sandbox-3.14.4-48.fc31.noarch.rpm
8562306a36Sopenharmony_ci   -rw-r--r--. 1 root root  14M Mar 20 12:17 selinux-policy-targeted-3.14.4-48.fc31.noarch.rpm
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci5. Install SELinux packages from Fedora repo, if not already done so, and
8862306a36Sopenharmony_ci   update with the patched rpms above:
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci   # rpm -Uhv rpmbuild/RPMS/noarch/selinux-policy-*
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci6. Enable SELinux Permissive mode for Targeted policy, if not already done so:
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci   # cat /etc/selinux/config
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci   # This file controls the state of SELinux on the system.
9762306a36Sopenharmony_ci   # SELINUX= can take one of these three values:
9862306a36Sopenharmony_ci   #     enforcing - SELinux security policy is enforced.
9962306a36Sopenharmony_ci   #     permissive - SELinux prints warnings instead of enforcing.
10062306a36Sopenharmony_ci   #     disabled - No SELinux policy is loaded.
10162306a36Sopenharmony_ci   SELINUX=permissive
10262306a36Sopenharmony_ci   # SELINUXTYPE= can take one of these three values:
10362306a36Sopenharmony_ci   #     targeted - Targeted processes are protected,
10462306a36Sopenharmony_ci   #     minimum - Modification of targeted policy. Only selected processes are protected.
10562306a36Sopenharmony_ci   #     mls - Multi Level Security protection.
10662306a36Sopenharmony_ci   SELINUXTYPE=targeted
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci7. Enable filesystem SELinux labeling at the next reboot:
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci   # touch /.autorelabel
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci8. Reboot machine and it will label filesystems and load Targeted policy into the kernel;
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci9. Login and check that dmesg output doesn't mention that perf_event class is unknown to SELinux subsystem;
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci10. Check that SELinux is enabled and in Permissive mode
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci    # getenforce
11962306a36Sopenharmony_ci    Permissive
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci11. Turn SELinux into Enforcing mode:
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci    # setenforce 1
12462306a36Sopenharmony_ci    # getenforce
12562306a36Sopenharmony_ci    Enforcing
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ciOpening access to perf_event_open() syscall on Fedora with SELinux
12862306a36Sopenharmony_ci==================================================================
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ciAccess to performance monitoring and observability operations by Perf
13162306a36Sopenharmony_cican be limited for superuser or CAP_PERFMON or CAP_SYS_ADMIN privileged
13262306a36Sopenharmony_ciprocesses. MAC policy settings (e.g. SELinux) can be loaded into the kernel
13362306a36Sopenharmony_ciand prevent unauthorized access to perf_event_open() syscall. In such case
13462306a36Sopenharmony_ciPerf tool provides a message similar to the one below:
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci   # perf stat
13762306a36Sopenharmony_ci   Error:
13862306a36Sopenharmony_ci   Access to performance monitoring and observability operations is limited.
13962306a36Sopenharmony_ci   Enforced MAC policy settings (SELinux) can limit access to performance
14062306a36Sopenharmony_ci   monitoring and observability operations. Inspect system audit records for
14162306a36Sopenharmony_ci   more perf_event access control information and adjusting the policy.
14262306a36Sopenharmony_ci   Consider adjusting /proc/sys/kernel/perf_event_paranoid setting to open
14362306a36Sopenharmony_ci   access to performance monitoring and observability operations for users
14462306a36Sopenharmony_ci   without CAP_PERFMON or CAP_SYS_ADMIN Linux capability.
14562306a36Sopenharmony_ci   perf_event_paranoid setting is -1:
14662306a36Sopenharmony_ci     -1: Allow use of (almost) all events by all users
14762306a36Sopenharmony_ci         Ignore mlock limit after perf_event_mlock_kb without CAP_IPC_LOCK
14862306a36Sopenharmony_ci   >= 0: Disallow raw and ftrace function tracepoint access
14962306a36Sopenharmony_ci   >= 1: Disallow CPU event access
15062306a36Sopenharmony_ci   >= 2: Disallow kernel profiling
15162306a36Sopenharmony_ci   To make the adjusted perf_event_paranoid setting permanent preserve it
15262306a36Sopenharmony_ci   in /etc/sysctl.conf (e.g. kernel.perf_event_paranoid = <setting>)
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ciTo make sure that access is limited by MAC policy settings inspect system
15562306a36Sopenharmony_ciaudit records using journalctl command or /var/log/audit/audit.log so the
15662306a36Sopenharmony_cioutput would contain AVC denied records related to perf_event:
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci   # journalctl --reverse --no-pager | grep perf_event
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci   python3[1318099]: SELinux is preventing perf from open access on the perf_event labeled unconfined_t.
16162306a36Sopenharmony_ci                                         If you believe that perf should be allowed open access on perf_event labeled unconfined_t by default.
16262306a36Sopenharmony_ci   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
16362306a36Sopenharmony_ci   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
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ciIn order to open access to perf_event_open() syscall MAC policy settings can
16662306a36Sopenharmony_cirequire to be extended. On SELinux system this can be done by loading a special
16762306a36Sopenharmony_cipolicy module extending base policy settings. Perf related policy module can
16862306a36Sopenharmony_cibe generated using the system audit records about blocking perf_event access.
16962306a36Sopenharmony_ciRun the command below to generate my-perf.te policy extension file with
17062306a36Sopenharmony_ciperf_event related rules:
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci   # ausearch -c 'perf' --raw | audit2allow -M my-perf && cat my-perf.te
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci   module my-perf 1.0;
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci   require {
17762306a36Sopenharmony_ci        type unconfined_t;
17862306a36Sopenharmony_ci        class perf_event { cpu kernel open read tracepoint write };
17962306a36Sopenharmony_ci   }
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci   #============= unconfined_t ==============
18262306a36Sopenharmony_ci   allow unconfined_t self:perf_event { cpu kernel open read tracepoint write };
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ciNow compile, pack and load my-perf.pp extension module into the kernel:
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci   # checkmodule -M -m -o my-perf.mod my-perf.te
18762306a36Sopenharmony_ci   # semodule_package -o my-perf.pp -m my-perf.mod
18862306a36Sopenharmony_ci   # semodule -X 300 -i my-perf.pp
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ciAfter all those taken steps above access to perf_event_open() syscall should
19162306a36Sopenharmony_cinow be allowed by the policy settings. Check access running Perf like this:
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci   # perf stat
19462306a36Sopenharmony_ci   ^C
19562306a36Sopenharmony_ci   Performance counter stats for 'system wide':
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci         36,387.41 msec cpu-clock                 #    7.999 CPUs utilized
19862306a36Sopenharmony_ci             2,629      context-switches          #    0.072 K/sec
19962306a36Sopenharmony_ci                57      cpu-migrations            #    0.002 K/sec
20062306a36Sopenharmony_ci                 1      page-faults               #    0.000 K/sec
20162306a36Sopenharmony_ci       263,721,559      cycles                    #    0.007 GHz
20262306a36Sopenharmony_ci       175,746,713      instructions              #    0.67  insn per cycle
20362306a36Sopenharmony_ci        19,628,798      branches                  #    0.539 M/sec
20462306a36Sopenharmony_ci         1,259,201      branch-misses             #    6.42% of all branches
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci       4.549061439 seconds time elapsed
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ciThe generated perf-event.pp related policy extension module can be removed
20962306a36Sopenharmony_cifrom the kernel using this command:
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci   # semodule -X 300 -r my-perf
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ciAlternatively the module can be temporarily disabled and enabled back using
21462306a36Sopenharmony_cithese two commands:
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci   # semodule -d my-perf
21762306a36Sopenharmony_ci   # semodule -e my-perf
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ciIf something went wrong
22062306a36Sopenharmony_ci=======================
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ciTo turn SELinux into Permissive mode:
22362306a36Sopenharmony_ci   # setenforce 0
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ciTo fully disable SELinux during kernel boot [3] set kernel command line parameter selinux=0
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ciTo remove SELinux labeling from local filesystems:
22862306a36Sopenharmony_ci   # find / -mount -print0 | xargs -0 setfattr -h -x security.selinux
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ciTo fully turn SELinux off a machine set SELINUX=disabled at /etc/selinux/config file and reboot;
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ciLinks
23362306a36Sopenharmony_ci=====
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci[1] https://download-ib01.fedoraproject.org/pub/fedora/linux/updates/31/Everything/SRPMS/Packages/s/selinux-policy-3.14.4-49.fc31.src.rpm
23662306a36Sopenharmony_ci[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
23762306a36Sopenharmony_ci[3] https://danwalsh.livejournal.com/10972.html
238