diff --git a/device.te b/device.te
index e3ddb95f2d6704897d6cc820d1b17bfbe5d3e9a7..22514d51ffbbc3789273ca069d77b752fcdb6ea5 100644
--- a/device.te
+++ b/device.te
@@ -5,6 +5,7 @@ type adb_device, dev_type;
 type ashmem_device, dev_type, mlstrustedobject;
 type audio_device, dev_type;
 type binder_device, dev_type, mlstrustedobject;
+type hwbinder_device, dev_type, mlstrustedobject;
 type block_device, dev_type;
 type camera_device, dev_type;
 type dm_device, dev_type;
diff --git a/domain.te b/domain.te
index d786106ee2accef8dc4ed3f992f2f59b532af4b8..6f8a232074b13387e4cf50123e8f008fa04554a4 100644
--- a/domain.te
+++ b/domain.te
@@ -72,7 +72,8 @@ allow domain owntty_device:chr_file rw_file_perms;
 allow domain null_device:chr_file rw_file_perms;
 allow domain zero_device:chr_file rw_file_perms;
 allow domain ashmem_device:chr_file rw_file_perms;
-allow domain binder_device:chr_file rw_file_perms;
+allow { domain -hwservicemanager } binder_device:chr_file rw_file_perms;
+allow { domain -servicemanager } hwbinder_device:chr_file rw_file_perms;
 allow domain ptmx_device:chr_file rw_file_perms;
 allow domain alarm_device:chr_file r_file_perms;
 allow domain urandom_device:chr_file rw_file_perms;
@@ -386,8 +387,11 @@ neverallow {
   -ueventd
 } misc_block_device:blk_file { append link relabelfrom rename write open read ioctl lock };
 
-# Only servicemanager should be able to register with binder as the context manager
-neverallow { domain -servicemanager } *:binder set_context_mgr;
+# Only servicemanager/hwservicemanager should be able to register with binder as the context manager
+neverallow { domain -servicemanager -hwservicemanager} *:binder set_context_mgr;
+# The service managers are only allowed to access their own device node
+neverallow servicemanager hwbinder_device:chr_file no_rw_file_perms;
+neverallow hwservicemanager binder_device:chr_file no_rw_file_perms;
 
 # Only authorized processes should be writing to files in /data/dalvik-cache
 neverallow {
diff --git a/file_contexts b/file_contexts
index d8b178f8522f7941499a16ee814c6d762749b4d2..b2499f9f8b1cd25237bc92889a7f55b04e7eae7e 100644
--- a/file_contexts
+++ b/file_contexts
@@ -71,6 +71,7 @@
 /dev/fuse		u:object_r:fuse_device:s0
 /dev/graphics(/.*)?	u:object_r:graphics_device:s0
 /dev/hw_random		u:object_r:hw_random_device:s0
+/dev/hwbinder		u:object_r:hwbinder_device:s0
 /dev/i2c-[0-9]+		u:object_r:i2c_device:s0
 /dev/input(/.*)		u:object_r:input_device:s0
 /dev/iio:device[0-9]+   u:object_r:iio_device:s0
@@ -157,6 +158,7 @@
 /system/bin/app_process32	u:object_r:zygote_exec:s0
 /system/bin/app_process64	u:object_r:zygote_exec:s0
 /system/bin/servicemanager	u:object_r:servicemanager_exec:s0
+/system/bin/hwservicemanager	u:object_r:hwservicemanager_exec:s0
 /system/bin/surfaceflinger	u:object_r:surfaceflinger_exec:s0
 /system/bin/drmserver	u:object_r:drmserver_exec:s0
 /system/bin/dumpstate   u:object_r:dumpstate_exec:s0
diff --git a/hwservicemanager.te b/hwservicemanager.te
new file mode 100644
index 0000000000000000000000000000000000000000..c3477556bb9b38085eb851ddeac046588fc3b240
--- /dev/null
+++ b/hwservicemanager.te
@@ -0,0 +1,18 @@
+# hwservicemanager - the Binder context manager for HAL services
+type hwservicemanager, domain, mlstrustedsubject;
+type hwservicemanager_exec, exec_type, file_type;
+
+init_daemon_domain(hwservicemanager)
+
+# Note that we do not use the binder_* macros here.
+# hwservicemanager only provides name service (aka context manager)
+# for Binder.
+# As such, it only ever receives and transfers other references
+# created by other domains.  It never passes its own references
+# or initiates a Binder IPC.
+allow hwservicemanager self:binder set_context_mgr;
+allow hwservicemanager { domain -init }:binder transfer;
+
+# TODO once hwservicemanager checks whether HALs are
+# allowed to register a certain service, add policy here
+# for allowing to check SELinux permissions.