diff --git a/Android.mk b/Android.mk
index 7c75f9d62258edaf09887bd06640424a44829417..cdf1270eafe72259b18f7235edeaa82a6e258785 100644
--- a/Android.mk
+++ b/Android.mk
@@ -979,6 +979,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 aa89601bac694c80f7e26baa36dab1f9cecae7b9..c31ec06e369bafd3754d8a60bdb0b9637f94b0c6 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 0000000000000000000000000000000000000000..4351ea1d866464cb9be5e9a761748a6ef6f6f126
--- /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 2a27ad96545fe04d334e27c5b15910db3d42c113..766ed2994285f48ed47beb5643fe451bac07c5d7 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 813340195bd05923d782cd27cb92ef97e92c37a1..35bbd6db7d01ca8d949f0cfcbab0240608a8b075 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 0000000000000000000000000000000000000000..a39ffd2a357178a57a52eaed1fe4969dc93f14de
--- /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 20a722931b0f1c1905d1c69228e78f1ee0a97683..1ffd2a67ec4074501fada827daf29d3b92a80031 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 cb1a0867cd1ab4fb0c9369eda52a4b3b744bf7d0..fd0f2efa2f261fa2bd0682e0d3c42a08c1a5f915 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 f410c4d81ff75def4c1dada77fdf4b892a9afc60..77fd07111359a625ff5b24d93a7d91b65b0bfd50 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 *;