Add sepolicy for fastbootd

Also allow adb and fastboot to talk to recovery
through recovery_socket. This enables changing
between modes with usb commands.

Test: No selinux denials
Bug: 78793464
Change-Id: I80c54d4eaf3b94a1fe26d2280af4e57cb1593790
diff --git a/private/adbd.te b/private/adbd.te
index 191c519..864358a 100644
--- a/private/adbd.te
+++ b/private/adbd.te
@@ -18,6 +18,9 @@
 recovery_only(`
   domain_trans(adbd, rootfs, shell)
   allow adbd shell:process dyntransition;
+
+  # Allows reboot fastboot to enter fastboot directly
+  unix_socket_connect(adbd, recovery, recovery)
 ')
 
 # Do not sanitize the environment or open fds of the shell. Allow signaling
diff --git a/private/compat/26.0/26.0.ignore.cil b/private/compat/26.0/26.0.ignore.cil
index 5a96107..d52b41b 100644
--- a/private/compat/26.0/26.0.ignore.cil
+++ b/private/compat/26.0/26.0.ignore.cil
@@ -49,6 +49,7 @@
     exported3_default_prop
     exported3_radio_prop
     exported3_system_prop
+    fastbootd
     fingerprint_vendor_data_file
     fs_bpf
     hal_audiocontrol_hwservice
@@ -96,6 +97,7 @@
     perfetto_traces_data_file
     perfprofd_service
     property_info
+    recovery_socket
     secure_element
     secure_element_device
     secure_element_tmpfs
diff --git a/private/compat/27.0/27.0.ignore.cil b/private/compat/27.0/27.0.ignore.cil
index 9120694..8e5370c 100644
--- a/private/compat/27.0/27.0.ignore.cil
+++ b/private/compat/27.0/27.0.ignore.cil
@@ -45,6 +45,7 @@
     exported_system_radio_prop
     exported_vold_prop
     exported_wifi_prop
+    fastbootd
     fingerprint_vendor_data_file
     fs_bpf
     hal_audiocontrol_hwservice
@@ -83,6 +84,7 @@
     perfetto_traces_data_file
     perfprofd_service
     property_info
+    recovery_socket
     secure_element
     secure_element_device
     secure_element_service
diff --git a/private/compat/28.0/28.0.ignore.cil b/private/compat/28.0/28.0.ignore.cil
index 18955b2..5386bee 100644
--- a/private/compat/28.0/28.0.ignore.cil
+++ b/private/compat/28.0/28.0.ignore.cil
@@ -5,6 +5,7 @@
 (typeattributeset new_objects
   ( activity_task_service
     adb_service
+    fastbootd
     hal_health_filesystem_hwservice
     hal_system_suspend_default
     hal_system_suspend_default_exec
@@ -14,6 +15,7 @@
     llkd_tmpfs
     mnt_product_file
     overlayfs_file
+    recovery_socket
     system_lmk_prop
     system_suspend_hwservice
     time_prop
diff --git a/private/fastbootd.te b/private/fastbootd.te
new file mode 100644
index 0000000..29a9157
--- /dev/null
+++ b/private/fastbootd.te
@@ -0,0 +1 @@
+typeattribute fastbootd coredomain;
diff --git a/private/file_contexts b/private/file_contexts
index 003d66c..0a77f6b 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -149,6 +149,7 @@
 /dev/socket/pdx/system/vr/display/vsync	u:object_r:pdx_display_vsync_endpoint_socket:s0
 /dev/socket/property_service	u:object_r:property_socket:s0
 /dev/socket/racoon	u:object_r:racoon_socket:s0
+/dev/socket/recovery    u:object_r:recovery_socket:s0
 /dev/socket/rild	u:object_r:rild_socket:s0
 /dev/socket/rild-debug	u:object_r:rild_debug_socket:s0
 /dev/socket/tombstoned_crash u:object_r:tombstoned_crash_socket:s0
diff --git a/private/init.te b/private/init.te
index 02686a3..30e5e36 100644
--- a/private/init.te
+++ b/private/init.te
@@ -9,6 +9,7 @@
 domain_auto_trans(init, e2fs_exec, e2fs)
 recovery_only(`
   domain_trans(init, rootfs, adbd)
+  domain_trans(init, rootfs, fastbootd)
   domain_trans(init, rootfs, recovery)
 ')
 domain_trans(init, shell_exec, shell)
diff --git a/public/domain.te b/public/domain.te
index db2beef..3afbe7e 100644
--- a/public/domain.te
+++ b/public/domain.te
@@ -557,6 +557,7 @@
   domain
   -adbd
   -dumpstate
+  -fastbootd
   -hal_drm_server
   -hal_cas_server
   -init
@@ -591,11 +592,21 @@
   -fsck
 } metadata_block_device:blk_file { append link rename write open read ioctl lock };
 
-# No domain other than recovery and update_engine can write to system partition(s).
-neverallow { domain -recovery -update_engine } system_block_device:blk_file { write append };
+# No domain other than recovery, update_engine and fastbootd can write to system partition(s).
+neverallow {
+  domain
+  -fastbootd
+  -recovery
+  -update_engine
+} system_block_device:blk_file { write append };
 
-# No domains other than install_recovery or recovery can write to recovery.
-neverallow { domain -install_recovery -recovery } recovery_block_device:blk_file { write append };
+# No domains other than install_recovery, recovery or fastbootd can write to recovery.
+neverallow {
+  domain
+  -fastbootd
+  -install_recovery
+  -recovery
+} recovery_block_device:blk_file { write append };
 
 # No domains other than a select few can access the misc_block_device. This
 # block device is reserved for OTA use.
@@ -604,6 +615,7 @@
 neverallow {
   domain
   userdebug_or_eng(`-domain') # exclude debuggable builds
+  -fastbootd
   -hal_bootctl_server
   -init
   -uncrypt
diff --git a/public/fastbootd.te b/public/fastbootd.te
new file mode 100644
index 0000000..82ae47b
--- /dev/null
+++ b/public/fastbootd.te
@@ -0,0 +1,59 @@
+# fastbootd (used in recovery init.rc for /sbin/fastbootd)
+
+# Declare the domain unconditionally so we can always reference it
+# in neverallow rules.
+type fastbootd, domain;
+
+# But the allow rules are only included in the recovery policy.
+# Otherwise fastbootd is only allowed the domain rules.
+recovery_only(`
+  # fastbootd can only use HALs in passthrough mode
+  passthrough_hal_client_domain(fastbootd, hal_bootctl)
+
+  # Access /dev/usb-ffs/fastbootd/ep0
+  allow fastbootd functionfs:dir search;
+  allow fastbootd functionfs:file rw_file_perms;
+
+  # Log to serial
+  allow fastbootd kmsg_device:chr_file { open write };
+
+  # battery info
+  allow fastbootd sysfs_batteryinfo:file r_file_perms;
+
+  allow fastbootd device:dir r_dir_perms;
+
+  # Reboot the device
+  set_prop(fastbootd, powerctl_prop)
+
+  # Read serial number of the device from system properties
+  get_prop(fastbootd, serialno_prop)
+
+  # Set sys.usb.ffs.ready.
+  set_prop(fastbootd, ffs_prop)
+  set_prop(fastbootd, exported_ffs_prop)
+
+  unix_socket_connect(fastbootd, recovery, recovery)
+
+  # Required for flashing
+  allow fastbootd dm_device:chr_file rw_file_perms;
+  allow fastbootd dm_device:blk_file rw_file_perms;
+
+  allow fastbootd system_block_device:blk_file rw_file_perms;
+  allow fastbootd boot_block_device:blk_file rw_file_perms;
+
+  allow fastbootd misc_block_device:blk_file rw_file_perms;
+
+  allow fastbootd proc_cmdline:file r_file_perms;
+  allow fastbootd rootfs:dir r_dir_perms;
+  allow fastbootd sysfs_dt_firmware_android:file r_file_perms;
+')
+
+###
+### neverallow rules
+###
+
+# Write permission is required to wipe userdata
+# until recovery supports vold.
+neverallow fastbootd {
+   data_file_type
+}:file { no_x_file_perms };
diff --git a/public/file.te b/public/file.te
index 75d1edc..4b0dc2d 100644
--- a/public/file.te
+++ b/public/file.te
@@ -342,6 +342,7 @@
 type netd_socket, file_type, coredomain_socket;
 type property_socket, file_type, coredomain_socket, mlstrustedobject;
 type racoon_socket, file_type, coredomain_socket;
+type recovery_socket, file_type, coredomain_socket;
 type rild_socket, file_type;
 type rild_debug_socket, file_type;
 type system_wpa_socket, file_type, data_file_type, core_data_file_type, coredomain_socket;
diff --git a/public/recovery.te b/public/recovery.te
index dcec970..317cf32 100644
--- a/public/recovery.te
+++ b/public/recovery.te
@@ -118,6 +118,10 @@
   set_prop(recovery, ffs_prop)
   set_prop(recovery, exported_ffs_prop)
 
+  # Set sys.usb.config when switching into fastboot.
+  set_prop(recovery, system_radio_prop)
+  set_prop(recovery, exported_system_radio_prop)
+
   # Read ro.boot.bootreason
   get_prop(recovery, bootloader_boot_reason_prop)