Recovery can use HALs only in passthrough mode

This adjusts the grants for recovery to make it explicit that recovery
can use the Boot Control HAL only in passthrough mode.

Test: Device boots up, no new denials
Test: Reboot into recovery, sideload OTA update succeeds
Test: Apply OTA update via update_engine:
      1. make dist
      2. Ensure device has network connectivity
      3. ota_call.py -s <serial here> out/dist/sailfish-ota-*.zip
Bug: 34170079

Change-Id: I0888816eca4d77939a55a7816e6cae9176713ee5
diff --git a/public/recovery.te b/public/recovery.te
index a61c8e9..1ec19c5 100644
--- a/public/recovery.te
+++ b/public/recovery.te
@@ -9,7 +9,8 @@
 recovery_only(`
   # Allow recovery to perform an update as update_engine would do.
   typeattribute recovery update_engine_common;
-  hal_client_domain(recovery, hal_bootctl)
+  # Recovery can only use HALs in passthrough mode
+  passthrough_hal_client_domain(recovery, hal_bootctl)
 
   allow recovery self:capability { chown dac_override fowner fsetid setfcap setuid setgid sys_admin sys_tty_config };
 
diff --git a/public/te_macros b/public/te_macros
index bc5da60..97dd948 100644
--- a/public/te_macros
+++ b/public/te_macros
@@ -204,6 +204,22 @@
 ')
 
 #####################################
+# passthrough_hal_client_domain(domain, hal_type)
+# Allow a base set of permissions required for a domain to be a
+# client of a passthrough HAL of the specified type.
+#
+# For example, make some_domain a client of passthrough Foo HAL:
+#   passthrough_hal_client_domain(some_domain, hal_foo)
+#
+define(`passthrough_hal_client_domain', `
+typeattribute $1 halclientdomain;
+typeattribute $1 $2_client;
+typeattribute $1 $2;
+# Find passthrough HAL implementations
+allow $2 system_file:dir r_dir_perms;
+')
+
+#####################################
 # unix_socket_connect(clientdomain, socket, serverdomain)
 # Allow a local socket connection from clientdomain via
 # socket to serverdomain.