From df5469d86494b35eb208b50253ce5260c1a8a2b2 Mon Sep 17 00:00:00 2001
From: Dan Cashman <dcashman@google.com>
Date: Tue, 26 Sep 2017 12:58:29 -0700
Subject: [PATCH] Sync internal master and AOSP sepolicy.

Bug: 37916906
Test: Builds 'n' boots.
Change-Id: Ia1d86264446ebecc1ca79f32f11354921bc77668
Merged-In: I208ec6a864127a059fb389417a9c6b259d7474cb
---
 Android.mk                          |  42 ++++-
 private/app_neverallows.te          |  16 +-
 private/compat/26.0/26.0.cil        |   2 +-
 private/compat/26.0/26.0.ignore.cil |  12 +-
 private/file.te                     |   3 +
 private/file_contexts               |   2 +-
 private/genfs_contexts              |   9 +
 private/hwservice_contexts          |   1 +
 private/property_contexts           |   4 +
 private/service_contexts            |   2 +
 private/storaged.te                 |   4 +
 private/system_app.te               |  10 +-
 private/system_server.te            |   8 +-
 public/attributes                   | 267 ++++------------------------
 public/device.te                    |   1 +
 public/dumpstate.te                 |  13 +-
 public/e2fs.te                      |   7 +-
 public/file.te                      |   9 +
 public/fsck.te                      |   5 +-
 public/fsck_untrusted.te            |   2 +-
 public/hal_audio.te                 |   1 +
 public/hal_lowpan.te                |  21 +++
 public/hwservice.te                 |   1 +
 public/init.te                      |   6 +
 public/kernel.te                    |   1 +
 public/property.te                  |   1 +
 public/sdcardd.te                   |   2 +-
 public/service.te                   |   2 +
 public/shell.te                     |  11 +-
 public/su.te                        |  43 +++++
 public/te_macros                    |  16 ++
 public/vdc.te                       |   9 +
 public/vold.te                      |  30 +++-
 tests/Android.bp                    |  10 ++
 tests/include/sepol_wrap.h          |   3 +
 tests/policy.py                     | 116 +++++++++---
 tests/searchpolicy.py               |  73 ++++++++
 tests/sepol_wrap.cpp                |  67 +++++--
 tests/treble_sepolicy_tests.py      |  47 ++++-
 vendor/file_contexts                |   1 +
 vendor/hal_lowpan_default.te        |   5 +
 41 files changed, 601 insertions(+), 284 deletions(-)
 create mode 100644 public/hal_lowpan.te
 create mode 100644 tests/searchpolicy.py
 create mode 100644 vendor/hal_lowpan_default.te

diff --git a/Android.mk b/Android.mk
index 965c7a7c2..43419cd01 100644
--- a/Android.mk
+++ b/Android.mk
@@ -194,12 +194,13 @@ LOCAL_REQUIRED_MODULES += \
     plat_sepolicy.cil \
     plat_and_mapping_sepolicy.cil.sha256 \
     secilc \
-    plat_sepolicy_vers.txt
+    plat_sepolicy_vers.txt \
 
 ifneq ($(with_asan),true)
 LOCAL_REQUIRED_MODULES += \
     treble_sepolicy_tests \
     sepolicy_tests
+
 endif
 
 # Include precompiled policy, unless told otherwise
@@ -223,12 +224,25 @@ LOCAL_REQUIRED_MODULES += \
     plat_seapp_contexts \
     plat_service_contexts \
     plat_hwservice_contexts \
+    searchpolicy \
     vndservice_contexts \
 
 ifneq ($(PRODUCT_FULL_TREBLE),true)
 LOCAL_REQUIRED_MODULES += nonplat_service_contexts
 endif
 
+ifneq ($(TARGET_BUILD_VARIANT), user)
+LOCAL_REQUIRED_MODULES += \
+    selinux_denial_metadata \
+
+endif
+
+ifneq ($(with_asan),true)
+LOCAL_REQUIRED_MODULES += \
+    sepolicy_tests \
+
+endif
+
 include $(BUILD_PHONY_PACKAGE)
 
 ##################################
@@ -665,6 +679,24 @@ file_contexts.device.sorted.tmp :=
 file_contexts.device.tmp :=
 file_contexts.local.tmp :=
 
+##################################
+ifneq ($(TARGET_BUILD_VARIANT), user)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := selinux_denial_metadata
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/selinux
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+bug_files := $(call build_policy, bug_map, $(LOCAL_PATH) $(PLAT_PRIVATE_POLICY) $(PLAT_VENDOR_POLICY) $(BOARD_SEPOLICY_DIRS) $(PLAT_PUBLIC_POLICY))
+
+$(LOCAL_BUILT_MODULE) : $(bug_files)
+	@mkdir -p $(dir $@)
+	cat $^ > $@
+
+bug_files :=
+endif
 ##################################
 include $(CLEAR_VARS)
 
@@ -1262,6 +1294,11 @@ $(treble_sepolicy_tests): PRIVATE_SEPOLICY := $(built_sepolicy)
 $(treble_sepolicy_tests): PRIVATE_SEPOLICY_OLD := $(built_26.0_plat_sepolicy)
 $(treble_sepolicy_tests): PRIVATE_COMBINED_MAPPING := $(26.0_mapping.combined.cil)
 $(treble_sepolicy_tests): PRIVATE_PLAT_SEPOLICY := $(built_plat_sepolicy)
+ifeq ($(PRODUCT_FULL_TREBLE_OVERRIDE),true)
+$(treble_sepolicy_tests): PRIVATE_FAKE_TREBLE := --fake-treble
+else
+$(treble_sepolicy_tests): PRIVATE_FAKE_TREBLE :=
+endif
 $(treble_sepolicy_tests): $(HOST_OUT_EXECUTABLES)/treble_sepolicy_tests \
 $(built_plat_fc) $(built_nonplat_fc) $(built_sepolicy) $(built_plat_sepolicy) \
 $(built_26.0_plat_sepolicy) $(26.0_compat) $(26.0_mapping.combined.cil)
@@ -1269,7 +1306,8 @@ $(built_26.0_plat_sepolicy) $(26.0_compat) $(26.0_mapping.combined.cil)
 	$(hide) python $(HOST_OUT_EXECUTABLES)/treble_sepolicy_tests -l \
 		$(HOST_OUT)/lib64 -f $(PRIVATE_PLAT_FC) -f $(PRIVATE_NONPLAT_FC) \
 		-b $(PRIVATE_PLAT_SEPOLICY) -m $(PRIVATE_COMBINED_MAPPING) \
-		-o $(PRIVATE_SEPOLICY_OLD) -p $(PRIVATE_SEPOLICY)
+		-o $(PRIVATE_SEPOLICY_OLD) -p $(PRIVATE_SEPOLICY) \
+		$(PRIVATE_FAKE_TREBLE)
 	$(hide) touch $@
 
 26.0_PLAT_PUBLIC_POLICY :=
diff --git a/private/app_neverallows.te b/private/app_neverallows.te
index a3d7d498c..db14f1b58 100644
--- a/private/app_neverallows.te
+++ b/private/app_neverallows.te
@@ -108,11 +108,25 @@ neverallow all_untrusted_apps anr_data_file:dir ~search;
 
 # Avoid reads from generically labeled /proc files
 # Create a more specific label if needed
-neverallow all_untrusted_apps proc:file { no_rw_file_perms no_x_file_perms };
+neverallow all_untrusted_apps {
+  proc
+  proc_asound_cards
+  proc_filesystems
+  proc_kmsg
+  proc_loadavg
+  proc_mounts
+  proc_pagetypeinfo
+  proc_swaps
+  proc_version
+  proc_vmallocinfo
+}:file { no_rw_file_perms no_x_file_perms };
 
 # Avoid all access to kernel configuration
 neverallow all_untrusted_apps config_gz:file { no_rw_file_perms no_x_file_perms };
 
+# Only system_server can access proc_uid_time_in_state
+neverallow { domain -init -system_server } proc_uid_time_in_state:file *;
+
 # Do not allow untrusted apps access to preloads data files
 neverallow all_untrusted_apps preloads_data_file:file no_rw_file_perms;
 
diff --git a/private/compat/26.0/26.0.cil b/private/compat/26.0/26.0.cil
index 9f1643b8d..ca34491c8 100644
--- a/private/compat/26.0/26.0.cil
+++ b/private/compat/26.0/26.0.cil
@@ -446,7 +446,7 @@
 (typeattributeset preopt2cachename_exec_26_0 (preopt2cachename_exec))
 (typeattributeset print_service_26_0 (print_service))
 (typeattributeset priv_app_26_0 (mediaprovider priv_app))
-(typeattributeset proc_26_0 (proc proc_uid_time_in_state proc_kmsg))
+(typeattributeset proc_26_0 (proc proc_asound_cards proc_cmdline proc_filesystems proc_kmsg proc_loadavg proc_mounts proc_pagetypeinfo proc_swaps proc_uid_time_in_state proc_version proc_vmallocinfo))
 (typeattributeset proc_bluetooth_writable_26_0 (proc_bluetooth_writable))
 (typeattributeset proc_cpuinfo_26_0 (proc_cpuinfo))
 (typeattributeset proc_drop_caches_26_0 (proc_drop_caches))
diff --git a/private/compat/26.0/26.0.ignore.cil b/private/compat/26.0/26.0.ignore.cil
index 9a418de9f..f3f462dfe 100644
--- a/private/compat/26.0/26.0.ignore.cil
+++ b/private/compat/26.0/26.0.ignore.cil
@@ -10,6 +10,7 @@
     e2fs_exec
     hal_broadcastradio_hwservice
     hal_cas_hwservice
+    hal_lowpan_hwservice
     hal_neuralnetworks_hwservice
     hal_tetheroffload_hwservice
     hal_wifi_offload_hwservice
@@ -18,6 +19,13 @@
     mediaprovider_tmpfs
     netd_stable_secret_prop
     package_native_service
+    lowpan_device
+    lowpan_prop
+    lowpan_service
+    mediaprovider_tmpfs
+    netd_stable_secret_prop
+    package_native_service
+    storaged_data_file
     sysfs_fs_ext4_features
     system_boot_reason_prop
     system_net_netd_hwservice
@@ -27,7 +35,9 @@
     thermalserviced_exec
     thermalserviced_tmpfs
     timezone_service
-    tombstoned_java_trace_socket))
+    tombstoned_java_trace_socket
+    tombstoned_java_trace_socket
+    vold_service))
 
 ;; private_objects - a collection of types that were labeled differently in
 ;;     older policy, but that should not remain accessible to vendor policy.
diff --git a/private/file.te b/private/file.te
index da5f9adde..7bd83f2c5 100644
--- a/private/file.te
+++ b/private/file.te
@@ -5,3 +5,6 @@ typealias app_data_file alias download_file;
 
 # /proc/config.gz
 type config_gz, fs_type;
+
+# /data/misc/storaged
+type storaged_data_file, file_type, data_file_type, core_data_file_type;
diff --git a/private/file_contexts b/private/file_contexts
index ed51482c6..d5a0bb1d1 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -28,7 +28,6 @@
 /mnt                u:object_r:tmpfs:s0
 /postinstall        u:object_r:postinstall_mnt_dir:s0
 /proc               u:object_r:rootfs:s0
-/root               u:object_r:rootfs:s0
 /sys                u:object_r:sysfs:s0
 
 # Symlinks
@@ -375,6 +374,7 @@
 /data/misc/recovery(/.*)?       u:object_r:recovery_data_file:s0
 /data/misc/shared_relro(/.*)?   u:object_r:shared_relro_file:s0
 /data/misc/sms(/.*)?            u:object_r:radio_data_file:s0
+/data/misc/storaged(/.*)?       u:object_r:storaged_data_file:s0
 /data/misc/systemkeys(/.*)?     u:object_r:systemkeys_data_file:s0
 /data/misc/textclassifier(/.*)?       u:object_r:textclassifier_data_file:s0
 /data/misc/user(/.*)?           u:object_r:misc_user_data_file:s0
diff --git a/private/genfs_contexts b/private/genfs_contexts
index e0375d158..b5827c803 100644
--- a/private/genfs_contexts
+++ b/private/genfs_contexts
@@ -2,18 +2,25 @@
 genfscon rootfs / u:object_r:rootfs:s0
 # proc labeling can be further refined (longest matching prefix).
 genfscon proc / u:object_r:proc:s0
+genfscon proc /asound/cards u:object_r:proc_asound_cards:s0
+genfscon proc /cmdline u:object_r:proc_cmdline:s0
 genfscon proc /config.gz u:object_r:config_gz:s0
+genfscon proc /filesystems u:object_r:proc_filesystems:s0
 genfscon proc /interrupts u:object_r:proc_interrupts:s0
 genfscon proc /iomem u:object_r:proc_iomem:s0
 genfscon proc /kmsg u:object_r:proc_kmsg:s0
+genfscon proc /loadavg u:object_r:proc_loadavg:s0
 genfscon proc /meminfo u:object_r:proc_meminfo:s0
 genfscon proc /misc u:object_r:proc_misc:s0
 genfscon proc /modules u:object_r:proc_modules:s0
+genfscon proc /mounts u:object_r:proc_mounts:s0
 genfscon proc /net u:object_r:proc_net:s0
 genfscon proc /net/xt_qtaguid/ctrl u:object_r:qtaguid_proc:s0
 genfscon proc /cpuinfo u:object_r:proc_cpuinfo:s0
+genfscon proc /pagetypeinfo u:object_r:proc_pagetypeinfo:s0
 genfscon proc /softirqs u:object_r:proc_timer:s0
 genfscon proc /stat u:object_r:proc_stat:s0
+genfscon proc /swaps u:object_r:proc_swaps:s0
 genfscon proc /sysrq-trigger u:object_r:proc_sysrq:s0
 genfscon proc /sys/fs/protected_hardlinks u:object_r:proc_security:s0
 genfscon proc /sys/fs/protected_symlinks u:object_r:proc_security:s0
@@ -42,6 +49,8 @@ genfscon proc /uid_cputime/remove_uid_range u:object_r:proc_uid_cputime_removeui
 genfscon proc /uid_io/stats u:object_r:proc_uid_io_stats:s0
 genfscon proc /uid_procstat/set u:object_r:proc_uid_procstat_set:s0
 genfscon proc /uid_time_in_state u:object_r:proc_uid_time_in_state:s0
+genfscon proc /version u:object_r:proc_version:s0
+genfscon proc /vmallocinfo u:object_r:proc_vmallocinfo:s0
 genfscon proc /zoneinfo u:object_r:proc_zoneinfo:s0
 
 # selinuxfs booleans can be individually labeled.
diff --git a/private/hwservice_contexts b/private/hwservice_contexts
index e30449553..9da38a61f 100644
--- a/private/hwservice_contexts
+++ b/private/hwservice_contexts
@@ -23,6 +23,7 @@ android.hardware.health::IHealth                                u:object_r:hal_h
 android.hardware.ir::IConsumerIr                                u:object_r:hal_ir_hwservice:s0
 android.hardware.keymaster::IKeymasterDevice                    u:object_r:hal_keymaster_hwservice:s0
 android.hardware.light::ILight                                  u:object_r:hal_light_hwservice:s0
+android.hardware.lowpan::ILowpanDevice                          u:object_r:hal_lowpan_hwservice:s0
 android.hardware.media.omx::IOmx                                u:object_r:hal_omx_hwservice:s0
 android.hardware.media.omx::IOmxStore                           u:object_r:hal_omx_hwservice:s0
 android.hardware.memtrack::IMemtrack                            u:object_r:hal_memtrack_hwservice:s0
diff --git a/private/property_contexts b/private/property_contexts
index bb7780a9d..55974c041 100644
--- a/private/property_contexts
+++ b/private/property_contexts
@@ -113,5 +113,9 @@ ro.dalvik.              u:object_r:dalvik_prop:s0
 # Shared between system server and wificond
 wlan.                   u:object_r:wifi_prop:s0
 
+# Lowpan properties
+lowpan.                 u:object_r:lowpan_prop:s0
+ro.lowpan.              u:object_r:lowpan_prop:s0
+
 # hwservicemanager properties
 hwservicemanager.       u:object_r:hwservicemanager_prop:s0
diff --git a/private/service_contexts b/private/service_contexts
index d967bd216..7dc83412f 100644
--- a/private/service_contexts
+++ b/private/service_contexts
@@ -46,6 +46,7 @@ drm.drmManager                            u:object_r:drmserver_service:s0
 dropbox                                   u:object_r:dropbox_service:s0
 dumpstate                                 u:object_r:dumpstate_service:s0
 econtroller                               u:object_r:radio_service:s0
+lowpan                                    u:object_r:lowpan_service:s0
 ethernet                                  u:object_r:ethernet_service:s0
 fingerprint                               u:object_r:fingerprint_service:s0
 font                                      u:object_r:font_service:s0
@@ -160,6 +161,7 @@ user                                      u:object_r:user_service:s0
 vibrator                                  u:object_r:vibrator_service:s0
 virtual_touchpad                          u:object_r:virtual_touchpad_service:s0
 voiceinteraction                          u:object_r:voiceinteraction_service:s0
+vold                                      u:object_r:vold_service:s0
 vr_hwc                                    u:object_r:vr_hwc_service:s0
 vrmanager                                 u:object_r:vr_manager_service:s0
 wallpaper                                 u:object_r:wallpaper_service:s0
diff --git a/private/storaged.te b/private/storaged.te
index 20377e046..8da1f26d8 100644
--- a/private/storaged.te
+++ b/private/storaged.te
@@ -15,6 +15,10 @@ allow storaged proc_uid_io_stats:file r_file_perms;
 # Read /data/system/packages.list
 allow storaged system_data_file:file r_file_perms;
 
+# Store storaged proto file
+allow storaged storaged_data_file:dir rw_dir_perms;
+allow storaged storaged_data_file:file create_file_perms;
+
 userdebug_or_eng(`
   # Read access to debugfs
   allow storaged debugfs_mmc:dir search;
diff --git a/private/system_app.te b/private/system_app.te
index 940033e02..904b8518d 100644
--- a/private/system_app.te
+++ b/private/system_app.te
@@ -58,7 +58,15 @@ binder_call(system_app, incidentd)
 
 allow system_app servicemanager:service_manager list;
 # TODO: scope this down? Too broad?
-allow system_app { service_manager_type -netd_service -dumpstate_service -installd_service -virtual_touchpad_service -vr_hwc_service }:service_manager find;
+allow system_app {
+  service_manager_type
+  -dumpstate_service
+  -installd_service
+  -netd_service
+  -virtual_touchpad_service
+  -vold_service
+  -vr_hwc_service
+}:service_manager find;
 
 allow system_app keystore:keystore_key {
     get_state
diff --git a/private/system_server.te b/private/system_server.te
index 1bf28b6b3..c1b184a31 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -178,6 +178,7 @@ binder_call(system_server, gatekeeperd)
 binder_call(system_server, installd)
 binder_call(system_server, incidentd)
 binder_call(system_server, netd)
+binder_call(system_server, vold)
 binder_call(system_server, wificond)
 binder_service(system_server)
 
@@ -574,6 +575,7 @@ allow system_server netd_service:service_manager find;
 allow system_server nfc_service:service_manager find;
 allow system_server radio_service:service_manager find;
 allow system_server surfaceflinger_service:service_manager find;
+allow system_server vold_service:service_manager find;
 allow system_server wificond_service:service_manager find;
 
 allow system_server keystore:keystore_key {
@@ -673,9 +675,13 @@ allow system_server preloads_media_file:dir { r_dir_perms write remove_name rmdi
 r_dir_file(system_server, cgroup)
 allow system_server ion_device:chr_file r_file_perms;
 
-r_dir_file(system_server, proc)
+r_dir_file(system_server, proc_asound_cards)
+r_dir_file(system_server, proc_loadavg)
 r_dir_file(system_server, proc_meminfo)
 r_dir_file(system_server, proc_net)
+r_dir_file(system_server, proc_pagetypeinfo)
+r_dir_file(system_server, proc_version)
+r_dir_file(system_server, proc_vmallocinfo)
 r_dir_file(system_server, rootfs)
 r_dir_file(system_server, sysfs_type)
 
diff --git a/public/attributes b/public/attributes
index 4dddf496c..986b0ed2a 100644
--- a/public/attributes
+++ b/public/attributes
@@ -190,234 +190,45 @@ attribute halclientdomain;
 expandattribute halclientdomain true;
 
 # HALs
-attribute hal_allocator;
-expandattribute hal_allocator true;
-attribute hal_allocator_client;
-expandattribute hal_allocator_client true;
-attribute hal_allocator_server;
-expandattribute hal_allocator_server false;
-attribute hal_audio;
-expandattribute hal_audio false;
-attribute hal_audio_client;
-expandattribute hal_audio_client true;
-attribute hal_audio_server;
-expandattribute hal_audio_server false;
-attribute hal_bluetooth;
-expandattribute hal_bluetooth true;
-attribute hal_bluetooth_client;
-expandattribute hal_bluetooth_client true;
-attribute hal_bluetooth_server;
-expandattribute hal_bluetooth_server false;
-attribute hal_bootctl;
-expandattribute hal_bootctl false;
-attribute hal_bootctl_client;
-expandattribute hal_bootctl_client true;
-attribute hal_bootctl_server;
-expandattribute hal_bootctl_server false;
-attribute hal_broadcastradio;
-expandattribute hal_broadcastradio true;
-attribute hal_broadcastradio_client;
-expandattribute hal_broadcastradio_client true;
-attribute hal_broadcastradio_server;
-expandattribute hal_broadcastradio_server false;
-attribute hal_camera;
-expandattribute hal_camera false;
-attribute hal_camera_client;
-expandattribute hal_camera_client true;
-attribute hal_camera_server;
-expandattribute hal_camera_server false;
-attribute hal_configstore;
-expandattribute hal_configstore true;
-attribute hal_configstore_client;
-expandattribute hal_configstore_client true;
-attribute hal_configstore_server;
-expandattribute hal_configstore_server false;
-attribute hal_contexthub;
-expandattribute hal_contexthub true;
-attribute hal_contexthub_client;
-expandattribute hal_contexthub_client true;
-attribute hal_contexthub_server;
-expandattribute hal_contexthub_server false;
-attribute hal_drm;
-expandattribute hal_drm false;
-attribute hal_drm_client;
-expandattribute hal_drm_client true;
-attribute hal_drm_server;
-expandattribute hal_drm_server true;
-attribute hal_cas;
-expandattribute hal_cas false;
-attribute hal_cas_client;
-expandattribute hal_cas_client true;
-attribute hal_cas_server;
-expandattribute hal_cas_server false;
-attribute hal_dumpstate;
-expandattribute hal_dumpstate true;
-attribute hal_dumpstate_client;
-expandattribute hal_dumpstate_client true;
-attribute hal_dumpstate_server;
-expandattribute hal_dumpstate_server false;
-attribute hal_fingerprint;
-expandattribute hal_fingerprint true;
-attribute hal_fingerprint_client;
-expandattribute hal_fingerprint_client true;
-attribute hal_fingerprint_server;
-expandattribute hal_fingerprint_server false;
-attribute hal_gatekeeper;
-expandattribute hal_gatekeeper true;
-attribute hal_gatekeeper_client;
-expandattribute hal_gatekeeper_client true;
-attribute hal_gatekeeper_server;
-expandattribute hal_gatekeeper_server false;
-attribute hal_gnss;
-expandattribute hal_gnss true;
-attribute hal_gnss_client;
-expandattribute hal_gnss_client true;
-attribute hal_gnss_server;
-expandattribute hal_gnss_server false;
-attribute hal_graphics_allocator;
-expandattribute hal_graphics_allocator true;
-attribute hal_graphics_allocator_client;
-expandattribute hal_graphics_allocator_client true;
-attribute hal_graphics_allocator_server;
-expandattribute hal_graphics_allocator_server false;
-attribute hal_graphics_composer;
-expandattribute hal_graphics_composer true;
-attribute hal_graphics_composer_client;
-expandattribute hal_graphics_composer_client true;
-attribute hal_graphics_composer_server;
-expandattribute hal_graphics_composer_server false;
-attribute hal_health;
-expandattribute hal_health true;
-attribute hal_health_client;
-expandattribute hal_health_client true;
-attribute hal_health_server;
-expandattribute hal_health_server false;
-attribute hal_ir;
-expandattribute hal_ir true;
-attribute hal_ir_client;
-expandattribute hal_ir_client true;
-attribute hal_ir_server;
-expandattribute hal_ir_server false;
-attribute hal_keymaster;
-expandattribute hal_keymaster true;
-attribute hal_keymaster_client;
-expandattribute hal_keymaster_client true;
-attribute hal_keymaster_server;
-expandattribute hal_keymaster_server false;
-attribute hal_light;
-expandattribute hal_light true;
-attribute hal_light_client;
-expandattribute hal_light_client true;
-attribute hal_light_server;
-expandattribute hal_light_server false;
-attribute hal_memtrack;
-expandattribute hal_memtrack true;
-attribute hal_memtrack_client;
-expandattribute hal_memtrack_client true;
-attribute hal_memtrack_server;
-expandattribute hal_memtrack_server false;
-attribute hal_neuralnetworks;
-expandattribute hal_neuralnetworks true;
-attribute hal_neuralnetworks_client;
-expandattribute hal_neuralnetworks_client true;
-attribute hal_neuralnetworks_server;
-expandattribute hal_neuralnetworks_server false;
-attribute hal_nfc;
-expandattribute hal_nfc true;
-attribute hal_nfc_client;
-expandattribute hal_nfc_client true;
-attribute hal_nfc_server;
-expandattribute hal_nfc_server false;
-attribute hal_oemlock;
-expandattribute hal_oemlock true;
-attribute hal_oemlock_client;
-expandattribute hal_oemlock_client true;
-attribute hal_oemlock_server;
-expandattribute hal_oemlock_server false;
-attribute hal_power;
-expandattribute hal_power true;
-attribute hal_power_client;
-expandattribute hal_power_client true;
-attribute hal_power_server;
-expandattribute hal_power_server false;
-attribute hal_sensors;
-expandattribute hal_sensors true;
-attribute hal_sensors_client;
-expandattribute hal_sensors_client true;
-attribute hal_sensors_server;
-expandattribute hal_sensors_server false;
-attribute hal_telephony;
-expandattribute hal_telephony true;
-attribute hal_telephony_client;
-expandattribute hal_telephony_client true;
-attribute hal_telephony_server;
-expandattribute hal_telephony_server false;
-attribute hal_tetheroffload;
-expandattribute hal_tetheroffload true;
-attribute hal_tetheroffload_client;
-expandattribute hal_tetheroffload_client true;
-attribute hal_tetheroffload_server;
-expandattribute hal_tetheroffload_server false;
-attribute hal_thermal;
-expandattribute hal_thermal true;
-attribute hal_thermal_client;
-expandattribute hal_thermal_client true;
-attribute hal_thermal_server;
-expandattribute hal_thermal_server false;
-attribute hal_tv_cec;
-expandattribute hal_tv_cec true;
-attribute hal_tv_cec_client;
-expandattribute hal_tv_cec_client true;
-attribute hal_tv_cec_server;
-expandattribute hal_tv_cec_server false;
-attribute hal_tv_input;
-expandattribute hal_tv_input true;
-attribute hal_tv_input_client;
-expandattribute hal_tv_input_client true;
-attribute hal_tv_input_server;
-expandattribute hal_tv_input_server false;
-attribute hal_usb;
-expandattribute hal_usb true;
-attribute hal_usb_client;
-expandattribute hal_usb_client true;
-attribute hal_usb_server;
-expandattribute hal_usb_server false;
-attribute hal_vibrator;
-expandattribute hal_vibrator true;
-attribute hal_vibrator_client;
-expandattribute hal_vibrator_client true;
-attribute hal_vibrator_server;
-expandattribute hal_vibrator_server false;
-attribute hal_vr;
-expandattribute hal_vr true;
-attribute hal_vr_client;
-expandattribute hal_vr_client true;
-attribute hal_vr_server;
-expandattribute hal_vr_server false;
-attribute hal_weaver;
-expandattribute hal_weaver true;
-attribute hal_weaver_client;
-expandattribute hal_weaver_client true;
-attribute hal_weaver_server;
-expandattribute hal_weaver_server false;
-attribute hal_wifi;
-expandattribute hal_wifi true;
-attribute hal_wifi_client;
-expandattribute hal_wifi_client true;
-attribute hal_wifi_server;
-expandattribute hal_wifi_server false;
-attribute hal_wifi_offload;
-expandattribute hal_wifi_offload true;
-attribute hal_wifi_offload_client;
-expandattribute hal_wifi_offload_client true;
-attribute hal_wifi_offload_server;
-expandattribute hal_wifi_offload_server false;
-attribute hal_wifi_supplicant;
-expandattribute hal_wifi_supplicant true;
-attribute hal_wifi_supplicant_client;
-expandattribute hal_wifi_supplicant_client true;
-attribute hal_wifi_supplicant_server;
-expandattribute hal_wifi_supplicant_server false;
+hal_attribute(allocator);
+hal_attribute(audio);
+hal_attribute(bluetooth);
+hal_attribute(bootctl);
+hal_attribute(broadcastradio);
+hal_attribute(camera);
+hal_attribute(configstore);
+hal_attribute(contexthub);
+hal_attribute(drm);
+hal_attribute(cas);
+hal_attribute(dumpstate);
+hal_attribute(fingerprint);
+hal_attribute(gatekeeper);
+hal_attribute(gnss);
+hal_attribute(graphics_allocator);
+hal_attribute(graphics_composer);
+hal_attribute(health);
+hal_attribute(ir);
+hal_attribute(keymaster);
+hal_attribute(light);
+hal_attribute(lowpan);
+hal_attribute(memtrack);
+hal_attribute(neuralnetworks);
+hal_attribute(nfc);
+hal_attribute(oemlock);
+hal_attribute(power);
+hal_attribute(sensors);
+hal_attribute(telephony);
+hal_attribute(tetheroffload);
+hal_attribute(thermal);
+hal_attribute(tv_cec);
+hal_attribute(tv_input);
+hal_attribute(usb);
+hal_attribute(vibrator);
+hal_attribute(vr);
+hal_attribute(weaver);
+hal_attribute(wifi);
+hal_attribute(wifi_offload);
+hal_attribute(wifi_supplicant);
 
 # HwBinder services offered across the core-vendor boundary
 #
diff --git a/public/device.te b/public/device.te
index 475948da0..1d0104529 100644
--- a/public/device.te
+++ b/public/device.te
@@ -30,6 +30,7 @@ type hw_random_device, dev_type;
 type input_device, dev_type;
 type kmem_device, dev_type;
 type port_device, dev_type;
+type lowpan_device, dev_type;
 type mtd_device, dev_type;
 type mtp_device, dev_type, mlstrustedobject;
 type nfc_device, dev_type;
diff --git a/public/dumpstate.te b/public/dumpstate.te
index 3d8049518..d0204a50b 100644
--- a/public/dumpstate.te
+++ b/public/dumpstate.te
@@ -153,6 +153,9 @@ read_runtime_log_tags(dumpstate)
 # Read files in /proc
 allow dumpstate proc_meminfo:file r_file_perms;
 allow dumpstate proc_net:file r_file_perms;
+allow dumpstate proc_pagetypeinfo:file r_file_perms;
+allow dumpstate proc_version:file r_file_perms;
+allow dumpstate proc_vmallocinfo:file r_file_perms;
 r_dir_file(dumpstate, proc)
 
 # Read network state info files.
@@ -186,7 +189,15 @@ userdebug_or_eng(`
   allow dumpstate misc_logd_file:file r_file_perms;
 ')
 
-allow dumpstate { service_manager_type -gatekeeper_service -dumpstate_service -incident_service -virtual_touchpad_service -vr_hwc_service }:service_manager find;
+allow dumpstate {
+  service_manager_type
+  -dumpstate_service
+  -gatekeeper_service
+  -incident_service
+  -virtual_touchpad_service
+  -vold_service
+  -vr_hwc_service
+}:service_manager find;
 allow dumpstate servicemanager:service_manager list;
 allow dumpstate hwservicemanager:hwservice_manager list;
 
diff --git a/public/e2fs.te b/public/e2fs.te
index 30a815a01..a95512128 100644
--- a/public/e2fs.te
+++ b/public/e2fs.te
@@ -5,8 +5,11 @@ allow e2fs block_device:blk_file getattr;
 allow e2fs block_device:dir search;
 allow e2fs userdata_block_device:blk_file rw_file_perms;
 
-# access /proc/filesystems
-allow e2fs proc:file r_file_perms;
+allow e2fs {
+  proc_filesystems
+  proc_mounts
+  proc_swaps
+}:file r_file_perms;
 
 # access /sys/fs/ext4/features
 allow e2fs sysfs_fs_ext4_features:file r_file_perms;
diff --git a/public/file.te b/public/file.te
index b49ff78b7..51a0439d6 100644
--- a/public/file.te
+++ b/public/file.te
@@ -13,16 +13,23 @@ type usermodehelper, fs_type;
 type sysfs_usermodehelper, fs_type, sysfs_type;
 type qtaguid_proc, fs_type, mlstrustedobject;
 type proc_bluetooth_writable, fs_type;
+type proc_asound_cards, fs_type;
+type proc_cmdline, fs_type;
 type proc_cpuinfo, fs_type;
+type proc_filesystems, fs_type;
 type proc_interrupts, fs_type;
 type proc_iomem, fs_type;
 type proc_kmsg, fs_type;
+type proc_loadavg, fs_type;
 type proc_meminfo, fs_type;
 type proc_misc, fs_type;
 type proc_modules, fs_type;
+type proc_mounts, fs_type;
 type proc_net, fs_type;
+type proc_pagetypeinfo, fs_type;
 type proc_perf, fs_type;
 type proc_stat, fs_type;
+type proc_swaps, fs_type;
 type proc_sysrq, fs_type;
 type proc_timer, fs_type;
 type proc_tty_drivers, fs_type;
@@ -31,6 +38,8 @@ type proc_uid_cputime_removeuid, fs_type;
 type proc_uid_io_stats, fs_type;
 type proc_uid_procstat_set, fs_type;
 type proc_uid_time_in_state, fs_type;
+type proc_version, fs_type;
+type proc_vmallocinfo, fs_type;
 type proc_zoneinfo, fs_type;
 type selinuxfs, fs_type, mlstrustedobject;
 type cgroup, fs_type, mlstrustedobject;
diff --git a/public/fsck.te b/public/fsck.te
index b682a877f..7cc7e8b18 100644
--- a/public/fsck.te
+++ b/public/fsck.te
@@ -30,7 +30,10 @@ allow fsck dm_device:blk_file rw_file_perms;
 # major/minor values.
 allow fsck dev_type:blk_file getattr;
 
-r_dir_file(fsck, proc)
+allow fsck {
+  proc_mounts
+  proc_swaps
+}:file r_file_perms;
 allow fsck rootfs:dir r_dir_perms;
 
 ###
diff --git a/public/fsck_untrusted.te b/public/fsck_untrusted.te
index e2aceb87b..8510c9424 100644
--- a/public/fsck_untrusted.te
+++ b/public/fsck_untrusted.te
@@ -12,7 +12,7 @@ allow fsck_untrusted vold:fifo_file { read write getattr };
 allow fsck_untrusted block_device:dir search;
 allow fsck_untrusted vold_device:blk_file rw_file_perms;
 
-r_dir_file(fsck_untrusted, proc)
+allow fsck_untrusted proc_mounts:file r_file_perms;
 
 # To determine if it is safe to run fsck on a filesystem, e2fsck
 # must first determine if the filesystem is mounted. To do that,
diff --git a/public/hal_audio.te b/public/hal_audio.te
index 33330bf6b..be7e23550 100644
--- a/public/hal_audio.te
+++ b/public/hal_audio.te
@@ -14,6 +14,7 @@ userdebug_or_eng(`
 ')
 
 r_dir_file(hal_audio, proc)
+r_dir_file(hal_audio, proc_asound_cards)
 allow hal_audio audio_device:dir r_dir_perms;
 allow hal_audio audio_device:chr_file rw_file_perms;
 
diff --git a/public/hal_lowpan.te b/public/hal_lowpan.te
new file mode 100644
index 000000000..af491b159
--- /dev/null
+++ b/public/hal_lowpan.te
@@ -0,0 +1,21 @@
+# HwBinder IPC from client to server, and callbacks
+binder_call(hal_lowpan_client, hal_lowpan_server)
+binder_call(hal_lowpan_server, hal_lowpan_client)
+
+add_hwservice(hal_lowpan_server, hal_lowpan_hwservice)
+
+# Allow hal_lowpan_client to be able to find the hal_lowpan_server
+allow hal_lowpan_client hal_lowpan_hwservice:hwservice_manager find;
+
+# hal_lowpan domain can write/read to/from lowpan_prop
+set_prop(hal_lowpan_server, lowpan_prop)
+
+# Allow hal_lowpan_server to open lowpan_devices
+allow hal_lowpan_server lowpan_device:chr_file rw_file_perms;
+
+###
+### neverallow rules
+###
+
+# Only LoWPAN HAL may directly access LoWPAN hardware
+neverallow { domain -hal_lowpan_server -init -ueventd } lowpan_device:chr_file ~getattr;
diff --git a/public/hwservice.te b/public/hwservice.te
index 97b9b8d19..19a72051b 100644
--- a/public/hwservice.te
+++ b/public/hwservice.te
@@ -22,6 +22,7 @@ type hal_health_hwservice, hwservice_manager_type;
 type hal_ir_hwservice, hwservice_manager_type;
 type hal_keymaster_hwservice, hwservice_manager_type;
 type hal_light_hwservice, hwservice_manager_type;
+type hal_lowpan_hwservice, hwservice_manager_type;
 type hal_memtrack_hwservice, hwservice_manager_type;
 type hal_neuralnetworks_hwservice, hwservice_manager_type;
 type hal_nfc_hwservice, hwservice_manager_type;
diff --git a/public/init.te b/public/init.te
index f317877c2..db2ce433d 100644
--- a/public/init.te
+++ b/public/init.te
@@ -271,6 +271,12 @@ allow init proc_sysrq:file w_file_perms;
 # Read /proc/stat for bootchart.
 allow init proc_stat:file r_file_perms;
 
+# Read /proc/version.
+allow init proc_version:file r_file_perms;
+
+# Read /proc/cmdline
+allow init proc_cmdline:file r_file_perms;
+
 # Reboot.
 allow init self:capability sys_boot;
 
diff --git a/public/kernel.te b/public/kernel.te
index 7f5d22443..64111b0fa 100644
--- a/public/kernel.te
+++ b/public/kernel.te
@@ -6,6 +6,7 @@ allow kernel self:capability sys_nice;
 # Root fs.
 r_dir_file(kernel, rootfs)
 r_dir_file(kernel, proc)
+allow kernel proc_cmdline:file r_file_perms;
 
 # Get SELinux enforcing status.
 allow kernel selinuxfs:dir r_dir_perms;
diff --git a/public/property.te b/public/property.te
index aa0b4ddf9..713dc8373 100644
--- a/public/property.te
+++ b/public/property.te
@@ -29,6 +29,7 @@ type logd_prop, property_type, core_property_type;
 type logpersistd_logging_prop, property_type;
 type log_prop, property_type, log_property_type;
 type log_tag_prop, property_type, log_property_type;
+type lowpan_prop, property_type;
 type mmc_prop, property_type;
 type net_dns_prop, property_type;
 type net_radio_prop, property_type, core_property_type;
diff --git a/public/sdcardd.te b/public/sdcardd.te
index 47a2f8061..2af64102d 100644
--- a/public/sdcardd.te
+++ b/public/sdcardd.te
@@ -32,7 +32,7 @@ allow sdcardd vold:fifo_file { read write getattr };
 allow sdcardd mnt_expand_file:dir search;
 
 # access /proc/filesystems
-allow sdcardd proc:file r_file_perms;
+allow sdcardd proc_filesystems:file r_file_perms;
 
 ###
 ### neverallow rules
diff --git a/public/service.te b/public/service.te
index e97b864db..068ea4e78 100644
--- a/public/service.te
+++ b/public/service.te
@@ -27,6 +27,7 @@ type system_app_service,        service_manager_type;
 type thermal_service,           service_manager_type;
 type update_engine_service,     service_manager_type;
 type virtual_touchpad_service,  service_manager_type;
+type vold_service,              service_manager_type;
 type vr_hwc_service,            service_manager_type;
 
 # system_server_services broken down
@@ -71,6 +72,7 @@ type netd_listener_service, system_server_service, service_manager_type;
 type DockObserver_service, system_server_service, service_manager_type;
 type dreams_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
 type dropbox_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
+type lowpan_service, system_api_service, system_server_service, service_manager_type;
 type ethernet_service, app_api_service, system_server_service, service_manager_type;
 type fingerprint_service, app_api_service, system_server_service, service_manager_type;
 type gfxinfo_service, system_api_service, system_server_service, service_manager_type;
diff --git a/public/shell.te b/public/shell.te
index 36964e50f..84e76f2a3 100644
--- a/public/shell.te
+++ b/public/shell.te
@@ -89,7 +89,16 @@ allow shell servicemanager:service_manager list;
 # don't allow shell to access GateKeeper service
 # TODO: why is this so broad? Tightening candidate? It needs at list:
 # - dumpstate_service (so it can receive dumpstate progress updates)
-allow shell { service_manager_type -gatekeeper_service -incident_service -installd_service -netd_service -virtual_touchpad_service -vr_hwc_service }:service_manager find;
+allow shell {
+  service_manager_type
+  -gatekeeper_service
+  -incident_service
+  -installd_service
+  -netd_service
+  -virtual_touchpad_service
+  -vold_service
+  -vr_hwc_service
+}:service_manager find;
 allow shell dumpstate:binder call;
 
 # allow shell to get information from hwservicemanager
diff --git a/public/su.te b/public/su.te
index 8ddd16224..88065f626 100644
--- a/public/su.te
+++ b/public/su.te
@@ -50,4 +50,47 @@ userdebug_or_eng(`
   dontaudit su domain:drmservice *;
   dontaudit su unlabeled:filesystem *;
   dontaudit su postinstall_file:filesystem *;
+
+  # VTS tests run in the permissive su domain on debug builds, but the HALs
+  # being tested run in enforcing mode. Because hal_foo_server is enforcing
+  # su needs to be declared as hal_foo_client to grant hal_foo_server
+  # permission to interact with it.
+  typeattribute su halclientdomain;
+  typeattribute su hal_allocator_client;
+  typeattribute su hal_audio_client;
+  typeattribute su hal_bluetooth_client;
+  typeattribute su hal_bootctl_client;
+  typeattribute su hal_camera_client;
+  typeattribute su hal_configstore_client;
+  typeattribute su hal_contexthub_client;
+  typeattribute su hal_drm_client;
+  typeattribute su hal_cas_client;
+  typeattribute su hal_dumpstate_client;
+  typeattribute su hal_fingerprint_client;
+  typeattribute su hal_gatekeeper_client;
+  typeattribute su hal_gnss_client;
+  typeattribute su hal_graphics_allocator_client;
+  typeattribute su hal_graphics_composer_client;
+  typeattribute su hal_health_client;
+  typeattribute su hal_ir_client;
+  typeattribute su hal_keymaster_client;
+  typeattribute su hal_light_client;
+  typeattribute su hal_memtrack_client;
+  typeattribute su hal_neuralnetworks_client;
+  typeattribute su hal_nfc_client;
+  typeattribute su hal_oemlock_client;
+  typeattribute su hal_power_client;
+  typeattribute su hal_sensors_client;
+  typeattribute su hal_telephony_client;
+  typeattribute su hal_tetheroffload_client;
+  typeattribute su hal_thermal_client;
+  typeattribute su hal_tv_cec_client;
+  typeattribute su hal_tv_input_client;
+  typeattribute su hal_usb_client;
+  typeattribute su hal_vibrator_client;
+  typeattribute su hal_vr_client;
+  typeattribute su hal_weaver_client;
+  typeattribute su hal_wifi_client;
+  typeattribute su hal_wifi_offload_client;
+  typeattribute su hal_wifi_supplicant_client;
 ')
diff --git a/public/te_macros b/public/te_macros
index 2f26199ee..0fdd9be64 100644
--- a/public/te_macros
+++ b/public/te_macros
@@ -201,6 +201,22 @@ define(`bluetooth_domain', `
 typeattribute $1 bluetoothdomain;
 ')
 
+#####################################
+# hal_attribute(hal_name)
+# Add an attribute for hal implementations along with necessary
+# restrictions.
+define(`hal_attribute', `
+attribute hal_$1;
+expandattribute hal_$1 true;
+attribute hal_$1_client;
+expandattribute hal_$1_client true;
+attribute hal_$1_server;
+expandattribute hal_$1_server false;
+
+neverallow { hal_$1_client -halclientdomain } domain:process fork;
+neverallow { hal_$1_server -halserverdomain } domain:process fork;
+')
+
 #####################################
 # hal_server_domain(domain, hal_type)
 # Allow a base set of permissions required for a domain to offer a
diff --git a/public/vdc.te b/public/vdc.te
index 53d7bbe2c..75a5d1b8a 100644
--- a/public/vdc.te
+++ b/public/vdc.te
@@ -8,16 +8,20 @@
 type vdc, domain;
 type vdc_exec, exec_type, file_type;
 
+# TODO: remove as part of 13758960
 unix_socket_connect(vdc, vold, vold)
 
 # vdc sends information back to dumpstate when "adb bugreport" is used
+# TODO: remove as part of 13758960
 allow vdc dumpstate:fd use;
 allow vdc dumpstate:unix_stream_socket { read write getattr };
 
 # vdc information is written to shell owned bugreport files
+# TODO: remove as part of 13758960
 allow vdc shell_data_file:file { write getattr };
 
 # Why?
+# TODO: remove as part of 13758960
 allow vdc dumpstate:unix_dgram_socket { read write };
 
 # vdc can be invoked with logwrapper, so let it write to pty
@@ -25,3 +29,8 @@ allow vdc devpts:chr_file rw_file_perms;
 
 # vdc writes directly to kmsg during the boot process
 allow vdc kmsg_device:chr_file w_file_perms;
+
+# vdc talks to vold over Binder
+binder_use(vdc)
+binder_call(vdc, vold)
+allow vdc vold_service:service_manager find;
diff --git a/public/vold.te b/public/vold.te
index 0657023ac..a8537154a 100644
--- a/public/vold.te
+++ b/public/vold.te
@@ -8,7 +8,6 @@ allow vold cache_file:file { getattr read };
 allow vold cache_file:lnk_file r_file_perms;
 
 # Read access to pseudo filesystems.
-r_dir_file(vold, proc)
 r_dir_file(vold, proc_net)
 r_dir_file(vold, sysfs_type)
 # XXX Label sysfs files with a specific type?
@@ -17,7 +16,13 @@ allow vold sysfs_usb:file w_file_perms;
 allow vold sysfs_zram_uevent:file w_file_perms;
 
 r_dir_file(vold, rootfs)
-allow vold proc_meminfo:file r_file_perms;
+allow vold {
+  proc_cmdline
+  proc_drop_caches
+  proc_filesystems
+  proc_meminfo
+  proc_mounts
+}:file r_file_perms;
 
 #Get file contexts
 allow vold file_contexts_file:file r_file_perms;
@@ -135,8 +140,15 @@ allow vold unlabeled:file { r_file_perms setattr relabelfrom };
 # Handle wake locks (used for device encryption)
 wakelock_use(vold)
 
-# talk to batteryservice
+# Allow vold to publish a binder service and make binder calls.
 binder_use(vold)
+add_service(vold, vold_service)
+
+# Allow vold to call into the system server so it can check permissions.
+binder_call(vold, system_server)
+allow vold permission_service:service_manager find;
+
+# talk to batteryservice
 binder_call(vold, healthd)
 
 # talk to keymaster
@@ -191,6 +203,18 @@ neverallow { domain -vold -init } vold_data_file:dir *;
 neverallow { domain -vold -init -kernel } vold_data_file:notdevfile_class_set *;
 neverallow { domain -vold -init } restorecon_prop:property_service set;
 
+# Only system_server and vdc can interact with vold over binder
+neverallow { domain -system_server -vdc -vold } vold_service:service_manager find;
+neverallow vold {
+  domain
+  -hal_keymaster
+  -healthd
+  -hwservicemanager
+  -servicemanager
+  -system_server
+  userdebug_or_eng(`-su')
+}:binder call;
+
 neverallow vold fsck_exec:file execute_no_trans;
 neverallow { domain -init } vold:process { transition dyntransition };
 neverallow vold *:process ptrace;
diff --git a/tests/Android.bp b/tests/Android.bp
index ec4b465cf..8fe89e5fe 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -47,3 +47,13 @@ python_binary_host {
     required: ["libsepolwrap"],
     defaults: ["py2_only"],
 }
+
+python_binary_host {
+    name: "searchpolicy",
+    srcs: [
+        "searchpolicy.py",
+        "policy.py",
+    ],
+    required: ["libsepolwrap"],
+    defaults: ["py2_only"],
+}
diff --git a/tests/include/sepol_wrap.h b/tests/include/sepol_wrap.h
index 5615913eb..2357421c7 100644
--- a/tests/include/sepol_wrap.h
+++ b/tests/include/sepol_wrap.h
@@ -9,6 +9,9 @@ void destroy_policy(void *policydbp);
 void *init_avtab(void *policydbp);
 void *init_cond_avtab(void *policydbp);
 void destroy_avtab(void *avtab_iterp);
+void *init_expanded_avtab(void *policydbp);
+void *init_expanded_cond_avtab(void *policydbp);
+void destroy_expanded_avtab(void *avtab_iterp);
 int get_type(char *out, size_t max_size, void *policydbp, void *type_iterp);
 void *init_type_iter(void *policydbp, const char *type, bool is_attr);
 void destroy_type_iter(void *type_iterp);
diff --git a/tests/policy.py b/tests/policy.py
index b8a362129..a0ddb9096 100644
--- a/tests/policy.py
+++ b/tests/policy.py
@@ -41,7 +41,8 @@ class TERule:
         self.rule = rule
 
 class Policy:
-    __Rules = None
+    __ExpandedRules = set()
+    __Rules = set()
     __FcDict = None
     __libsepolwrap = None
     __policydbP = None
@@ -97,6 +98,50 @@ class Policy:
         self.__libsepolwrap.destroy_type_iter(TypeIterP)
         return TypeAttr
 
+    def __TERuleMatch(self, Rule, **kwargs):
+        # Match source type
+        if ("scontext" in kwargs and
+                len(kwargs['scontext']) > 0 and
+                Rule.sctx not in kwargs['scontext']):
+            return False
+        # Match target type
+        if ("tcontext" in kwargs and
+                len(kwargs['tcontext']) > 0 and
+                Rule.tctx not in kwargs['tcontext']):
+            return False
+        # Match target class
+        if ("tclass" in kwargs and
+                len(kwargs['tclass']) > 0 and
+                not bool(set([Rule.tclass]) & kwargs['tclass'])):
+            return False
+        # Match any perms
+        if ("perms" in kwargs and
+                len(kwargs['perms']) > 0 and
+                not bool(Rule.perms & kwargs['perms'])):
+            return False
+        return True
+
+    # resolve a type to its attributes or
+    # resolve an attribute to its types and attributes
+    # For example if scontext is the domain attribute, then we need to
+    # include all types with the domain attribute such as untrusted_app and
+    # priv_app and all the attributes of those types such as appdomain.
+    def ResolveTypeAttribute(self, Type):
+        types = self.GetAllTypes(False)
+        attributes = self.GetAllTypes(True)
+
+        if Type in types:
+            return self.QueryTypeAttribute(Type, False)
+        elif Type in attributes:
+            TypesAndAttributes = set()
+            Types = self.QueryTypeAttribute(Type, True)
+            TypesAndAttributes |= Types
+            for T in Types:
+                TypesAndAttributes |= self.QueryTypeAttribute(T, False)
+            return TypesAndAttributes
+        else:
+            return set()
+
     # Return all TERules that match:
     # (any scontext) or (any tcontext) or (any tclass) or (any perms),
     # perms.
@@ -106,23 +151,32 @@ class Policy:
     # Will return any rule with:
     # (tcontext="foo" or tcontext="bar") and ("entrypoint" in perms)
     def QueryTERule(self, **kwargs):
-        if self.__Rules is None:
+        if len(self.__Rules) == 0:
             self.__InitTERules()
+
+        # add any matching types and attributes for scontext and tcontext
+        if ("scontext" in kwargs and len(kwargs['scontext']) > 0):
+            scontext = set()
+            for sctx in kwargs['scontext']:
+                scontext |= self.ResolveTypeAttribute(sctx)
+            kwargs['scontext'] = scontext
+        if ("tcontext" in kwargs and len(kwargs['tcontext']) > 0):
+            tcontext = set()
+            for tctx in kwargs['tcontext']:
+                tcontext |= self.ResolveTypeAttribute(tctx)
+            kwargs['tcontext'] = tcontext
         for Rule in self.__Rules:
-            # Match source type
-            if "scontext" in kwargs and Rule.sctx not in kwargs['scontext']:
-                continue
-            # Match target type
-            if "tcontext" in kwargs and Rule.tctx not in kwargs['tcontext']:
-                continue
-            # Match target class
-            if "tclass" in kwargs and Rule.tclass not in kwargs['tclass']:
-                continue
-            # Match any perms
-            if "perms" in kwargs and not bool(Rule.perms & set(kwargs['perms'])):
-                continue
-            yield Rule
+            if self.__TERuleMatch(Rule, **kwargs):
+                yield Rule
 
+    # Same as QueryTERule but only using the expanded ruleset.
+    # i.e. all attributes have been expanded to their various types.
+    def QueryExpandedTERule(self, **kwargs):
+        if len(self.__ExpandedRules) == 0:
+            self.__InitExpandedTERules()
+        for Rule in self.__ExpandedRules:
+            if self.__TERuleMatch(Rule, **kwargs):
+                yield Rule
 
     def GetAllTypes(self, isAttr):
         TypeIterP = self.__libsepolwrap.init_type_iter(self.__policydbP, None, isAttr)
@@ -155,9 +209,9 @@ class Policy:
         return Types
 
 
-    def __GetTERules(self, policydbP, avtabIterP):
-        if self.__Rules is None:
-            self.__Rules = set()
+    def __GetTERules(self, policydbP, avtabIterP, Rules):
+        if Rules is None:
+            Rules = set()
         buf = create_string_buffer(self.__BUFSIZE)
         ret = 0
         while True:
@@ -165,7 +219,7 @@ class Policy:
                         policydbP, avtabIterP)
             if ret == 0:
                 Rule = TERule(buf.value)
-                self.__Rules.add(Rule)
+                Rules.add(Rule)
                 continue
             if ret == 1:
                 break;
@@ -176,14 +230,26 @@ class Policy:
         avtabIterP = self.__libsepolwrap.init_avtab(self.__policydbP)
         if (avtabIterP == None):
             sys.exit("Failed to initialize avtab")
-        self.__GetTERules(self.__policydbP, avtabIterP)
+        self.__GetTERules(self.__policydbP, avtabIterP, self.__Rules)
         self.__libsepolwrap.destroy_avtab(avtabIterP)
         avtabIterP = self.__libsepolwrap.init_cond_avtab(self.__policydbP)
         if (avtabIterP == None):
             sys.exit("Failed to initialize conditional avtab")
-        self.__GetTERules(self.__policydbP, avtabIterP)
+        self.__GetTERules(self.__policydbP, avtabIterP, self.__Rules)
         self.__libsepolwrap.destroy_avtab(avtabIterP)
 
+    def __InitExpandedTERules(self):
+        avtabIterP = self.__libsepolwrap.init_expanded_avtab(self.__policydbP)
+        if (avtabIterP == None):
+            sys.exit("Failed to initialize avtab")
+        self.__GetTERules(self.__policydbP, avtabIterP, self.__ExpandedRules)
+        self.__libsepolwrap.destroy_expanded_avtab(avtabIterP)
+        avtabIterP = self.__libsepolwrap.init_expanded_cond_avtab(self.__policydbP)
+        if (avtabIterP == None):
+            sys.exit("Failed to initialize conditional avtab")
+        self.__GetTERules(self.__policydbP, avtabIterP, self.__ExpandedRules)
+        self.__libsepolwrap.destroy_expanded_avtab(avtabIterP)
+
     # load ctypes-ified libsepol wrapper
     def __InitLibsepolwrap(self, LibPath):
         if "linux" in sys.platform:
@@ -201,6 +267,14 @@ class Policy:
         lib.load_policy.argtypes = [c_char_p]
         # void destroy_policy(void *policydbp);
         lib.destroy_policy.argtypes = [c_void_p]
+        # void *init_expanded_avtab(void *policydbp);
+        lib.init_expanded_avtab.restype = c_void_p
+        lib.init_expanded_avtab.argtypes = [c_void_p]
+        # void *init_expanded_cond_avtab(void *policydbp);
+        lib.init_expanded_cond_avtab.restype = c_void_p
+        lib.init_expanded_cond_avtab.argtypes = [c_void_p]
+        # void destroy_expanded_avtab(void *avtab_iterp);
+        lib.destroy_expanded_avtab.argtypes = [c_void_p]
         # void *init_avtab(void *policydbp);
         lib.init_avtab.restype = c_void_p
         lib.init_avtab.argtypes = [c_void_p]
diff --git a/tests/searchpolicy.py b/tests/searchpolicy.py
new file mode 100644
index 000000000..ff9318b7f
--- /dev/null
+++ b/tests/searchpolicy.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+
+import argparse
+import policy
+
+parser = argparse.ArgumentParser(
+    description="SELinux policy rule search tool. Intended to have a similar "
+        + "API as sesearch, but simplified to use only code availabe in AOSP")
+parser.add_argument("policy", help="Path to the SELinux policy to search.", nargs="?")
+parser.add_argument("--libpath", dest="libpath", help="Path to the libsepolwrap.so", nargs="?")
+tertypes = parser.add_argument_group("TE Rule Types")
+tertypes.add_argument("--allow", action="append_const",
+                    const="allow", dest="tertypes",
+                    help="Search allow rules.")
+expr = parser.add_argument_group("Expressions")
+expr.add_argument("-s", "--source",
+                  help="Source type/role of the TE/RBAC rule.")
+expr.add_argument("-t", "--target",
+                  help="Target type/role of the TE/RBAC rule.")
+expr.add_argument("-c", "--class", dest="tclass",
+                  help="Comma separated list of object classes")
+expr.add_argument("-p", "--perms", metavar="PERMS",
+                  help="Comma separated list of permissions.")
+
+args = parser.parse_args()
+
+if not args.tertypes:
+    parser.error("Must specify \"--allow\"")
+
+if not args.policy:
+    parser.error("Must include path to policy")
+if not args.libpath:
+    parser.error("Must include path to libsepolwrap library")
+
+if not (args.source or args.target or args.tclass or args.perms):
+    parser.error("Must something to filter on, e.g. --source, --target, etc.")
+
+pol = policy.Policy(args.policy, None, args.libpath)
+
+if args.source:
+    scontext = {args.source}
+else:
+    scontext = set()
+if args.target:
+    tcontext = {args.target}
+else:
+    tcontext = set()
+if args.tclass:
+    tclass = set(args.tclass.split(","))
+else:
+    tclass = set()
+if args.perms:
+    perms = set(args.perms.split(","))
+else:
+    perms = set()
+
+TERules = pol.QueryTERule(scontext=scontext,
+                       tcontext=tcontext,
+                       tclass=tclass,
+                       perms=perms)
+
+# format rules for printing
+rules = []
+for r in TERules:
+    if len(r.perms) > 1:
+        rules.append("allow " + r.sctx + " " + r.tctx + ":" + r.tclass + " { " +
+                " ".join(r.perms) + " };")
+    else:
+        rules.append("allow " + r.sctx + " " + r.tctx + ":" + r.tclass + " " +
+                " ".join(r.perms) + ";")
+
+for r in sorted(rules):
+    print r
diff --git a/tests/sepol_wrap.cpp b/tests/sepol_wrap.cpp
index 8fea2d5b4..d537b7e00 100644
--- a/tests/sepol_wrap.cpp
+++ b/tests/sepol_wrap.cpp
@@ -181,7 +181,7 @@ void *load_policy(const char *policy_path)
 
 /* items needed to iterate over the avtab */
 struct avtab_iter {
-    avtab_t avtab;
+    avtab_t *avtab;
     uint32_t i;
     avtab_ptr_t cur;
 };
@@ -198,9 +198,9 @@ static int get_avtab_allow_rule(char *out, size_t max_size, policydb_t *db,
 {
     size_t len;
 
-    for (; avtab_i->i < avtab_i->avtab.nslot; (avtab_i->i)++) {
+    for (; avtab_i->i < avtab_i->avtab->nslot; (avtab_i->i)++) {
         if (avtab_i->cur == NULL) {
-            avtab_i->cur = avtab_i->avtab.htable[avtab_i->i];
+            avtab_i->cur = avtab_i->avtab->htable[avtab_i->i];
         }
         for (; avtab_i->cur; avtab_i->cur = (avtab_i->cur)->next) {
             if (!((avtab_i->cur)->key.specified & AVTAB_ALLOWED)) continue;
@@ -233,6 +233,37 @@ int get_allow_rule(char *out, size_t len, void *policydbp, void *avtab_iterp)
     return get_avtab_allow_rule(out, len, db, avtab_i);
 }
 
+static avtab_iter *init_avtab_common(avtab_t *in)
+{
+    struct avtab_iter *out = (struct avtab_iter *)
+                            calloc(1, sizeof(struct avtab_iter));
+    if (!out) {
+        std::cerr << "Failed to allocate avtab iterator" << std::endl;
+        return NULL;
+    }
+
+    out->avtab = in;
+    return out;
+}
+
+void *init_avtab(void *policydbp)
+{
+    policydb_t *p = static_cast<policydb_t *>(policydbp);
+    return static_cast<void *>(init_avtab_common(&p->te_avtab));
+}
+
+void *init_cond_avtab(void *policydbp)
+{
+    policydb_t *p = static_cast<policydb_t *>(policydbp);
+    return static_cast<void *>(init_avtab_common(&p->te_cond_avtab));
+}
+
+void destroy_avtab(void *avtab_iterp)
+{
+    struct avtab_iter *avtab_i = static_cast<struct avtab_iter *>(avtab_iterp);
+    free(avtab_i);
+}
+
 /*
  * <sepol/policydb/expand.h->conditional.h> uses 'bool' as a variable name
  * inside extern "C" { .. } construct, which clang doesn't like.
@@ -240,45 +271,57 @@ int get_allow_rule(char *out, size_t len, void *policydbp, void *avtab_iterp)
  */
 extern "C" int expand_avtab(policydb_t *p, avtab_t *a, avtab_t *expa);
 
-static avtab_iter *init_avtab_common(avtab_t *in, policydb_t *p)
+static avtab_iter *init_expanded_avtab_common(avtab_t *in, policydb_t *p)
 {
     struct avtab_iter *out = (struct avtab_iter *)
                             calloc(1, sizeof(struct avtab_iter));
     if (!out) {
+        std::cerr << "Failed to allocate avtab iterator" << std::endl;
+        return NULL;
+    }
+
+    avtab_t *avtab = (avtab_t *) calloc(1, sizeof(avtab_t));
+
+    if (!avtab) {
         std::cerr << "Failed to allocate avtab" << std::endl;
+        free(out);
         return NULL;
     }
 
-    if (avtab_init(&out->avtab)) {
+    out->avtab = avtab;
+    if (avtab_init(out->avtab)) {
         std::cerr << "Failed to initialize avtab" << std::endl;
+        free(avtab);
         free(out);
         return NULL;
     }
 
-    if (expand_avtab(p, in, &out->avtab)) {
+    if (expand_avtab(p, in, out->avtab)) {
         std::cerr << "Failed to expand avtab" << std::endl;
+        free(avtab);
         free(out);
         return NULL;
     }
     return out;
 }
 
-void *init_avtab(void *policydbp)
+void *init_expanded_avtab(void *policydbp)
 {
     policydb_t *p = static_cast<policydb_t *>(policydbp);
-    return static_cast<void *>(init_avtab_common(&p->te_avtab, p));
+    return static_cast<void *>(init_expanded_avtab_common(&p->te_avtab, p));
 }
 
-void *init_cond_avtab(void *policydbp)
+void *init_expanded_cond_avtab(void *policydbp)
 {
     policydb_t *p = static_cast<policydb_t *>(policydbp);
-    return static_cast<void *>(init_avtab_common(&p->te_cond_avtab, p));
+    return static_cast<void *>(init_expanded_avtab_common(&p->te_cond_avtab, p));
 }
 
-void destroy_avtab(void *avtab_iterp)
+void destroy_expanded_avtab(void *avtab_iterp)
 {
     struct avtab_iter *avtab_i = static_cast<struct avtab_iter *>(avtab_iterp);
-    avtab_destroy(&avtab_i->avtab);
+    avtab_destroy(avtab_i->avtab);
+    free(avtab_i->avtab);
     free(avtab_i);
 }
 
diff --git a/tests/treble_sepolicy_tests.py b/tests/treble_sepolicy_tests.py
index 58fd85bc3..2c0cef378 100644
--- a/tests/treble_sepolicy_tests.py
+++ b/tests/treble_sepolicy_tests.py
@@ -76,6 +76,9 @@ alltypes = set()
 oldalltypes = set()
 compatMapping = None
 
+# Distinguish between PRODUCT_FULL_TREBLE and PRODUCT_FULL_TREBLE_OVERRIDE
+FakeTreble = False
+
 def GetAllDomains(pol):
     global alldomains
     for result in pol.QueryTypeAttribute("domain", True):
@@ -129,7 +132,7 @@ def GetCoreDomains():
 #
 def GetDomainEntrypoints(pol):
     global alldomains
-    for x in pol.QueryTERule(tclass="file", perms=["entrypoint"]):
+    for x in pol.QueryExpandedTERule(tclass=set(["file"]), perms=set(["entrypoint"])):
         if not x.sctx in alldomains:
             continue
         alldomains[x.sctx].entrypoints.append(str(x.tctx))
@@ -172,6 +175,14 @@ def compatSetup(pol, oldpol, mapping):
     GetAllTypes(pol, oldpol)
     compatMapping = mapping
 
+def DomainsWithAttribute(attr):
+    global alldomains
+    domains = []
+    for domain in alldomains:
+        if attr in alldomains[domain].attributes:
+            domains.append(domain)
+    return domains
+
 #############################################################
 # Tests
 #############################################################
@@ -255,6 +266,26 @@ def TestTrebleCompatMapping():
     ret = TestNoUnmappedNewTypes()
     ret += TestNoUnmappedRmTypes()
     return ret
+
+def TestViolatorAttribute(attribute):
+    global FakeTreble
+    ret = ""
+    if FakeTreble:
+        return ret
+
+    violators = DomainsWithAttribute(attribute)
+    if len(violators) > 0:
+        ret += "SELinux: The following domains violate the Treble ban "
+        ret += "against use of the " + attribute + " attribute: "
+        ret += " ".join(str(x) for x in sorted(violators)) + "\n"
+    return ret
+
+def TestViolatorAttributes():
+    ret = TestViolatorAttribute("binder_in_vendor_violators")
+    ret += TestViolatorAttribute("socket_between_core_and_vendor_violators")
+    ret += TestViolatorAttribute("vendor_executes_system_violators")
+    return ret
+
 ###
 # extend OptionParser to allow the same option flag to be used multiple times.
 # This is used to allow multiple file_contexts files and tests to be
@@ -273,11 +304,13 @@ class MultipleOption(Option):
             Option.take_action(self, action, dest, opt, value, values, parser)
 
 Tests = {"CoredomainViolations": TestCoredomainViolations,
-         "TrebleCompatMapping": TestTrebleCompatMapping }
+         "TrebleCompatMapping": TestTrebleCompatMapping,
+         "ViolatorAttributes": TestViolatorAttributes}
 
 if __name__ == '__main__':
-    usage = "treble_sepolicy_tests.py -f nonplat_file_contexts -f "
-    usage +="plat_file_contexts -p curr_policy -b base_policy -o old_policy "
+    usage = "treble_sepolicy_tests.py -l out/host/linux-x86/lib64 "
+    usage += "-f nonplat_file_contexts -f plat_file_contexts "
+    usage += "-p curr_policy -b base_policy -o old_policy "
     usage +="-m mapping file [--test test] [--help]"
     parser = OptionParser(option_class=MultipleOption, usage=usage)
     parser.add_option("-b", "--basepolicy", dest="basepolicy", metavar="FILE")
@@ -288,8 +321,9 @@ if __name__ == '__main__':
     parser.add_option("-o", "--oldpolicy", dest="oldpolicy", metavar="FILE")
     parser.add_option("-p", "--policy", dest="policy", metavar="FILE")
     parser.add_option("-t", "--test", dest="tests", action="extend",
-
             help="Test options include "+str(Tests))
+    parser.add_option("--fake-treble", action="store_true", dest="faketreble",
+            default=False)
 
     (options, args) = parser.parse_args()
 
@@ -317,6 +351,9 @@ if __name__ == '__main__':
             sys.exit("Error: File_contexts file " + f + " does not exist\n" +
                     parser.usage)
 
+    if options.faketreble:
+        FakeTreble = True
+
     pol = policy.Policy(options.policy, options.file_contexts, options.libpath)
     setup(pol)
     basepol = policy.Policy(options.basepolicy, None, options.libpath)
diff --git a/vendor/file_contexts b/vendor/file_contexts
index 8d68d9fb9..1efbe73d0 100644
--- a/vendor/file_contexts
+++ b/vendor/file_contexts
@@ -20,6 +20,7 @@
 /(vendor|system/vendor)/bin/hw/android\.hardware\.ir@1\.0-service             u:object_r:hal_ir_default_exec:s0
 /(vendor|system/vendor)/bin/hw/android\.hardware\.keymaster@3\.0-service      u:object_r:hal_keymaster_default_exec:s0
 /(vendor|system/vendor)/bin/hw/android\.hardware\.light@2\.0-service          u:object_r:hal_light_default_exec:s0
+/(vendor|system/vendor)/bin/hw/android\.hardware\.lowpan@1\.0-service         u:object_r:hal_lowpan_default_exec:s0
 /(vendor|system/vendor)/bin/hw/android\.hardware\.memtrack@1\.0-service       u:object_r:hal_memtrack_default_exec:s0
 /(vendor|system/vendor)/bin/hw/android\.hardware\.nfc@1\.0-service            u:object_r:hal_nfc_default_exec:s0
 /(vendor|system/vendor)/bin/hw/android\.hardware\.media\.omx@1\.0-service            u:object_r:mediacodec_exec:s0
diff --git a/vendor/hal_lowpan_default.te b/vendor/hal_lowpan_default.te
new file mode 100644
index 000000000..a49bf243f
--- /dev/null
+++ b/vendor/hal_lowpan_default.te
@@ -0,0 +1,5 @@
+type hal_lowpan_default, domain;
+type hal_lowpan_default_exec, exec_type, vendor_file_type, file_type;
+
+hal_server_domain(hal_lowpan_default, hal_lowpan)
+init_daemon_domain(hal_lowpan_default)
-- 
GitLab