much more finegrained bpf selinux privs for networking mainline

Goal is to gain a better handle on who has access to which maps
and to allow (with bpfloader changes to create in one directory
and move into the target directory) per-map selection of
selinux context, while still having reasonable defaults for stuff
pinned directly into the target location.

BPFFS (ie. /sys/fs/bpf) labelling is as follows:
  subdirectory   selinux context      mainline  usecase / usable by
  /              fs_bpf               no (*)    core operating system (ie. platform)
  /net_private   fs_bpf_net_private   yes, T+   network_stack
  /net_shared    fs_bpf_net_shared    yes, T+   network_stack & system_server
  /netd_readonly fs_bpf_netd_readonly yes, T+   network_stack & system_server & r/o to netd
  /netd_shared   fs_bpf_netd_shared   yes, T+   network_stack & system_server & netd [**]
  /tethering     fs_bpf_tethering     yes, S+   network_stack
  /vendor        fs_bpf_vendor        no, T+    vendor

* initial support for bpf was added back in P,
  but things worked differently back then with no bpfloader,
  and instead netd doing stuff by hand,
  bpfloader with pinning into /sys/fs/bpf was (I believe) added in Q
  (and was definitely there in R)

** additionally bpf programs are accesible to netutils_wrapper
   for use by iptables xt_bpf extensions

'mainline yes' currently means shipped by the com.android.tethering apex,
but this is really another case of bad naming, as it's really
the 'networking/connectivity/tethering' apex / mainline module.
Long term the plan is to merge a few other networking mainline modules
into it (and maybe give it a saner name...).

The reason for splitting net_private vs tethering is that:
  S+ must support 4.9+ kernels and S era bpfloader v0.2+
  T+ must support 4.14+ kernels and T beta3 era bpfloader v0.13+

The kernel affects the intelligence of the in-kernel bpf verifier
and the available bpf helper functions.  Older kernels have
a tendency to reject programs that newer kernels allow.

/ && /vendor are not shipped via mainline, so only need to work
with the bpfloader that's part of the core os.

Ignore-AOSP-First: will be cherrypicked from tm-dev to aosp/master

Bug: 218408035
Test: TreeHugger, manually on cuttlefish
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I674866ebe32aca4fc851818c1ffcbec12ac4f7d4
This commit is contained in:
Maciej Żenczykowski 2022-05-21 05:03:29 -07:00
parent 57f48ae1d2
commit 15715aea32
21 changed files with 174 additions and 44 deletions

View file

@ -6,9 +6,9 @@ typeattribute bpfloader bpfdomain;
allow bpfloader kmsg_device:chr_file w_file_perms;
# These permissions are required to pin ebpf maps & programs.
allow bpfloader { fs_bpf fs_bpf_tethering fs_bpf_vendor }:dir { add_name create search write };
allow bpfloader { fs_bpf fs_bpf_tethering fs_bpf_vendor }:file { create read setattr };
allow { fs_bpf_tethering fs_bpf_vendor } fs_bpf:filesystem associate;
allow bpfloader bpffs_type:dir { add_name create remove_name search write };
allow bpfloader bpffs_type:file { create read rename setattr };
allow { bpffs_type -fs_bpf } fs_bpf:filesystem associate;
# Allow bpfloader to create bpf maps and programs.
allow bpfloader self:bpf { map_create map_read map_write prog_load prog_run };
@ -26,17 +26,21 @@ allow bpfloader bpfloader_exec:file execute_no_trans;
###
# TODO: get rid of init & vendor_init; Note: we don't care about getattr/mounton/search
neverallow { domain -init -vendor_init } { fs_bpf fs_bpf_tethering fs_bpf_vendor }:dir { open read setattr };
neverallow { domain -bpfloader } { fs_bpf fs_bpf_tethering fs_bpf_vendor }:dir { add_name create write };
neverallow domain { fs_bpf fs_bpf_tethering fs_bpf_vendor }:dir ~{ add_name create getattr mounton open read search setattr write };
neverallow { domain -init -vendor_init } bpffs_type:dir { open read setattr };
neverallow { domain -bpfloader } bpffs_type:dir { add_name create remove_name write };
neverallow domain bpffs_type:dir ~{ add_name create getattr mounton open read remove_name search setattr write };
# TODO: get rid of init & vendor_init
neverallow { domain -bpfloader -init -vendor_init } { fs_bpf fs_bpf_tethering fs_bpf_vendor }:file { map open setattr };
neverallow { domain -bpfloader } { fs_bpf fs_bpf_tethering fs_bpf_vendor }:file create;
neverallow { domain -bpfloader -gpuservice -init -lmkd -mediaprovider_app -netd -netutils_wrapper -network_stack -system_server -vendor_init } { fs_bpf }:file read;
neverallow { domain -bpfloader -gpuservice -init -lmkd -netd -netutils_wrapper -network_stack -system_server -vendor_init } { fs_bpf_tethering }:file read;
neverallow { domain -bpfloader -gpuservice -netd -netutils_wrapper -network_stack -system_server } { fs_bpf fs_bpf_tethering }:file write;
neverallow domain { fs_bpf fs_bpf_tethering }:file ~{ create map open read setattr write };
neverallow { domain -bpfloader -init -vendor_init } bpffs_type:file { map open setattr };
neverallow { domain -bpfloader } bpffs_type:file { create rename };
neverallow { domain -bpfloader -gpuservice -init -lmkd -mediaprovider_app -netd -netutils_wrapper -system_server -vendor_init } fs_bpf:file read;
neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_net_private:file read;
neverallow { domain -bpfloader -init -network_stack -system_server -vendor_init } fs_bpf_net_shared:file read;
neverallow { domain -bpfloader -init -netd -network_stack -system_server -vendor_init } fs_bpf_netd_readonly:file read;
neverallow { domain -bpfloader -init -netd -netutils_wrapper -network_stack -system_server -vendor_init } fs_bpf_netd_shared:file read;
neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_tethering:file read;
neverallow { domain -bpfloader -gpuservice -netd -netutils_wrapper -network_stack -system_server } { bpffs_type -fs_bpf_vendor }:file write;
neverallow domain bpffs_type:file ~{ create map open read rename setattr write };
neverallow { domain -bpfloader } *:bpf { map_create prog_load };

View file

@ -1,6 +1,13 @@
# /proc/config.gz
type config_gz, fs_type, proc_type;
# /sys/fs/bpf/<dir> for mainline tethering use
# TODO: move S+ fs_bpf_tethering here from public/file.te
type fs_bpf_net_private, fs_type, bpffs_type;
type fs_bpf_net_shared, fs_type, bpffs_type;
type fs_bpf_netd_readonly, fs_type, bpffs_type;
type fs_bpf_netd_shared, fs_type, bpffs_type;
# /data/misc/storaged
type storaged_data_file, file_type, data_file_type, core_data_file_type;

View file

@ -395,5 +395,9 @@ genfscon functionfs / u:object_r:functionfs:s0
genfscon usbfs / u:object_r:usbfs:s0
genfscon binfmt_misc / u:object_r:binfmt_miscfs:s0
genfscon bpf / u:object_r:fs_bpf:s0
genfscon bpf /net_private u:object_r:fs_bpf_net_private:s0
genfscon bpf /net_shared u:object_r:fs_bpf_net_shared:s0
genfscon bpf /netd_readonly u:object_r:fs_bpf_netd_readonly:s0
genfscon bpf /netd_shared u:object_r:fs_bpf_netd_shared:s0
genfscon bpf /tethering u:object_r:fs_bpf_tethering:s0
genfscon bpf /vendor u:object_r:fs_bpf_vendor:s0

View file

@ -6,6 +6,10 @@ init_daemon_domain(netd)
# Allow netd to spawn dnsmasq in it's own domain
domain_auto_trans(netd, dnsmasq_exec, dnsmasq)
allow netd { fs_bpf fs_bpf_netd_readonly fs_bpf_netd_shared }:dir search;
allow netd { fs_bpf fs_bpf_netd_readonly fs_bpf_netd_shared }:file read;
allow netd { fs_bpf fs_bpf_netd_shared }:file write;
# give netd permission to setup iptables rule with xt_bpf, attach program to cgroup, and read/write
# the map created by bpfloader
allow netd bpfloader:bpf { prog_run map_read map_write };

View file

@ -25,7 +25,9 @@ binder_call(netutils_wrapper, netd);
# For vendor code that update the iptables rules at runtime. They need to reload
# the whole chain including the xt_bpf rules. They need to access to the pinned
# program when reloading the rule.
allow netutils_wrapper fs_bpf:file { read write };
allow netutils_wrapper { fs_bpf fs_bpf_netd_shared }:dir search;
allow netutils_wrapper { fs_bpf fs_bpf_netd_shared }:file read;
allow netutils_wrapper { fs_bpf }:file write;
allow netutils_wrapper bpfloader:bpf prog_run;
# For /data/misc/net access to ndc and ip

View file

@ -60,8 +60,8 @@ hal_client_domain(network_stack, hal_tetheroffload)
allow network_stack self:netlink_netfilter_socket create_socket_perms_no_ioctl;
allow network_stack network_stack_service:service_manager find;
# allow Tethering(network_stack process) to run/update/read the eBPF maps to offload tethering traffic by eBPF.
allow network_stack { fs_bpf fs_bpf_tethering }:dir search;
allow network_stack { fs_bpf fs_bpf_tethering }:file { read write };
allow network_stack { fs_bpf_net_private fs_bpf_net_shared fs_bpf_netd_readonly fs_bpf_netd_shared fs_bpf_tethering }:dir search;
allow network_stack { fs_bpf_net_private fs_bpf_net_shared fs_bpf_netd_readonly fs_bpf_netd_shared fs_bpf_tethering }:file { read write };
allow network_stack bpfloader:bpf { map_read map_write prog_run };
# Use XFRM (IPsec) netlink sockets
@ -71,8 +71,46 @@ allow network_stack self:netlink_xfrm_socket { create_socket_perms_no_ioctl nlms
allow network_stack tun_device:chr_file rw_file_perms;
allowxperm network_stack tun_device:chr_file ioctl { TUNGETIFF TUNSETIFF TUNSETLINK TUNSETCARRIER };
# Only the bpfloader and the network_stack should ever touch 'fs_bpf_tethering' programs/maps.
############### NEVER ALLOW RULES
# This place is as good as any for these rules,
# and it is probably the most appropriate because
# network_stack itself is entirely mainline code.
#
# Unfortunately init/vendor_init have all sorts of extra privs
# T+: Only the bpfloader and the network_stack should ever touch 'fs_bpf_net_private' programs/maps.
neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_net_private:dir ~getattr;
neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_net_private:file *;
neverallow { domain -bpfloader -network_stack } fs_bpf_net_private:dir ~{ getattr open read search setattr };
neverallow { domain -bpfloader -network_stack } fs_bpf_net_private:file ~{ map open read setattr };
# T+: Only the bpfloader, network_stack and system_server should ever touch 'fs_bpf_net_shared' programs/maps.
neverallow { domain -bpfloader -init -network_stack -system_server -vendor_init } fs_bpf_net_shared:dir ~getattr;
neverallow { domain -bpfloader -init -network_stack -system_server -vendor_init } fs_bpf_net_shared:file *;
neverallow { domain -bpfloader -network_stack -system_server } fs_bpf_net_shared:dir ~{ getattr open read search setattr };
neverallow { domain -bpfloader -network_stack -system_server } fs_bpf_net_shared:file ~{ map open read setattr };
# T+: Only the bpfloader, netd, network_stack and system_server should ever touch 'fs_bpf_netd_readonly' programs/maps.
# netd's access should be readonly
neverallow { domain -bpfloader -init -netd -network_stack -system_server -vendor_init } fs_bpf_netd_readonly:dir ~getattr;
neverallow { domain -bpfloader -init -netd -network_stack -system_server -vendor_init } fs_bpf_netd_readonly:file *;
neverallow netd fs_bpf_netd_readonly:file write;
neverallow { domain -bpfloader -netd -network_stack -system_server } fs_bpf_netd_readonly:dir ~{ getattr open read search setattr };
neverallow { domain -bpfloader -netd -network_stack -system_server } fs_bpf_netd_readonly:file ~{ map open read setattr };
# T+: Only the bpfloader, netd, netutils_wrapper, network_stack and system_server should ever touch 'fs_bpf_netd_shared' programs/maps.
# netutils_wrapper requires access to be able to run iptables and only needs readonly access
neverallow { domain -bpfloader -init -netd -netutils_wrapper -network_stack -system_server -vendor_init } fs_bpf_netd_shared:dir ~getattr;
neverallow { domain -bpfloader -init -netd -netutils_wrapper -network_stack -system_server -vendor_init } fs_bpf_netd_shared:file *;
neverallow netutils_wrapper fs_bpf_netd_shared:file write;
neverallow { domain -bpfloader -netd -netutils_wrapper -network_stack -system_server } fs_bpf_netd_shared:dir ~{ getattr open read search setattr };
neverallow { domain -bpfloader -netd -netutils_wrapper -network_stack -system_server } fs_bpf_netd_shared:file ~{ map open read setattr };
# S+: Only the bpfloader and the network_stack should ever touch 'fs_bpf_tethering' programs/maps.
neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_tethering:dir ~getattr;
neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_tethering:file *;

View file

@ -1154,7 +1154,8 @@ with_asan(`
# allow system_server to read the eBPF maps that stores the traffic stats information and update
# the map after snapshot is recorded, and to read, update and run the maps and programs used for
# time in state accounting
allow system_server fs_bpf:file { read write };
allow system_server { fs_bpf fs_bpf_net_shared fs_bpf_netd_readonly fs_bpf_netd_shared }:dir search;
allow system_server { fs_bpf fs_bpf_net_shared fs_bpf_netd_readonly fs_bpf_netd_shared }:file { read write };
allow system_server bpfloader:bpf { map_read map_write prog_run };
# in order to invoke side effect of close() on such a socket calling synchronize_rcu()
allow system_server self:key_socket create;

View file

@ -10,6 +10,9 @@ attribute dev_type;
# TODO(b/202520796) Remove this attribute once the sc-dev branch stops using it.
attribute bdev_type;
# Attribute for all bpf filesystem subtypes.
attribute bpffs_type;
# All types used for processes.
attribute domain;

View file

@ -129,9 +129,10 @@ type sysfs_vendor_sched, sysfs_type, fs_type;
userdebug_or_eng(`
typeattribute sysfs_vendor_sched mlstrustedobject;
')
type fs_bpf, fs_type;
type fs_bpf_tethering, fs_type;
type fs_bpf_vendor, fs_type;
type fs_bpf, fs_type, bpffs_type;
# TODO: S+ fs_bpf_tethering (used by mainline) should be private
type fs_bpf_tethering, fs_type, bpffs_type;
type fs_bpf_vendor, fs_type, bpffs_type;
type configfs, fs_type;
# /sys/devices/cs_etm
type sysfs_devices_cs_etm, fs_type, sysfs_type;

View file

@ -64,8 +64,6 @@ allow netd sysfs_usb:file write;
r_dir_file(netd, cgroup_v2)
allow netd fs_bpf:file { read write };
# TODO: netd previously thought it needed these permissions to do WiFi related
# work. However, after all the WiFi stuff is gone, we still need them.
# Why?

View file

@ -6,9 +6,9 @@ typeattribute bpfloader bpfdomain;
allow bpfloader kmsg_device:chr_file w_file_perms;
# These permissions are required to pin ebpf maps & programs.
allow bpfloader { fs_bpf fs_bpf_tethering fs_bpf_vendor }:dir { add_name create search write };
allow bpfloader { fs_bpf fs_bpf_tethering fs_bpf_vendor }:file { create read setattr };
allow { fs_bpf_tethering fs_bpf_vendor } fs_bpf:filesystem associate;
allow bpfloader bpffs_type:dir { add_name create remove_name search write };
allow bpfloader bpffs_type:file { create read rename setattr };
allow { bpffs_type -fs_bpf } fs_bpf:filesystem associate;
# Allow bpfloader to create bpf maps and programs.
allow bpfloader self:bpf { map_create map_read map_write prog_load prog_run };
@ -26,17 +26,21 @@ allow bpfloader bpfloader_exec:file execute_no_trans;
###
# TODO: get rid of init & vendor_init; Note: we don't care about getattr/mounton/search
neverallow { domain -init -vendor_init } { fs_bpf fs_bpf_tethering fs_bpf_vendor }:dir { open read setattr };
neverallow { domain -bpfloader } { fs_bpf fs_bpf_tethering fs_bpf_vendor }:dir { add_name create write };
neverallow domain { fs_bpf fs_bpf_tethering fs_bpf_vendor }:dir ~{ add_name create getattr mounton open read search setattr write };
neverallow { domain -init -vendor_init } bpffs_type:dir { open read setattr };
neverallow { domain -bpfloader } bpffs_type:dir { add_name create remove_name write };
neverallow domain bpffs_type:dir ~{ add_name create getattr mounton open read remove_name search setattr write };
# TODO: get rid of init & vendor_init
neverallow { domain -bpfloader -init -vendor_init } { fs_bpf fs_bpf_tethering fs_bpf_vendor }:file { map open setattr };
neverallow { domain -bpfloader } { fs_bpf fs_bpf_tethering fs_bpf_vendor }:file create;
neverallow { domain -bpfloader -gpuservice -init -lmkd -mediaprovider_app -netd -netutils_wrapper -network_stack -system_server -vendor_init } { fs_bpf }:file read;
neverallow { domain -bpfloader -gpuservice -init -lmkd -netd -netutils_wrapper -network_stack -system_server -vendor_init } { fs_bpf_tethering }:file read;
neverallow { domain -bpfloader -gpuservice -netd -netutils_wrapper -network_stack -system_server } { fs_bpf fs_bpf_tethering }:file write;
neverallow domain { fs_bpf fs_bpf_tethering }:file ~{ create map open read setattr write };
neverallow { domain -bpfloader -init -vendor_init } bpffs_type:file { map open setattr };
neverallow { domain -bpfloader } bpffs_type:file { create rename };
neverallow { domain -bpfloader -gpuservice -init -lmkd -mediaprovider_app -netd -netutils_wrapper -system_server -vendor_init } fs_bpf:file read;
neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_net_private:file read;
neverallow { domain -bpfloader -init -network_stack -system_server -vendor_init } fs_bpf_net_shared:file read;
neverallow { domain -bpfloader -init -netd -network_stack -system_server -vendor_init } fs_bpf_netd_readonly:file read;
neverallow { domain -bpfloader -init -netd -netutils_wrapper -network_stack -system_server -vendor_init } fs_bpf_netd_shared:file read;
neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_tethering:file read;
neverallow { domain -bpfloader -gpuservice -netd -netutils_wrapper -network_stack -system_server } { bpffs_type -fs_bpf_vendor }:file write;
neverallow domain bpffs_type:file ~{ create map open read rename setattr write };
neverallow { domain -bpfloader } *:bpf { map_create prog_load };

View file

@ -1,6 +1,13 @@
# /proc/config.gz
type config_gz, fs_type, proc_type;
# /sys/fs/bpf/<dir> for mainline tethering use
# TODO: move S+ fs_bpf_tethering here from public/file.te
type fs_bpf_net_private, fs_type, bpffs_type;
type fs_bpf_net_shared, fs_type, bpffs_type;
type fs_bpf_netd_readonly, fs_type, bpffs_type;
type fs_bpf_netd_shared, fs_type, bpffs_type;
# /data/misc/storaged
type storaged_data_file, file_type, data_file_type, core_data_file_type;

View file

@ -395,5 +395,9 @@ genfscon functionfs / u:object_r:functionfs:s0
genfscon usbfs / u:object_r:usbfs:s0
genfscon binfmt_misc / u:object_r:binfmt_miscfs:s0
genfscon bpf / u:object_r:fs_bpf:s0
genfscon bpf /net_private u:object_r:fs_bpf_net_private:s0
genfscon bpf /net_shared u:object_r:fs_bpf_net_shared:s0
genfscon bpf /netd_readonly u:object_r:fs_bpf_netd_readonly:s0
genfscon bpf /netd_shared u:object_r:fs_bpf_netd_shared:s0
genfscon bpf /tethering u:object_r:fs_bpf_tethering:s0
genfscon bpf /vendor u:object_r:fs_bpf_vendor:s0

View file

@ -6,6 +6,10 @@ init_daemon_domain(netd)
# Allow netd to spawn dnsmasq in it's own domain
domain_auto_trans(netd, dnsmasq_exec, dnsmasq)
allow netd { fs_bpf fs_bpf_netd_readonly fs_bpf_netd_shared }:dir search;
allow netd { fs_bpf fs_bpf_netd_readonly fs_bpf_netd_shared }:file read;
allow netd { fs_bpf fs_bpf_netd_shared }:file write;
# give netd permission to setup iptables rule with xt_bpf, attach program to cgroup, and read/write
# the map created by bpfloader
allow netd bpfloader:bpf { prog_run map_read map_write };

View file

@ -25,7 +25,9 @@ binder_call(netutils_wrapper, netd);
# For vendor code that update the iptables rules at runtime. They need to reload
# the whole chain including the xt_bpf rules. They need to access to the pinned
# program when reloading the rule.
allow netutils_wrapper fs_bpf:file { read write };
allow netutils_wrapper { fs_bpf fs_bpf_netd_shared }:dir search;
allow netutils_wrapper { fs_bpf fs_bpf_netd_shared }:file read;
allow netutils_wrapper { fs_bpf }:file write;
allow netutils_wrapper bpfloader:bpf prog_run;
# For /data/misc/net access to ndc and ip

View file

@ -60,8 +60,8 @@ hal_client_domain(network_stack, hal_tetheroffload)
allow network_stack self:netlink_netfilter_socket create_socket_perms_no_ioctl;
allow network_stack network_stack_service:service_manager find;
# allow Tethering(network_stack process) to run/update/read the eBPF maps to offload tethering traffic by eBPF.
allow network_stack { fs_bpf fs_bpf_tethering }:dir search;
allow network_stack { fs_bpf fs_bpf_tethering }:file { read write };
allow network_stack { fs_bpf_net_private fs_bpf_net_shared fs_bpf_netd_readonly fs_bpf_netd_shared fs_bpf_tethering }:dir search;
allow network_stack { fs_bpf_net_private fs_bpf_net_shared fs_bpf_netd_readonly fs_bpf_netd_shared fs_bpf_tethering }:file { read write };
allow network_stack bpfloader:bpf { map_read map_write prog_run };
# Use XFRM (IPsec) netlink sockets
@ -71,8 +71,46 @@ allow network_stack self:netlink_xfrm_socket { create_socket_perms_no_ioctl nlms
allow network_stack tun_device:chr_file rw_file_perms;
allowxperm network_stack tun_device:chr_file ioctl { TUNGETIFF TUNSETIFF TUNSETLINK TUNSETCARRIER };
# Only the bpfloader and the network_stack should ever touch 'fs_bpf_tethering' programs/maps.
############### NEVER ALLOW RULES
# This place is as good as any for these rules,
# and it is probably the most appropriate because
# network_stack itself is entirely mainline code.
#
# Unfortunately init/vendor_init have all sorts of extra privs
# T+: Only the bpfloader and the network_stack should ever touch 'fs_bpf_net_private' programs/maps.
neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_net_private:dir ~getattr;
neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_net_private:file *;
neverallow { domain -bpfloader -network_stack } fs_bpf_net_private:dir ~{ getattr open read search setattr };
neverallow { domain -bpfloader -network_stack } fs_bpf_net_private:file ~{ map open read setattr };
# T+: Only the bpfloader, network_stack and system_server should ever touch 'fs_bpf_net_shared' programs/maps.
neverallow { domain -bpfloader -init -network_stack -system_server -vendor_init } fs_bpf_net_shared:dir ~getattr;
neverallow { domain -bpfloader -init -network_stack -system_server -vendor_init } fs_bpf_net_shared:file *;
neverallow { domain -bpfloader -network_stack -system_server } fs_bpf_net_shared:dir ~{ getattr open read search setattr };
neverallow { domain -bpfloader -network_stack -system_server } fs_bpf_net_shared:file ~{ map open read setattr };
# T+: Only the bpfloader, netd, network_stack and system_server should ever touch 'fs_bpf_netd_readonly' programs/maps.
# netd's access should be readonly
neverallow { domain -bpfloader -init -netd -network_stack -system_server -vendor_init } fs_bpf_netd_readonly:dir ~getattr;
neverallow { domain -bpfloader -init -netd -network_stack -system_server -vendor_init } fs_bpf_netd_readonly:file *;
neverallow netd fs_bpf_netd_readonly:file write;
neverallow { domain -bpfloader -netd -network_stack -system_server } fs_bpf_netd_readonly:dir ~{ getattr open read search setattr };
neverallow { domain -bpfloader -netd -network_stack -system_server } fs_bpf_netd_readonly:file ~{ map open read setattr };
# T+: Only the bpfloader, netd, netutils_wrapper, network_stack and system_server should ever touch 'fs_bpf_netd_shared' programs/maps.
# netutils_wrapper requires access to be able to run iptables and only needs readonly access
neverallow { domain -bpfloader -init -netd -netutils_wrapper -network_stack -system_server -vendor_init } fs_bpf_netd_shared:dir ~getattr;
neverallow { domain -bpfloader -init -netd -netutils_wrapper -network_stack -system_server -vendor_init } fs_bpf_netd_shared:file *;
neverallow netutils_wrapper fs_bpf_netd_shared:file write;
neverallow { domain -bpfloader -netd -netutils_wrapper -network_stack -system_server } fs_bpf_netd_shared:dir ~{ getattr open read search setattr };
neverallow { domain -bpfloader -netd -netutils_wrapper -network_stack -system_server } fs_bpf_netd_shared:file ~{ map open read setattr };
# S+: Only the bpfloader and the network_stack should ever touch 'fs_bpf_tethering' programs/maps.
neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_tethering:dir ~getattr;
neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_tethering:file *;

View file

@ -1154,7 +1154,8 @@ with_asan(`
# allow system_server to read the eBPF maps that stores the traffic stats information and update
# the map after snapshot is recorded, and to read, update and run the maps and programs used for
# time in state accounting
allow system_server fs_bpf:file { read write };
allow system_server { fs_bpf fs_bpf_net_shared fs_bpf_netd_readonly fs_bpf_netd_shared }:dir search;
allow system_server { fs_bpf fs_bpf_net_shared fs_bpf_netd_readonly fs_bpf_netd_shared }:file { read write };
allow system_server bpfloader:bpf { map_read map_write prog_run };
# in order to invoke side effect of close() on such a socket calling synchronize_rcu()
allow system_server self:key_socket create;

View file

@ -10,6 +10,9 @@ attribute dev_type;
# TODO(b/202520796) Remove this attribute once the sc-dev branch stops using it.
attribute bdev_type;
# Attribute for all bpf filesystem subtypes.
attribute bpffs_type;
# All types used for processes.
attribute domain;

View file

@ -129,9 +129,10 @@ type sysfs_vendor_sched, sysfs_type, fs_type;
userdebug_or_eng(`
typeattribute sysfs_vendor_sched mlstrustedobject;
')
type fs_bpf, fs_type;
type fs_bpf_tethering, fs_type;
type fs_bpf_vendor, fs_type;
type fs_bpf, fs_type, bpffs_type;
# TODO: S+ fs_bpf_tethering (used by mainline) should be private
type fs_bpf_tethering, fs_type, bpffs_type;
type fs_bpf_vendor, fs_type, bpffs_type;
type configfs, fs_type;
# /sys/devices/cs_etm
type sysfs_devices_cs_etm, fs_type, sysfs_type;

View file

@ -64,8 +64,6 @@ allow netd sysfs_usb:file write;
r_dir_file(netd, cgroup_v2)
allow netd fs_bpf:file { read write };
# TODO: netd previously thought it needed these permissions to do WiFi related
# work. However, after all the WiFi stuff is gone, we still need them.
# Why?

View file

@ -44,6 +44,9 @@ def TestSystemTypeViolations(pol):
return pol.AssertPathTypesHaveAttr(partitions, exceptions, "system_file_type")
def TestBpffsTypeViolations(pol):
return pol.AssertGenfsFilesystemTypesHaveAttr("bpf", "bpffs_type")
def TestProcTypeViolations(pol):
return pol.AssertGenfsFilesystemTypesHaveAttr("proc", "proc_type")
@ -128,6 +131,7 @@ class MultipleOption(Option):
Option.take_action(self, action, dest, opt, value, values, parser)
Tests = [
"TestBpffsTypeViolations",
"TestDataTypeViolators",
"TestProcTypeViolations",
"TestSysfsTypeViolations",
@ -175,6 +179,8 @@ if __name__ == '__main__':
results = ""
# If an individual test is not specified, run all tests.
if options.test is None or "TestBpffsTypeViolations" in options.test:
results += TestBpffsTypeViolations(pol)
if options.test is None or "TestDataTypeViolations" in options.test:
results += TestDataTypeViolations(pol)
if options.test is None or "TestProcTypeViolations" in options.test: