sepolicy: allow init to share a kallsyms fd with tracing daemons
See r.android.com/3408241 for context.
The new order of operations in init:
1) open /proc/kallsyms while it is allowed to see the raw addresses,
which becomes a property of that fd. The fd is retained.
2) Raise kptr_restrict to 2, masking out addresses for all future opens
of /proc/kallsyms, including by init itself. This happens before
the "early-init" stage.
3) Share duplicates of the original saved fd with tracing daemons when
they're started.
The two daemons are still allowed to open their own copies of
/proc/kallsyms to facilitate file locks to coordinate access to the
shared fd (which cannot be used for locking as all processes will share
the lock as well). These opens are harmless since they couldn't give
more info than the fd shared by init (and in practice, the addresses
will be masked out due to kptr_restrict=2).
I've removed the neverallow exclusion for vendor_init since I believe
there wasn't a concrete use-case when it was first added, and it does
not participate in this new fd sharing.
Bug: 383513654
Change-Id: Ie2ab26da6186524bc77cd99bb55a61cef4a7ddf4
diff --git a/microdroid/system/private/init.te b/microdroid/system/private/init.te
index 9a0345f..11e398e 100644
--- a/microdroid/system/private/init.te
+++ b/microdroid/system/private/init.te
@@ -19,6 +19,12 @@
allow init self:global_capability2_class_set perfmon;
dontaudit init self:perf_event { kernel tracepoint read write };
+# Allow opening /proc/kallsyms so that on boot, init can create and retain an
+# fd with the full address visibility (which is evaluated on open and persists
+# for the lifetime of the open file description). This fd can then be shared
+# with other privileged processes.
+allow init proc_kallsyms:file r_file_perms;
+
# Allow init to restore contexts of vd_device(/dev/block/vd[..]) when labeling
# /dev/block.
allow init vd_device:blk_file relabelto;
diff --git a/private/domain.te b/private/domain.te
index e941e10..d671a48 100644
--- a/private/domain.te
+++ b/private/domain.te
@@ -2120,18 +2120,24 @@
-dumpstate
} mm_events_config_prop:file no_rw_file_perms;
-# Allow the tracing daemon and callstack sampler to use kallsyms to symbolize
-# kernel traces. Addresses are not disclosed, they are repalced with symbol
-# names (if available). Traces don't disclose KASLR.
+# Allow init to open /proc/kallsyms while kernel address mappings are still
+# visible, and later share it with tracing daemons (traced_probes,
+# traced_perf). These daemons are allowed to read from the shared fd, but also
+# to separately open the file (which will always have zeroed out addresses due
+# to init raising kptr_restrict) for locking to coordinate access to the shared
+# fd. The performance traces contain only the referenced kernel symbols, and
+# never the raw addresses (i.e. KASLR is not disclosed).
+# On debuggable builds, performance tools are allowed to open and read the file
+# directly because init is allowed to temporarily unrestrict systemwide address
+# visibility.
neverallow {
domain
-init
- userdebug_or_eng(`-profcollectd')
- -vendor_init
- userdebug_or_eng(`-simpleperf_boot')
-traced_probes
-traced_perf
-} proc_kallsyms:file { open read };
+ userdebug_or_eng(`-profcollectd')
+ userdebug_or_eng(`-simpleperf_boot')
+} proc_kallsyms:file *;
# debugfs_kcov type is not included in this neverallow statement since the KCOV
# tool uses it for kernel fuzzing.
diff --git a/private/init.te b/private/init.te
index b16e918..c3899e1 100644
--- a/private/init.te
+++ b/private/init.te
@@ -68,6 +68,12 @@
allow init self:perf_event { open cpu };
allow init self:global_capability2_class_set perfmon;
+# Allow opening /proc/kallsyms so that on boot, init can create and retain an
+# fd with the full address visibility (which is evaluated on open and persists
+# for the lifetime of the open file description). This fd can then be shared
+# with other privileged processes.
+allow init proc_kallsyms:file r_file_perms;
+
# Allow init to communicate with snapuserd to transition Virtual A/B devices
# from the first-stage daemon to the second-stage.
allow init snapuserd_socket:sock_file write;
diff --git a/private/traced_perf.te b/private/traced_perf.te
index c7e81cd..8bd7ad3 100644
--- a/private/traced_perf.te
+++ b/private/traced_perf.te
@@ -35,10 +35,13 @@
r_dir_file(traced_perf, apex_art_data_file)
allow traced_perf apex_module_data_file:dir { getattr search };
-# Allow to temporarily lift the kptr_restrict setting and build a symbolization
-# map reading /proc/kallsyms.
+# For kernel address symbolisation. Allow reading from /proc/kallsyms inherited
+# from init, as well as separately opening and locking the file for
+# coordinating the use of that shared fd.
+# On debuggable builds, allow using lower_kptr_restrict_prop to temporarily
+# lift kptr_restrict systemwide.
userdebug_or_eng(`set_prop(traced_perf, lower_kptr_restrict_prop)')
-allow traced_perf proc_kallsyms:file r_file_perms;
+allow traced_perf proc_kallsyms:file { open read lock };
# Allow reading tracefs files to get the format and numeric ids of tracepoints.
allow traced_perf debugfs_tracing:dir r_dir_perms;
diff --git a/private/traced_probes.te b/private/traced_probes.te
index 6540420..78dc7eb 100644
--- a/private/traced_probes.te
+++ b/private/traced_probes.te
@@ -35,10 +35,13 @@
# Allow procfs access
r_dir_file(traced_probes, domain)
-# Allow to temporarily lift the kptr_restrict setting and build a symbolization
-# map reading /proc/kallsyms.
+# For kernel address symbolisation. Allow reading from /proc/kallsyms inherited
+# from init, as well as separately opening and locking the file for
+# coordinating the use of that shared fd.
+# On debuggable builds, allow using lower_kptr_restrict_prop to temporarily
+# lift kptr_restrict systemwide.
userdebug_or_eng(`set_prop(traced_probes, lower_kptr_restrict_prop)')
-allow traced_probes proc_kallsyms:file r_file_perms;
+allow traced_probes proc_kallsyms:file { open read lock };
# Allow to read packages.list file.
allow traced_probes packages_list_file:file r_file_perms;
diff --git a/private/vendor_init.te b/private/vendor_init.te
index a50bc27..60962d4 100644
--- a/private/vendor_init.te
+++ b/private/vendor_init.te
@@ -116,6 +116,7 @@
-aconfig_storage_metadata_file
-aconfig_storage_flags_metadata_file
-tradeinmode_metadata_file
+ -proc_kallsyms
enforce_debugfs_restriction(`-debugfs_type')
}:file { create getattr open read write setattr relabelfrom unlink map };
@@ -195,6 +196,7 @@
-proc_uid_time_in_state
-proc_uid_concurrent_active_time
-proc_uid_concurrent_policy_time
+ -proc_kallsyms
enforce_debugfs_restriction(`-debugfs_type')
}:file { open read setattr map };