Add sysprop for init's perf_event_open LSM hook check

Written exclusively by init. Made it readable by shell for CTS, and for
easier platform debugging.

Bug: 137092007
Change-Id: Ia5b056117502c272bc7169661069d0c8020695e2
diff --git a/private/compat/29.0/29.0.ignore.cil b/private/compat/29.0/29.0.ignore.cil
index 3a5be19..9f798fc 100644
--- a/private/compat/29.0/29.0.ignore.cil
+++ b/private/compat/29.0/29.0.ignore.cil
@@ -41,6 +41,7 @@
     incfs
     incremental_service
     incremental_root_file
+    init_perf_lsm_hooks_prop
     init_svc_debug_prop
     iorap_prefetcherd
     iorap_prefetcherd_data_file
diff --git a/private/init.te b/private/init.te
index 116eff4..42ec0f3 100644
--- a/private/init.te
+++ b/private/init.te
@@ -45,3 +45,18 @@
 set_prop(init, userspace_reboot_exported_prop)
 neverallow { domain -init } userspace_reboot_prop:property_service set;
 neverallow { domain -init } userspace_reboot_exported_prop:property_service set;
+
+# Second-stage init performs a test for whether the kernel has SELinux hooks
+# for the perf_event_open() syscall. This is done by testing for the syscall
+# outcomes corresponding to this policy.
+# TODO(b/137092007): this can be removed once the platform stops supporting
+# kernels that precede the perf_event_open hooks (Android common kernels 4.4
+# and 4.9).
+allow init self:perf_event { open cpu };
+neverallow init self:perf_event { kernel tracepoint read write };
+dontaudit init self:perf_event { kernel tracepoint read write };
+
+# Only init is allowed to set the sysprop indicating whether perf_event_open()
+# SELinux hooks were detected.
+set_prop(init, init_perf_lsm_hooks_prop)
+neverallow { domain -init } init_perf_lsm_hooks_prop:property_service set;
diff --git a/private/property_contexts b/private/property_contexts
index 625bf37..2db46a0 100644
--- a/private/property_contexts
+++ b/private/property_contexts
@@ -23,6 +23,7 @@
 ro.hw.                  u:object_r:system_prop:s0
 sys.                    u:object_r:system_prop:s0
 sys.init.userspace_reboot   u:object_r:userspace_reboot_prop:s0
+sys.init.perf_lsm_hooks u:object_r:init_perf_lsm_hooks_prop:s0
 sys.cppreopt            u:object_r:cppreopt_prop:s0
 sys.linker.             u:object_r:linker_prop:s0
 sys.lpdumpd             u:object_r:lpdumpd_prop:s0
diff --git a/public/property.te b/public/property.te
index 7a1e4dd..8142aa2 100644
--- a/public/property.te
+++ b/public/property.te
@@ -13,6 +13,7 @@
 system_internal_prop(device_config_sys_traced_prop)
 system_internal_prop(firstboot_prop)
 system_internal_prop(gsid_prop)
+system_internal_prop(init_perf_lsm_hooks_prop)
 system_internal_prop(init_svc_debug_prop)
 system_internal_prop(last_boot_reason_prop)
 system_internal_prop(netd_stable_secret_prop)
diff --git a/public/shell.te b/public/shell.te
index 532d05f..8bce38d 100644
--- a/public/shell.te
+++ b/public/shell.te
@@ -106,6 +106,9 @@
 get_prop(shell, last_boot_reason_prop)
 get_prop(shell, system_boot_reason_prop)
 
+# Allow reading the outcome of perf_event_open LSM support test for CTS.
+get_prop(shell, init_perf_lsm_hooks_prop)
+
 # allow shell access to services
 allow shell servicemanager:service_manager list;
 # don't allow shell to access GateKeeper service
diff --git a/public/vendor_init.te b/public/vendor_init.te
index 6a20bf2..609821f 100644
--- a/public/vendor_init.te
+++ b/public/vendor_init.te
@@ -220,6 +220,7 @@
       -apexd_prop
       -gsid_prop
       -nnapi_ext_deny_product_prop
+      -init_perf_lsm_hooks_prop
       -init_svc_debug_prop
       -linker_prop
       -module_sdkextensions_prop