init: add "shared_kallsyms" option for tracing daemons

The perfetto tracing daemons can currently symbolise kernel addresses
within ftrace & perf_event data on debuggable builds, but not on release
builds. This is due to concerns with side-effects of changing the
kptr_restrict sysctl at runtime, as it affects more than just
/proc/kallsyms. The sysctl also controls vsprintf behaviour in the
kernel (affecting printk and e.g. /proc/vmallocinfo), as well as other
procfs files such as /proc/modules. This patch adds a special case to
init to allow for kernel address symbolisation on release builds without
any additional kptr_restrict changes.

The key observations are:
* symbol visibility through an opened /proc/kallsyms fd is fixed for the
  lifetime of that fd as it's cached in the kernel seq_file structure.
* second_stage init is responsible for changing the kptr_restrict from
  the on-boot Linux default (0) to the Android's default of 2. init is
  therefore uniquely positioned to open /proc/kallsyms while addresses
  are still visible to itself (due to CAP_SYSLOG).

This patch makes second_stage init open /proc/kallsyms and save that fd
as a static, which is then duplicated and passed to services specifying
a new "shared_kallsyms" option. Permissions are enforced by selinux,
since the service domains needs to be allowed to read files with the
`proc_kallsyms` label.

See go/perfetto-kallsyms-user for more details.

Test: atest CtsPerfettoTestCases
Test: manual tracing on panther-trunk_staging-user{,debug}
Bug: 383513654
Change-Id: I7bc707521349b7f50a32283642927bc4982dd9a1
6 files changed