From 3ea47b9249d4f9a4a90cae7867a119cbfdb7d4b6 Mon Sep 17 00:00:00 2001
From: Martijn Coenen <maco@google.com>
Date: Fri, 7 Apr 2017 16:14:43 -0700
Subject: [PATCH] Add hwservice_contexts and support for querying it.

hwservicemanager can check hwservice_contexts files
both from the framework and vendor partitions.

Initially, have a wildcard '*' in hwservice_contexts
that maps to a label that can be added/found from
domain. This needs to be removed when the proper policy
is in place.

Also, grant su/shell access to hwservicemanager list
operations, so tools like 'lshal' continue to work.

Bug: 34454312
Test: Marlin boots
Change-Id: I3a02d97a82458692b528d85c1b8e78b6f82ea1bc
---
 Android.mk                 | 64 ++++++++++++++++++++++++++++++++++++++
 private/file_contexts      |  4 +++
 private/hwservice_contexts |  1 +
 public/domain.te           |  3 ++
 public/file.te             |  3 ++
 public/hwservice.te        |  1 +
 public/hwservicemanager.te |  8 +++--
 public/shell.te            |  1 +
 public/su.te               |  2 ++
 9 files changed, 84 insertions(+), 3 deletions(-)
 create mode 100644 private/hwservice_contexts
 create mode 100644 public/hwservice.te

diff --git a/Android.mk b/Android.mk
index 776be6c0a..d7b977cda 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1078,6 +1078,70 @@ nonplat_service_contexts.tmp :=
 ##################################
 include $(CLEAR_VARS)
 
+LOCAL_MODULE := plat_hwservice_contexts
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+ifeq ($(PRODUCT_FULL_TREBLE),true)
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/selinux
+else
+LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
+endif
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+plat_hwsvcfiles := $(call build_policy, hwservice_contexts, $(PLAT_PRIVATE_POLICY))
+
+plat_hwservice_contexts.tmp := $(intermediates)/plat_hwservice_contexts.tmp
+$(plat_hwservice_contexts.tmp): PRIVATE_SVC_FILES := $(plat_hwsvcfiles)
+$(plat_hwservice_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(plat_hwservice_contexts.tmp): $(plat_hwsvcfiles)
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_SVC_FILES) > $@
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
+$(LOCAL_BUILT_MODULE): $(plat_hwservice_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
+	@mkdir -p $(dir $@)
+	sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
+	$(HOST_OUT_EXECUTABLES)/checkfc -e -l $(PRIVATE_SEPOLICY) $@
+
+plat_hwsvcfiles :=
+plat_hwservice_contexts.tmp :=
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := nonplat_hwservice_contexts
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+ifeq ($(PRODUCT_FULL_TREBLE),true)
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/selinux
+else
+LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
+endif
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+nonplat_hwsvcfiles := $(call build_policy, hwservice_contexts, $(PLAT_VENDOR_POLICY) $(BOARD_SEPOLICY_DIRS) $(REQD_MASK_POLICY))
+
+nonplat_hwservice_contexts.tmp := $(intermediates)/nonplat_hwservice_contexts.tmp
+$(nonplat_hwservice_contexts.tmp): PRIVATE_SVC_FILES := $(nonplat_hwsvcfiles)
+$(nonplat_hwservice_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(nonplat_hwservice_contexts.tmp): $(nonplat_hwsvcfiles)
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_SVC_FILES) > $@
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
+$(LOCAL_BUILT_MODULE): $(nonplat_hwservice_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
+	@mkdir -p $(dir $@)
+	sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -e -l $(PRIVATE_SEPOLICY) $@
+
+nonplat_hwsvcfiles :=
+nonplat_hwservice_contexts.tmp :=
+
+##################################
+include $(CLEAR_VARS)
+
 LOCAL_MODULE := vndservice_contexts
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_TAGS := optional
diff --git a/private/file_contexts b/private/file_contexts
index d547a9f52..7e5582f23 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -51,7 +51,9 @@
 /plat_seapp_contexts     u:object_r:seapp_contexts_file:s0
 /sepolicy           u:object_r:sepolicy_file:s0
 /plat_service_contexts   u:object_r:service_contexts_file:s0
+/plat_hwservice_contexts   u:object_r:hwservice_contexts_file:s0
 /nonplat_service_contexts   u:object_r:service_contexts_file:s0
+/nonplat_hwservice_contexts   u:object_r:hwservice_contexts_file:s0
 /vndservice_contexts   u:object_r:vndservice_contexts_file:s0
 
 ##########################
@@ -252,6 +254,7 @@
 /system/etc/selinux/plat_mac_permissions.xml u:object_r:mac_perms_file:s0
 /system/etc/selinux/plat_property_contexts  u:object_r:property_contexts_file:s0
 /system/etc/selinux/plat_service_contexts  u:object_r:service_contexts_file:s0
+/system/etc/selinux/plat_hwservice_contexts  u:object_r:hwservice_contexts_file:s0
 /system/etc/selinux/plat_file_contexts  u:object_r:file_contexts_file:s0
 /system/etc/selinux/plat_seapp_contexts  u:object_r:seapp_contexts_file:s0
 /system/etc/selinux/plat_sepolicy.cil       u:object_r:sepolicy_file:s0
@@ -280,6 +283,7 @@
 /vendor/etc/selinux/nonplat_mac_permissions.xml u:object_r:mac_perms_file:s0
 /vendor/etc/selinux/nonplat_property_contexts   u:object_r:property_contexts_file:s0
 /vendor/etc/selinux/nonplat_service_contexts    u:object_r:service_contexts_file:s0
+/vendor/etc/selinux/nonplat_hwservice_contexts    u:object_r:hwservice_contexts_file:s0
 /vendor/etc/selinux/nonplat_file_contexts   u:object_r:file_contexts_file:s0
 /vendor/etc/selinux/nonplat_seapp_contexts    u:object_r:seapp_contexts_file:s0
 /vendor/etc/selinux/nonplat_sepolicy.cil       u:object_r:sepolicy_file:s0
diff --git a/private/hwservice_contexts b/private/hwservice_contexts
new file mode 100644
index 000000000..4351ea1d8
--- /dev/null
+++ b/private/hwservice_contexts
@@ -0,0 +1 @@
+*                                    u:object_r:default_android_hwservice:s0
diff --git a/public/domain.te b/public/domain.te
index 66029f812..da8b253f5 100644
--- a/public/domain.te
+++ b/public/domain.te
@@ -212,6 +212,9 @@ allowxperm domain domain:{ unix_dgram_socket unix_stream_socket }
 # separately.
 allowxperm domain devpts:chr_file ioctl unpriv_tty_ioctls;
 
+# TODO(b/34454312) remove this when the correct policy is in place
+allow domain default_android_hwservice:hwservice_manager { add find };
+
 ###
 ### neverallow rules
 ###
diff --git a/public/file.te b/public/file.te
index 813340195..35bbd6db7 100644
--- a/public/file.te
+++ b/public/file.te
@@ -296,6 +296,9 @@ type sepolicy_file, file_type;
 # service_contexts file
 type service_contexts_file, file_type;
 
+# hwservice_contexts file
+type hwservice_contexts_file, file_type;
+
 # vndservice_contexts file
 type vndservice_contexts_file, file_type;
 
diff --git a/public/hwservice.te b/public/hwservice.te
new file mode 100644
index 000000000..a39ffd2a3
--- /dev/null
+++ b/public/hwservice.te
@@ -0,0 +1 @@
+type default_android_hwservice,   hwservice_manager_type;
diff --git a/public/hwservicemanager.te b/public/hwservicemanager.te
index 20a722931..1ffd2a67e 100644
--- a/public/hwservicemanager.te
+++ b/public/hwservicemanager.te
@@ -15,6 +15,8 @@ set_prop(hwservicemanager, hwservicemanager_prop)
 # Scan through /system/lib64/hw looking for installed HALs
 allow hwservicemanager system_file:dir r_dir_perms;
 
-# TODO once hwservicemanager checks whether HALs are
-# allowed to register a certain service, add policy here
-# for allowing to check SELinux permissions.
+# Read hwservice_contexts
+allow hwservicemanager hwservice_contexts_file:file r_file_perms;
+
+# Check SELinux permissions.
+selinux_check_access(hwservicemanager)
diff --git a/public/shell.te b/public/shell.te
index cb1a0867c..fd0f2efa2 100644
--- a/public/shell.te
+++ b/public/shell.te
@@ -86,6 +86,7 @@ allow shell dumpstate:binder call;
 # allow shell to get information from hwservicemanager
 # for instance, listing hardware services with lshal
 hwbinder_use(shell)
+allow shell hwservicemanager:hwservice_manager list;
 
 # allow shell to look through /proc/ for ps, top, netstat
 r_dir_file(shell, proc)
diff --git a/public/su.te b/public/su.te
index f410c4d81..77fd07111 100644
--- a/public/su.te
+++ b/public/su.te
@@ -40,6 +40,8 @@ userdebug_or_eng(`
   dontaudit su hwservice_manager_type:hwservice_manager *;
   dontaudit su vndservice_manager_type:vndservice_manager *;
   dontaudit su servicemanager:service_manager list;
+  dontaudit su hwservicemanager:hwservice_manager list;
+  dontaudit su vndservicemanager:vndservice_manager list;
   dontaudit su keystore:keystore_key *;
   dontaudit su domain:drmservice *;
   dontaudit su unlabeled:filesystem *;
-- 
GitLab