apply 'fs_bpf_tethering' label to /sys/fs/bpf/tethering

We want to label /sys/fs/bpf/tethering/... with a new label distinct
from /sys/fs/bpf, as this will allow locking down the programs/maps
tighter then is currently possible with the existing system.

These programs and maps are provided via the tethering mainline module,
and as such their number, names, key/value types, etc. are all prone to
be changed by a tethering mainline module update.

Test: atest, TreeHugger
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Ifc4108d76a1106a936b941a3dda1abc5a65c05b0
diff --git a/private/bpfloader.te b/private/bpfloader.te
index b2e5992..f1932bb 100644
--- a/private/bpfloader.te
+++ b/private/bpfloader.te
@@ -4,27 +4,32 @@
 typeattribute bpfloader coredomain;
 
 # These permissions are required to pin ebpf maps & programs.
-allow bpfloader fs_bpf:dir { create search write add_name };
-allow bpfloader fs_bpf:file { create setattr read };
+allow bpfloader { fs_bpf fs_bpf_tethering }:dir { add_name create search write };
+allow bpfloader { fs_bpf fs_bpf_tethering }:file { create read setattr };
+allow fs_bpf_tethering 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 };
 
 allow bpfloader self:capability { chown sys_admin };
 
+set_prop(bpfloader, bpf_progs_loaded_prop)
+
 ###
 ### Neverallow rules
 ###
 
-# TODO: get rid of init & vendor_init
-neverallow { domain -init -vendor_init } fs_bpf:dir setattr;
-neverallow { domain -bpfloader } fs_bpf:dir { create write add_name };
-neverallow domain fs_bpf:dir { reparent rename rmdir };
+# 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 }:dir { open read setattr };
+neverallow { domain -bpfloader } { fs_bpf fs_bpf_tethering }:dir { add_name create write };
+neverallow domain { fs_bpf fs_bpf_tethering }:dir ~{ add_name create getattr mounton open read search setattr write };
 
 # TODO: get rid of init & vendor_init
-neverallow { domain -bpfloader -init -vendor_init } fs_bpf:file setattr;
-neverallow { domain -bpfloader } fs_bpf:file create;
-neverallow domain fs_bpf:file { rename unlink };
+neverallow { domain -bpfloader -init -vendor_init } { fs_bpf fs_bpf_tethering }:file { map open setattr };
+neverallow { domain -bpfloader } { fs_bpf fs_bpf_tethering }:file create;
+neverallow { domain -bpfloader -gpuservice -init -netd -netutils_wrapper -network_stack -system_server -vendor_init } { fs_bpf 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 } *:bpf { map_create prog_load };
 neverallow { domain -bpfloader -gpuservice -netd -netutils_wrapper -network_stack -system_server } *:bpf prog_run;
@@ -32,9 +37,7 @@
 
 neverallow { domain -bpfloader -init } bpfloader_exec:file { execute execute_no_trans };
 
-neverallow bpfloader domain:{ tcp_socket udp_socket rawip_socket } *;
+neverallow bpfloader *:{ tcp_socket udp_socket rawip_socket } *;
 
 # No domain should be allowed to ptrace bpfloader
 neverallow { domain userdebug_or_eng(`-llkd') } bpfloader:process ptrace;
-
-set_prop(bpfloader, bpf_progs_loaded_prop)
diff --git a/private/compat/30.0/30.0.ignore.cil b/private/compat/30.0/30.0.ignore.cil
index 3eace95..2fe9eff 100644
--- a/private/compat/30.0/30.0.ignore.cil
+++ b/private/compat/30.0/30.0.ignore.cil
@@ -30,6 +30,7 @@
     domain_verification_service
     dumpstate_tmpfs
     framework_watchdog_config_prop
+    fs_bpf_tethering
     fwk_stats_service
     game_service
     font_data_file
diff --git a/private/genfs_contexts b/private/genfs_contexts
index 05dc06f..d205cd5 100644
--- a/private/genfs_contexts
+++ b/private/genfs_contexts
@@ -349,3 +349,4 @@
 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 /tethering u:object_r:fs_bpf_tethering:s0
diff --git a/private/network_stack.te b/private/network_stack.te
index f130e80..9598fa5 100644
--- a/private/network_stack.te
+++ b/private/network_stack.te
@@ -29,6 +29,13 @@
 
 binder_call(network_stack, netd);
 
+# in order to invoke side effect of close() on such a socket calling synchronize_rcu()
+# TODO: Remove this permission when 4.9 kernel is deprecated.
+allow network_stack self:key_socket create;
+
+# Grant read permission of connectivity namespace system property prefix.
+get_prop(network_stack, device_config_connectivity_prop)
+
 # Create/use netlink_tcpdiag_socket to get tcp info
 allow network_stack self:netlink_tcpdiag_socket { create_socket_perms_no_ioctl nlmsg_read nlmsg_write };
 ############### Tethering Service app - Tethering.apk ##############
@@ -37,13 +44,15 @@
 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:dir search;
-allow network_stack fs_bpf:file { read write };
+allow network_stack { fs_bpf fs_bpf_tethering }:dir search;
+allow network_stack { fs_bpf fs_bpf_tethering }:file { read write };
 allow network_stack bpfloader:bpf { map_read map_write prog_run };
 
-# in order to invoke side effect of close() on such a socket calling synchronize_rcu()
-# TODO: Remove this permission when 4.9 kernel is deprecated.
-allow network_stack self:key_socket create;
+# Only the bpfloader and the network_stack should ever touch 'fs_bpf_tethering' programs/maps.
+# TODO: remove netd once netd/tethering mainline module split is complete
+# Unfortunately init/vendor_init have all sorts of extra privs
+neverallow { domain -bpfloader -init -netd -network_stack -vendor_init } fs_bpf_tethering:dir ~getattr;
+neverallow { domain -bpfloader -init -netd -network_stack -vendor_init } fs_bpf_tethering:file *;
 
-# Grant read permission of connectivity namespace system property prefix.
-get_prop(network_stack, device_config_connectivity_prop)
+neverallow { domain -bpfloader -netd -network_stack } fs_bpf_tethering:dir ~{ getattr open read search setattr };
+neverallow { domain -bpfloader -netd -network_stack } fs_bpf_tethering:file ~{ map open read setattr };
diff --git a/public/file.te b/public/file.te
index 181979c..a188c78 100644
--- a/public/file.te
+++ b/public/file.te
@@ -113,6 +113,7 @@
 type sysfs_fs_f2fs, sysfs_type, fs_type;
 type sysfs_fs_incfs_features, sysfs_type, fs_type;
 type fs_bpf, fs_type;
+type fs_bpf_tethering, fs_type;
 type configfs, fs_type;
 # /sys/devices/cs_etm
 type sysfs_devices_cs_etm, fs_type, sysfs_type;
diff --git a/public/netd.te b/public/netd.te
index ff0bff6..4472938 100644
--- a/public/netd.te
+++ b/public/netd.te
@@ -64,8 +64,9 @@
 
 r_dir_file(netd, cgroup_v2)
 
-allow netd fs_bpf:dir search;
-allow netd fs_bpf:file { read write };
+# TODO: remove 'fs_bpf_tethering' once netd/tethering mainline module split is completed.
+allow netd { fs_bpf fs_bpf_tethering }:dir search;
+allow netd { fs_bpf fs_bpf_tethering }: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.