Merge "Add missing sepolicies for OemLock HAL." into oc-dev am: 60e4fd9dfa
am: 39a81fd517
Change-Id: I0e7a02ff77ef0e6490a481229e042145c9dfb89a
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..9952a8f
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1 @@
+subdirs = ["tests"]
diff --git a/private/app.te b/private/app.te
index 5d3c722..74675ed 100644
--- a/private/app.te
+++ b/private/app.te
@@ -342,6 +342,9 @@
allow appdomain cache_file:dir getattr;
+# Allow apps to run with asanwrapper.
+with_asan(`allow appdomain asanwrapper_exec:file rx_file_perms;')
+
###
### Neverallow rules
###
@@ -491,7 +494,6 @@
neverallow appdomain kernel:system { syslog_read syslog_mod syslog_console };
# SELinux is not an API for apps to use
-neverallow { appdomain -shell } selinuxfs:file no_rw_file_perms;
neverallow { appdomain -shell } *:security { compute_av check_context };
neverallow { appdomain -shell } *:netlink_selinux_socket *;
diff --git a/private/app_neverallows.te b/private/app_neverallows.te
index 9c762a1..9277d41 100644
--- a/private/app_neverallows.te
+++ b/private/app_neverallows.te
@@ -166,6 +166,9 @@
-hidl_token_hwservice # Designed for use by any domain
}:hwservice_manager find;
+# SELinux is not an API for untrusted apps to use
+neverallow all_untrusted_apps selinuxfs:file no_rw_file_perms;
+
# Restrict *Binder access from apps to HAL domains. We can only do this on full
# Treble devices where *Binder communications between apps and HALs are tightly
# restricted.
diff --git a/private/e2fs.te b/private/e2fs.te
new file mode 100644
index 0000000..add1cc2
--- /dev/null
+++ b/private/e2fs.te
@@ -0,0 +1,14 @@
+type e2fs, domain, coredomain;
+
+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;
+
+# access /sys/fs/ext4/features
+allow e2fs sysfs_fs_ext4_features:file r_file_perms;
+
+# access sselinux context files
+allow e2fs file_contexts_file:file { getattr open read };
diff --git a/private/file_contexts b/private/file_contexts
index d211bd8..691605a 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -17,6 +17,8 @@
/charger u:object_r:rootfs:s0
/init u:object_r:init_exec:s0
/sbin(/.*)? u:object_r:rootfs:s0
+/sbin/e2fsdroid u:object_r:e2fs_exec:s0
+/sbin/mke2fs u:object_r:e2fs_exec:s0
# For kernel modules
/lib(/.*)? u:object_r:rootfs:s0
@@ -459,6 +461,7 @@
/sys/devices/virtual/block/zram\d+(/.*)? u:object_r:sysfs_zram:s0
/sys/devices/virtual/block/zram\d+/uevent u:object_r:sysfs_zram_uevent:s0
/sys/devices/virtual/misc/hw_random(/.*)? u:object_r:sysfs_hwrandom:s0
+/sys/fs/ext4/features(/.*)? u:object_r:sysfs_fs_ext4_features:s0
/sys/power/wake_lock -- u:object_r:sysfs_wake_lock:s0
/sys/power/wake_unlock -- u:object_r:sysfs_wake_lock:s0
/sys/kernel/uevent_helper -- u:object_r:usermodehelper:s0
@@ -493,6 +496,7 @@
/sys/kernel(/debug)?/tracing/events/vmscan/mm_vmscan_direct_reclaim_end/enable u:object_r:tracing_shell_writable:s0
/sys/kernel(/debug)?/tracing/events/vmscan/mm_vmscan_kswapd_sleep/enable u:object_r:tracing_shell_writable:s0
/sys/kernel(/debug)?/tracing/events/vmscan/mm_vmscan_kswapd_wake/enable u:object_r:tracing_shell_writable:s0
+/sys/kernel(/debug)?/tracing/events/lowmemorykiller/enable u:object_r:tracing_shell_writable:s0
/sys/kernel(/debug)?/tracing/instances(/.*)? u:object_r:debugfs_tracing_instances:s0
/sys/kernel(/debug)?/tracing/instances/wifi/free_buffer u:object_r:debugfs_wifi_tracing:s0
/sys/kernel(/debug)?/tracing/instances/wifi/trace u:object_r:debugfs_wifi_tracing:s0
diff --git a/private/file_contexts_asan b/private/file_contexts_asan
index d35cd3c..0401ffe 100644
--- a/private/file_contexts_asan
+++ b/private/file_contexts_asan
@@ -3,3 +3,7 @@
/data/asan/vendor/lib(/.*)? u:object_r:system_file:s0
/data/asan/vendor/lib64(/.*)? u:object_r:system_file:s0
/system/bin/asan_extract u:object_r:asan_extract_exec:s0
+/system/bin/asanwrapper u:object_r:asanwrapper_exec:s0
+/system/bin/asan/app_process u:object_r:zygote_exec:s0
+/system/bin/asan/app_process32 u:object_r:zygote_exec:s0
+/system/bin/asan/app_process64 u:object_r:zygote_exec:s0
diff --git a/private/hwservice_contexts b/private/hwservice_contexts
index 0516364..397a3b1 100644
--- a/private/hwservice_contexts
+++ b/private/hwservice_contexts
@@ -42,6 +42,7 @@
android.hardware.vr::IVr u:object_r:hal_vr_hwservice:s0
android.hardware.weaver::IWeaver u:object_r:hal_weaver_hwservice:s0
android.hardware.wifi::IWifi u:object_r:hal_wifi_hwservice:s0
+android.hardware.wifi.offload::IOffload u:object_r:hal_wifi_offload_hwservice:s0
android.hardware.wifi.supplicant::ISupplicant u:object_r:hal_wifi_supplicant_hwservice:s0
android.hidl.allocator::IAllocator u:object_r:hidl_allocator_hwservice:s0
android.hidl.base::IBase u:object_r:hidl_base_hwservice:s0
diff --git a/private/init.te b/private/init.te
index b6c49b9..afbd878 100644
--- a/private/init.te
+++ b/private/init.te
@@ -7,6 +7,7 @@
domain_trans(init, rootfs, charger)
domain_trans(init, rootfs, healthd)
domain_trans(init, rootfs, slideshow)
+domain_auto_trans(init, e2fs_exec, e2fs)
recovery_only(`
domain_trans(init, rootfs, recovery)
')
diff --git a/private/isolated_app.te b/private/isolated_app.te
index 418a322..ac9dc04 100644
--- a/private/isolated_app.te
+++ b/private/isolated_app.te
@@ -62,6 +62,17 @@
neverallow isolated_app anr_data_file:file ~{ open append };
neverallow isolated_app anr_data_file:dir ~search;
+# Isolated apps must not be permitted to use HwBinder
+neverallow isolated_app hwbinder_device:chr_file *;
+neverallow isolated_app *:hwservice_manager *;
+
+# Isolated apps must not be permitted to use VndBinder
+neverallow isolated_app vndbinder_device:chr_file *;
+
+# Isolated apps must not be permitted to perform actions on Binder and VndBinder service_manager
+# except the find actions for services whitelisted below.
+neverallow isolated_app *:service_manager ~find;
+
# b/17487348
# Isolated apps can only access three services,
# activity_service, display_service and webviewupdate_service.
diff --git a/private/priv_app.te b/private/priv_app.te
index 109c869..9603180 100644
--- a/private/priv_app.te
+++ b/private/priv_app.te
@@ -108,6 +108,9 @@
# Allow privileged apps (e.g. GMS core) to generate unique hardware IDs
allow priv_app keystore:keystore_key gen_unique_id;
+# Allow GMS core to access /sys/fs/selinux/policyvers for compatibility check
+allow priv_app selinuxfs:file r_file_perms;
+
read_runtime_log_tags(priv_app)
###
diff --git a/private/property_contexts b/private/property_contexts
index 4c27b35..2315034 100644
--- a/private/property_contexts
+++ b/private/property_contexts
@@ -111,6 +111,3 @@
# hwservicemanager properties
hwservicemanager. u:object_r:hwservicemanager_prop:s0
-
-# ASAN install trigger
-asan.restore_reboot u:object_r:asan_reboot_prop:s0
diff --git a/private/system_server.te b/private/system_server.te
index 5963103..2bfd4cd 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -17,11 +17,11 @@
# For art.
allow system_server dalvikcache_data_file:dir r_dir_perms;
-allow system_server dalvikcache_data_file:file { r_file_perms execute };
-userdebug_or_eng(`
- # Report dalvikcache_data_file:file execute violations.
- auditallow system_server dalvikcache_data_file:file execute;
-')
+allow system_server dalvikcache_data_file:file r_file_perms;
+
+# When running system server under --invoke-with, we'll try to load the boot image under the
+# system server domain, following links to the system partition.
+with_asan(`allow system_server dalvikcache_data_file:lnk_file r_file_perms;')
# /data/resource-cache
allow system_server resourcecache_data_file:file r_file_perms;
@@ -675,10 +675,12 @@
allow system_server debugfs_tracing_instances:dir search;
allow system_server debugfs_wifi_tracing:file rw_file_perms;
-# allow system_server to exec shell on ASAN builds. Needed to run
+# allow system_server to exec shell, asanwrapper & zygote(app_process) on ASAN builds. Needed to run
# asanwrapper.
with_asan(`
allow system_server shell_exec:file rx_file_perms;
+ allow system_server asanwrapper_exec:file rx_file_perms;
+ allow system_server zygote_exec:file rx_file_perms;
')
###
@@ -706,7 +708,7 @@
file_type
-toolbox_exec
-logcat_exec
- with_asan(`-shell_exec')
+ with_asan(`-shell_exec -asanwrapper_exec -zygote_exec')
}:file execute_no_trans;
# Ensure that system_server doesn't perform any domain transitions other than
diff --git a/public/asan_extract.te b/public/asan_extract.te
index 6d0de6c..46b7557 100644
--- a/public/asan_extract.te
+++ b/public/asan_extract.te
@@ -31,6 +31,10 @@
# Restorecon will actually already try to run with sanitized libraries (libpackagelistparser).
allow asan_extract system_data_file:file execute;
+ # TODO - remove (b/38241921):
# We use asan.restore_reboot to signal a reboot is required.
set_prop(asan_extract, asan_reboot_prop)
+
+ # We need to signal a reboot when done
+ set_prop(asan_extract, powerctl_prop)
')
diff --git a/public/attributes b/public/attributes
index 90740d4..2b28cf0 100644
--- a/public/attributes
+++ b/public/attributes
@@ -160,116 +160,225 @@
attribute halserverdomain;
# All HAL clients
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 true;
attribute hal_audio;
+expandattribute hal_audio true;
attribute hal_audio_client;
+expandattribute hal_audio_client true;
attribute hal_audio_server;
+expandattribute hal_audio_server true;
attribute hal_bluetooth;
+expandattribute hal_bluetooth true;
attribute hal_bluetooth_client;
+expandattribute hal_bluetooth_client true;
attribute hal_bluetooth_server;
+expandattribute hal_bluetooth_server true;
attribute hal_bootctl;
+expandattribute hal_bootctl true;
attribute hal_bootctl_client;
+expandattribute hal_bootctl_client true;
attribute hal_bootctl_server;
+expandattribute hal_bootctl_server true;
attribute hal_camera;
+expandattribute hal_camera true;
attribute hal_camera_client;
+expandattribute hal_camera_client true;
attribute hal_camera_server;
+expandattribute hal_camera_server true;
attribute hal_configstore;
+expandattribute hal_configstore true;
attribute hal_configstore_client;
+expandattribute hal_configstore_client true;
attribute hal_configstore_server;
+expandattribute hal_configstore_server true;
attribute hal_contexthub;
+expandattribute hal_contexthub true;
attribute hal_contexthub_client;
+expandattribute hal_contexthub_client true;
attribute hal_contexthub_server;
+expandattribute hal_contexthub_server true;
attribute hal_drm;
+expandattribute hal_drm true;
attribute hal_drm_client;
+expandattribute hal_drm_client true;
attribute hal_drm_server;
+expandattribute hal_drm_server true;
attribute hal_dumpstate;
+expandattribute hal_dumpstate true;
attribute hal_dumpstate_client;
+expandattribute hal_dumpstate_client true;
attribute hal_dumpstate_server;
+expandattribute hal_dumpstate_server true;
attribute hal_fingerprint;
+expandattribute hal_fingerprint true;
attribute hal_fingerprint_client;
+expandattribute hal_fingerprint_client true;
attribute hal_fingerprint_server;
+expandattribute hal_fingerprint_server true;
attribute hal_gatekeeper;
+expandattribute hal_gatekeeper true;
attribute hal_gatekeeper_client;
+expandattribute hal_gatekeeper_client true;
attribute hal_gatekeeper_server;
+expandattribute hal_gatekeeper_server true;
attribute hal_gnss;
+expandattribute hal_gnss true;
attribute hal_gnss_client;
+expandattribute hal_gnss_client true;
attribute hal_gnss_server;
+expandattribute hal_gnss_server true;
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 true;
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 true;
attribute hal_health;
+expandattribute hal_health true;
attribute hal_health_client;
+expandattribute hal_health_client true;
attribute hal_health_server;
+expandattribute hal_health_server true;
attribute hal_ir;
+expandattribute hal_ir true;
attribute hal_ir_client;
+expandattribute hal_ir_client true;
attribute hal_ir_server;
+expandattribute hal_ir_server true;
attribute hal_keymaster;
+expandattribute hal_keymaster true;
attribute hal_keymaster_client;
+expandattribute hal_keymaster_client true;
attribute hal_keymaster_server;
+expandattribute hal_keymaster_server true;
attribute hal_light;
+expandattribute hal_light true;
attribute hal_light_client;
+expandattribute hal_light_client true;
attribute hal_light_server;
+expandattribute hal_light_server true;
attribute hal_memtrack;
+expandattribute hal_memtrack true;
attribute hal_memtrack_client;
+expandattribute hal_memtrack_client true;
attribute hal_memtrack_server;
+expandattribute hal_memtrack_server true;
attribute hal_nfc;
+expandattribute hal_nfc true;
attribute hal_nfc_client;
+expandattribute hal_nfc_client true;
attribute hal_nfc_server;
+expandattribute hal_nfc_server true;
attribute hal_oemlock;
+expandattribute hal_oemlock true;
attribute hal_oemlock_client;
+expandattribute hal_oemlock_client true;
attribute hal_oemlock_server;
+expandattribute hal_oemlock_server true;
attribute hal_power;
+expandattribute hal_power true;
attribute hal_power_client;
+expandattribute hal_power_client true;
attribute hal_power_server;
+expandattribute hal_power_server true;
attribute hal_sensors;
+expandattribute hal_sensors true;
attribute hal_sensors_client;
+expandattribute hal_sensors_client true;
attribute hal_sensors_server;
+expandattribute hal_sensors_server true;
attribute hal_telephony;
+expandattribute hal_telephony true;
attribute hal_telephony_client;
+expandattribute hal_telephony_client true;
attribute hal_telephony_server;
+expandattribute hal_telephony_server true;
attribute hal_tetheroffload;
+expandattribute hal_tetheroffload true;
attribute hal_tetheroffload_client;
+expandattribute hal_tetheroffload_client true;
attribute hal_tetheroffload_server;
+expandattribute hal_tetheroffload_server true;
attribute hal_thermal;
+expandattribute hal_thermal true;
attribute hal_thermal_client;
+expandattribute hal_thermal_client true;
attribute hal_thermal_server;
+expandattribute hal_thermal_server true;
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 true;
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 true;
attribute hal_usb;
+expandattribute hal_usb true;
attribute hal_usb_client;
+expandattribute hal_usb_client true;
attribute hal_usb_server;
+expandattribute hal_usb_server true;
attribute hal_vibrator;
+expandattribute hal_vibrator true;
attribute hal_vibrator_client;
+expandattribute hal_vibrator_client true;
attribute hal_vibrator_server;
+expandattribute hal_vibrator_server true;
attribute hal_vr;
+expandattribute hal_vr true;
attribute hal_vr_client;
+expandattribute hal_vr_client true;
attribute hal_vr_server;
+expandattribute hal_vr_server true;
attribute hal_weaver;
+expandattribute hal_weaver true;
attribute hal_weaver_client;
+expandattribute hal_weaver_client true;
attribute hal_weaver_server;
+expandattribute hal_weaver_server true;
attribute hal_wifi;
+expandattribute hal_wifi true;
attribute hal_wifi_client;
+expandattribute hal_wifi_client true;
attribute hal_wifi_server;
+expandattribute hal_wifi_server true;
attribute hal_wifi_keystore;
+expandattribute hal_wifi_keystore true;
attribute hal_wifi_keystore_client;
+expandattribute hal_wifi_keystore_client true;
attribute hal_wifi_keystore_server;
+expandattribute hal_wifi_keystore_server true;
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 true;
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 true;
# HwBinder services offered across the core-vendor boundary
#
diff --git a/public/domain.te b/public/domain.te
index 8eb8936..ea63d1c 100644
--- a/public/domain.te
+++ b/public/domain.te
@@ -75,7 +75,7 @@
} binder_device:chr_file rw_file_perms;
# Devices which are not full TREBLE have fewer restrictions on access to /dev/binder
not_full_treble(`allow { domain -hwservicemanager -vndservicemanager } binder_device:chr_file rw_file_perms;')
-allow { domain -servicemanager -vndservicemanager } hwbinder_device:chr_file rw_file_perms;
+allow { domain -servicemanager -vndservicemanager -isolated_app } 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 random_device:chr_file rw_file_perms;
@@ -219,6 +219,9 @@
# when it's not explicitly used in allow rules
allow { domain -domain } vndservice_manager_type:service_manager { add find };
+# Under ASAN, processes will try to read /data, as the sanitized libraries are there.
+with_asan(`allow domain system_data_file:dir getattr;')
+
###
### neverallow rules
###
@@ -352,7 +355,6 @@
-dumpstate
-shell
userdebug_or_eng(`-su')
- -system_server
-webview_zygote
-zygote
} {
diff --git a/public/e2fs.te b/public/e2fs.te
new file mode 100644
index 0000000..ecb25a2
--- /dev/null
+++ b/public/e2fs.te
@@ -0,0 +1 @@
+type e2fs_exec, exec_type, file_type;
diff --git a/public/file.te b/public/file.te
index ad978e8..bf8223a 100644
--- a/public/file.te
+++ b/public/file.te
@@ -41,6 +41,7 @@
type sysfs_wake_lock, fs_type, sysfs_type;
type sysfs_mac_address, fs_type, sysfs_type;
type sysfs_usb, sysfs_type, file_type, mlstrustedobject;
+type sysfs_fs_ext4_features, sysfs_type, fs_type;
type configfs, fs_type;
# /sys/devices/system/cpu
type sysfs_devices_system_cpu, fs_type, sysfs_type;
@@ -328,6 +329,9 @@
allow app_fuse_file app_fusefs:filesystem associate;
allow postinstall_file self:filesystem associate;
+# asanwrapper (run a sanitized app_process, to be used with wrap properties)
+with_asan(`type asanwrapper_exec, exec_type, file_type;')
+
# It's a bug to assign the file_type attribute and fs_type attribute
# to any type. Do not allow it.
#
diff --git a/public/hal_wifi_offload.te b/public/hal_wifi_offload.te
index dac5171..dc0cf5a 100644
--- a/public/hal_wifi_offload.te
+++ b/public/hal_wifi_offload.te
@@ -2,5 +2,8 @@
binder_call(hal_wifi_offload_client, hal_wifi_offload_server)
binder_call(hal_wifi_offload_server, hal_wifi_offload_client)
+add_hwservice(hal_wifi_offload_server, hal_wifi_offload_hwservice)
+allow hal_wifi_offload_client hal_wifi_offload_hwservice:hwservice_manager find;
+
r_dir_file(hal_wifi_offload, proc_net)
r_dir_file(hal_wifi_offload, sysfs_type)
diff --git a/public/hwservice.te b/public/hwservice.te
index 65c52a2..c3f3077 100644
--- a/public/hwservice.te
+++ b/public/hwservice.te
@@ -36,6 +36,7 @@
type hal_vr_hwservice, hwservice_manager_type;
type hal_weaver_hwservice, hwservice_manager_type;
type hal_wifi_hwservice, hwservice_manager_type;
+type hal_wifi_offload_hwservice, hwservice_manager_type;
type hal_wifi_supplicant_hwservice, hwservice_manager_type;
type hidl_allocator_hwservice, hwservice_manager_type, coredomain_hwservice;
type hidl_base_hwservice, hwservice_manager_type;
diff --git a/public/property.te b/public/property.te
index d6fa868..c633dab 100644
--- a/public/property.te
+++ b/public/property.te
@@ -1,4 +1,4 @@
-type asan_reboot_prop, property_type;
+type asan_reboot_prop, property_type; # TODO - remove (b/38241921)
type audio_prop, property_type, core_property_type;
type boottime_prop, property_type;
type bluetooth_prop, property_type;
diff --git a/public/recovery.te b/public/recovery.te
index 6e211ac..99d792c 100644
--- a/public/recovery.te
+++ b/public/recovery.te
@@ -75,6 +75,9 @@
allow recovery functionfs:dir search;
allow recovery functionfs:file rw_file_perms;
+ # Access to /sys/fs/selinux/policyvers for compatibility check
+ allow recovery selinuxfs:file r_file_perms;
+
# Required to e.g. wipe userdata/cache.
allow recovery device:dir r_dir_perms;
allow recovery block_device:dir r_dir_perms;
diff --git a/public/ueventd.te b/public/ueventd.te
index 4c77e11..da2695f 100644
--- a/public/ueventd.te
+++ b/public/ueventd.te
@@ -30,7 +30,7 @@
r_dir_file(ueventd, selinuxfs)
# Access for /vendor/ueventd.rc and /vendor/firmware
-r_dir_file(ueventd, vendor_file)
+r_dir_file(ueventd, { vendor_file_type -vendor_app_file -vendor_overlay_file })
# Get file contexts for new device nodes
allow ueventd file_contexts_file:file r_file_perms;
diff --git a/tests/Android.bp b/tests/Android.bp
new file mode 100644
index 0000000..87afab8
--- /dev/null
+++ b/tests/Android.bp
@@ -0,0 +1,7 @@
+cc_library_host_shared {
+ name: "libsepolwrap",
+ srcs: ["sepol_wrap.cpp"],
+ shared_libs: ["libbase", "libsepol"],
+ cflags: ["-Wall", "-Werror",],
+ export_include_dirs: ["include"],
+}
diff --git a/tests/include/sepol_wrap.h b/tests/include/sepol_wrap.h
new file mode 100644
index 0000000..0683a3b
--- /dev/null
+++ b/tests/include/sepol_wrap.h
@@ -0,0 +1,20 @@
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int get_allow_rule(char *out, size_t len, void *policydbp, void *avtab_iterp);
+bool init_libsepol(const char *policy_path);
+void *load_policy(const char *policy_path);
+void destroy_policy(void *policydbp);
+void *init_avtab(void *policydbp);
+void *init_cond_avtab(void *policydbp);
+void destroy_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);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/tests/policy.py b/tests/policy.py
new file mode 100644
index 0000000..480faa2
--- /dev/null
+++ b/tests/policy.py
@@ -0,0 +1,142 @@
+from ctypes import *
+import re
+import os
+
+class TERule:
+ def __init__(self, rule):
+ data = rule.split(',')
+ self.flavor = data[0]
+ self.sctx = data[1]
+ self.tctx = data[2]
+ self.tclass = data[3]
+ self.perms = set((data[4].strip()).split(' '))
+ self.rule = rule
+
+class Policy:
+ __Rules = None
+ __FcDict = None
+ __libsepolwrap = None
+ __policydbP = None
+
+ # Return all file_contexts entries that map to the input Type.
+ def QueryFc(self, Type):
+ if Type in self.__FcDict:
+ return self.__FcDict[Type]
+ else:
+ return None
+
+ # Return all attributes associated with a type if IsAttr=False or
+ # all types associated with an attribute if IsAttr=True
+ def QueryTypeAttribute(self, Type, IsAttr):
+ TypeIterP = self.__libsepolwrap.init_type_iter(self.__policydbP,
+ create_string_buffer(Type), c_bool(IsAttr))
+ if (TypeIterP == None):
+ sys.exit("Failed to initialize type iterator")
+ buf = create_string_buffer(2048)
+
+ while True:
+ ret = self.__libsepolwrap.get_type(buf, c_int(2048),
+ self.__policydbP, TypeIterP)
+ if ret == 0:
+ yield buf.value
+ continue
+ if ret == 1:
+ break;
+ # We should never get here.
+ sys.exit("Failed to import policy")
+ self.__libsepolwrap.destroy_type_iter(TypeIterP)
+
+ # Return all TERules that match:
+ # (any scontext) or (any tcontext) or (any tclass) or (any perms),
+ # perms.
+ # Any unspecified paramenter will match all.
+ #
+ # Example: QueryTERule(tcontext=["foo", "bar"], perms=["entrypoint"])
+ # Will return any rule with:
+ # (tcontext="foo" or tcontext="bar") and ("entrypoint" in perms)
+ def QueryTERule(self, **kwargs):
+ if self.__Rules is None:
+ self.__InitTERules()
+ 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
+
+
+ def __GetTERules(self, policydbP, avtabIterP):
+ if self.__Rules is None:
+ self.__Rules = set()
+ buf = create_string_buffer(2048)
+ ret = 0
+ while True:
+ ret = self.__libsepolwrap.get_allow_rule(buf, c_int(2048), policydbP, avtabIterP)
+ if ret == 0:
+ Rule = TERule(buf.value)
+ self.__Rules.add(Rule)
+ continue
+ if ret == 1:
+ break;
+ # We should never get here.
+ sys.exit("Failed to import policy")
+
+ def __InitTERules(self):
+ avtabIterP = self.__libsepolwrap.init_avtab(self.__policydbP)
+ if (avtabIterP == None):
+ sys.exit("Failed to initialize avtab")
+ self.__GetTERules(self.__policydbP, avtabIterP)
+ 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.__libsepolwrap.destroy_avtab(avtabIterP)
+
+ # load ctypes-ified libsepol wrapper
+ def __InitLibsepolwrap(self):
+ self.__libsepolwrap = CDLL("libsepolwrap.so")
+
+ # load file_contexts
+ def __InitFC(self, FcPaths):
+ fc = []
+ for path in FcPaths:
+ if not os.path.exists(path):
+ sys.exit("file_contexts file " + path + " does not exist.")
+ fd = open(path, "r")
+ fc += fd.readlines()
+ fd.close()
+ self.__FcDict = {}
+ for i in fc:
+ rec = i.split()
+ try:
+ t = rec[-1].split(":")[2]
+ if t in self.__FcDict:
+ self.__FcDict[t].append(rec[0])
+ else:
+ self.__FcDict[t] = [rec[0]]
+ except:
+ pass
+
+ # load policy
+ def __InitPolicy(self, PolicyPath):
+ self.__policydbP = self.__libsepolwrap.load_policy(create_string_buffer(PolicyPath))
+ if (self.__policydbP is None):
+ sys.exit("Failed to load policy")
+
+ def __init__(self, PolicyPath, FcPaths):
+ self.__InitLibsepolwrap()
+ self.__InitFC(FcPaths)
+ self.__InitPolicy(PolicyPath)
+
+ def __del__(self):
+ if self.__policydbP is not None:
+ self.__libsepolwrap.destroy_policy(self.__policydbP)
diff --git a/tests/sepol_wrap.cpp b/tests/sepol_wrap.cpp
new file mode 100644
index 0000000..a12d438
--- /dev/null
+++ b/tests/sepol_wrap.cpp
@@ -0,0 +1,266 @@
+#include <stdio.h>
+#include <string>
+#include <sstream>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sepol/policydb/avtab.h>
+#include <sepol/policydb/policydb.h>
+#include <sepol/policydb/services.h>
+#include <sepol/policydb/util.h>
+#include <sys/types.h>
+#include <fstream>
+
+#include <android-base/file.h>
+#include <android-base/strings.h>
+#include <sepol_wrap.h>
+
+
+struct type_iter {
+ type_datum *d;
+ ebitmap_node *n;
+ unsigned int length;
+ unsigned int bit;
+};
+
+void *init_type_iter(void *policydbp, const char *type, bool is_attr)
+{
+ policydb_t *db = static_cast<policydb_t *>(policydbp);
+ struct type_iter *out = (struct type_iter *)
+ calloc(1, sizeof(struct type_iter));
+
+ if (!out) {
+ std::cerr << "Failed to allocate type type iterator" << std::endl;
+ return NULL;
+ }
+
+ out->d = static_cast<type_datum *>(hashtab_search(db->p_types.table, type));
+ if (is_attr && out->d->flavor != TYPE_ATTRIB) {
+ std::cerr << "\"" << type << "\" MUST be an attribute in the policy" << std::endl;
+ free(out);
+ return NULL;
+ } else if (!is_attr && out->d->flavor !=TYPE_TYPE) {
+ std::cerr << "\"" << type << "\" MUST be a type in the policy" << std::endl;
+ free(out);
+ return NULL;
+ }
+
+ if (is_attr) {
+ out->bit = ebitmap_start(&db->attr_type_map[out->d->s.value - 1], &out->n);
+ out->length = ebitmap_length(&db->attr_type_map[out->d->s.value - 1]);
+ } else {
+ out->bit = ebitmap_start(&db->type_attr_map[out->d->s.value - 1], &out->n);
+ out->length = ebitmap_length(&db->type_attr_map[out->d->s.value - 1]);
+ }
+
+ return static_cast<void *>(out);
+}
+
+void destroy_type_iter(void *type_iterp)
+{
+ struct type_iter *type_i = static_cast<struct type_iter *>(type_iterp);
+ free(type_i);
+}
+
+/*
+ * print allow rule into *out buffer.
+ *
+ * Returns -1 on error.
+ * Returns 0 on successfully reading an avtab entry.
+ * Returns 1 on complete
+ */
+int get_type(char *out, size_t max_size, void *policydbp, void *type_iterp)
+{
+ size_t len;
+ policydb_t *db = static_cast<policydb_t *>(policydbp);
+ struct type_iter *i = static_cast<struct type_iter *>(type_iterp);
+
+ for (; i->bit < i->length; i->bit = ebitmap_next(&i->n, i->bit)) {
+ if (!ebitmap_node_get_bit(i->n, i->bit)) {
+ continue;
+ }
+ len = snprintf(out, max_size, "%s", db->p_type_val_to_name[i->bit]);
+ if (len >= max_size) {
+ std::cerr << "type name exceeds buffer size." << std::endl;
+ return -1;
+ }
+ i->bit = ebitmap_next(&i->n, i->bit);
+ return 0;
+ }
+
+ return 1;
+}
+
+void *load_policy(const char *policy_path)
+{
+ FILE *fp;
+ policydb_t *db;
+
+ fp = fopen(policy_path, "re");
+ if (!fp) {
+ std::cerr << "Invalid or non-existing policy file: " << policy_path << std::endl;
+ return NULL;
+ }
+
+ db = (policydb_t *) calloc(1, sizeof(policydb_t));
+ if (!db) {
+ std::cerr << "Failed to allocate memory for policy db." << std::endl;
+ fclose(fp);
+ return NULL;
+ }
+
+ sidtab_t sidtab;
+ sepol_set_sidtab(&sidtab);
+ sepol_set_policydb(db);
+
+ struct stat sb;
+ if (fstat(fileno(fp), &sb)) {
+ std::cerr << "Failed to stat the policy file" << std::endl;
+ free(db);
+ fclose(fp);
+ return NULL;
+ }
+
+ auto unmap = [=](void *ptr) { munmap(ptr, sb.st_size); };
+ std::unique_ptr<void, decltype(unmap)> map(
+ mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fileno(fp), 0), unmap);
+ if (!map) {
+ std::cerr << "Failed to map the policy file" << std::endl;
+ free(db);
+ fclose(fp);
+ return NULL;
+ }
+
+ struct policy_file pf;
+ policy_file_init(&pf);
+ pf.type = PF_USE_MEMORY;
+ pf.data = static_cast<char *>(map.get());
+ pf.len = sb.st_size;
+ if (policydb_init(db)) {
+ std::cerr << "Failed to initialize policydb" << std::endl;
+ free(db);
+ fclose(fp);
+ return NULL;
+ }
+
+ if (policydb_read(db, &pf, 0)) {
+ std::cerr << "Failed to read binary policy" << std::endl;
+ policydb_destroy(db);
+ free(db);
+ fclose(fp);
+ return NULL;
+ }
+
+ return static_cast<void *>(db);
+}
+
+/* items needed to iterate over the avtab */
+struct avtab_iter {
+ avtab_t avtab;
+ uint32_t i;
+ avtab_ptr_t cur;
+};
+
+/*
+ * print allow rule into *out buffer.
+ *
+ * Returns -1 on error.
+ * Returns 0 on successfully reading an avtab entry.
+ * Returns 1 on complete
+ */
+static int get_avtab_allow_rule(char *out, size_t max_size, policydb_t *db,
+ struct avtab_iter *avtab_i)
+{
+ size_t len;
+
+ 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];
+ }
+ for (; avtab_i->cur; avtab_i->cur = (avtab_i->cur)->next) {
+ if (!((avtab_i->cur)->key.specified & AVTAB_ALLOWED)) continue;
+
+ len = snprintf(out, max_size, "allow,%s,%s,%s,%s",
+ db->p_type_val_to_name[(avtab_i->cur)->key.source_type - 1],
+ db->p_type_val_to_name[(avtab_i->cur)->key.target_type - 1],
+ db->p_class_val_to_name[(avtab_i->cur)->key.target_class - 1],
+ sepol_av_to_string(db, (avtab_i->cur)->key.target_class, (avtab_i->cur)->datum.data));
+ avtab_i->cur = (avtab_i->cur)->next;
+ if (!(avtab_i->cur))
+ (avtab_i->i)++;
+ if (len >= max_size) {
+ std::cerr << "Allow rule exceeds buffer size." << std::endl;
+ return -1;
+ }
+ return 0;
+ }
+ avtab_i->cur = NULL;
+ }
+
+ return 1;
+}
+
+int get_allow_rule(char *out, size_t len, void *policydbp, void *avtab_iterp)
+{
+ policydb_t *db = static_cast<policydb_t *>(policydbp);
+ struct avtab_iter *avtab_i = static_cast<struct avtab_iter *>(avtab_iterp);
+
+ return get_avtab_allow_rule(out, len, db, avtab_i);
+}
+
+/*
+ * <sepol/policydb/expand.h->conditional.h> uses 'bool' as a variable name
+ * inside extern "C" { .. } construct, which clang doesn't like.
+ * So, declare the function we need from expand.h ourselves.
+ */
+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)
+{
+ struct avtab_iter *out = (struct avtab_iter *)
+ calloc(1, sizeof(struct avtab_iter));
+ if (!out) {
+ std::cerr << "Failed to allocate avtab" << std::endl;
+ return NULL;
+ }
+
+ if (avtab_init(&out->avtab)) {
+ std::cerr << "Failed to initialize avtab" << std::endl;
+ free(out);
+ return NULL;
+ }
+
+ if (expand_avtab(p, in, &out->avtab)) {
+ std::cerr << "Failed to expand avtab" << std::endl;
+ free(out);
+ return NULL;
+ }
+ 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, p));
+}
+
+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, p));
+}
+
+void destroy_avtab(void *avtab_iterp)
+{
+ struct avtab_iter *avtab_i = static_cast<struct avtab_iter *>(avtab_iterp);
+ avtab_destroy(&avtab_i->avtab);
+ free(avtab_i);
+}
+
+void destroy_policy(void *policydbp)
+{
+ policydb_t *p = static_cast<policydb_t *>(policydbp);
+ policydb_destroy(p);
+}
diff --git a/tests/treble.py b/tests/treble.py
new file mode 100644
index 0000000..901f702
--- /dev/null
+++ b/tests/treble.py
@@ -0,0 +1,257 @@
+from optparse import OptionParser
+from optparse import Option, OptionValueError
+import os
+import policy
+import re
+import sys
+
+'''
+Use file_contexts and policy to verify Treble requirements
+are not violated.
+'''
+###
+# Differentiate between domains that are part of the core Android platform and
+# domains introduced by vendors
+coreAppdomain = {
+ 'bluetooth',
+ 'ephemeral_app',
+ 'isolated_app',
+ 'nfc',
+ 'platform_app',
+ 'priv_app',
+ 'radio',
+ 'shared_relro',
+ 'shell',
+ 'system_app',
+ 'untrusted_app',
+ 'untrusted_app_25',
+ 'untrusted_v2_app',
+ }
+coredomainWhitelist = {
+ 'adbd',
+ 'kernel',
+ 'postinstall',
+ 'postinstall_dexopt',
+ 'recovery',
+ 'system_server',
+ }
+coredomainWhitelist |= coreAppdomain
+
+class scontext:
+ def __init__(self):
+ self.fromSystem = False
+ self.fromVendor = False
+ self.coredomain = False
+ self.appdomain = False
+ self.attributes = set()
+ self.entrypoints = []
+ self.entrypointpaths = []
+
+def PrintScontext(domain, sctx):
+ print domain
+ print "\tcoredomain="+str(sctx.coredomain)
+ print "\tappdomain="+str(sctx.appdomain)
+ print "\tfromSystem="+str(sctx.fromSystem)
+ print "\tfromVendor="+str(sctx.fromVendor)
+ print "\tattributes="+str(sctx.attributes)
+ print "\tentrypoints="+str(sctx.entrypoints)
+ print "\tentrypointpaths="
+ if sctx.entrypointpaths is not None:
+ for path in sctx.entrypointpaths:
+ print "\t\t"+str(path)
+
+alldomains = {}
+coredomains = set()
+appdomains = set()
+vendordomains = set()
+
+###
+# Check whether the regex will match a file path starting with the provided
+# prefix
+#
+# Compares regex entries in file_contexts with a path prefix. Regex entries
+# are often more specific than this file prefix. For example, the regex could
+# be /system/bin/foo\.sh and the prefix could be /system. This function
+# loops over the regex removing characters from the end until
+# 1) there is a match - return True or 2) run out of characters - return
+# False.
+#
+def MatchPathPrefix(pathregex, prefix):
+ for i in range(len(pathregex), 0, -1):
+ try:
+ pattern = re.compile('^' + pathregex[0:i] + "$")
+ except:
+ continue
+ if pattern.match(prefix):
+ return True
+ return False
+
+def GetAllDomains(pol):
+ global alldomains
+ for result in pol.QueryTypeAttribute("domain", True):
+ alldomains[result] = scontext()
+
+def GetAppDomains():
+ global appdomains
+ global alldomains
+ for d in alldomains:
+ # The application of the "appdomain" attribute is trusted because core
+ # selinux policy contains neverallow rules that enforce that only zygote
+ # and runas spawned processes may transition to processes that have
+ # the appdomain attribute.
+ if "appdomain" in alldomains[d].attributes:
+ alldomains[d].appdomain = True
+ appdomains.add(d)
+
+
+def GetCoreDomains():
+ global alldomains
+ global coredomains
+ for d in alldomains:
+ # TestCoredomainViolators will verify if coredomain was incorrectly
+ # applied.
+ if "coredomain" in alldomains[d].attributes:
+ alldomains[d].coredomain = True
+ coredomains.add(d)
+ # check whether domains are executed off of /system or /vendor
+ if d in coredomainWhitelist:
+ continue
+ # TODO, add checks to prevent app domains from being incorrectly
+ # labeled as coredomain. Apps don't have entrypoints as they're always
+ # dynamically transitioned to by zygote.
+ if d in appdomains:
+ continue
+ if not alldomains[d].entrypointpaths:
+ continue
+ for path in alldomains[d].entrypointpaths:
+ # Processes with entrypoint on /system
+ if ((MatchPathPrefix(path, "/system") and not
+ MatchPathPrefix(path, "/system/vendor")) or
+ MatchPathPrefix(path, "/init") or
+ MatchPathPrefix(path, "/charger")):
+ alldomains[d].fromSystem = True
+ # Processes with entrypoint on /vendor or /system/vendor
+ if (MatchPathPrefix(path, "/vendor") or
+ MatchPathPrefix(path, "/system/vendor")):
+ alldomains[d].fromVendor = True
+
+###
+# Add the entrypoint type and path(s) to each domain.
+#
+def GetDomainEntrypoints(pol):
+ global alldomains
+ for x in pol.QueryTERule(tclass="file", perms=["entrypoint"]):
+ if not x.sctx in alldomains:
+ continue
+ alldomains[x.sctx].entrypoints.append(str(x.tctx))
+ # postinstall_file represents a special case specific to A/B OTAs.
+ # Update_engine mounts a partition and relabels it postinstall_file.
+ # There is no file_contexts entry associated with postinstall_file
+ # so skip the lookup.
+ if x.tctx == "postinstall_file":
+ continue
+ alldomains[x.sctx].entrypointpaths = pol.QueryFc(x.tctx)
+###
+# Get attributes associated with each domain
+#
+def GetAttributes(pol):
+ global alldomains
+ for domain in alldomains:
+ for result in pol.QueryTypeAttribute(domain, False):
+ alldomains[domain].attributes.add(result)
+
+def setup(pol):
+ GetAllDomains(pol)
+ GetAttributes(pol)
+ GetDomainEntrypoints(pol)
+ GetAppDomains()
+ GetCoreDomains()
+
+#############################################################
+# Tests
+#############################################################
+def TestCoredomainViolations():
+ global alldomains
+ # verify that all domains launched from /system have the coredomain
+ # attribute
+ ret = ""
+ violators = []
+ for d in alldomains:
+ domain = alldomains[d]
+ if domain.fromSystem and "coredomain" not in domain.attributes:
+ violators.append(d);
+ if len(violators) > 0:
+ ret += "The following domain(s) must be associated with the "
+ ret += "\"coredomain\" attribute because they are executed off of "
+ ret += "/system:\n"
+ ret += " ".join(str(x) for x in sorted(violators)) + "\n"
+
+ # verify that all domains launched form /vendor do not have the coredomain
+ # attribute
+ violators = []
+ for d in alldomains:
+ domain = alldomains[d]
+ if domain.fromVendor and "coredomain" in domain.attributes:
+ violators.append(d)
+ if len(violators) > 0:
+ ret += "The following domains must not be associated with the "
+ ret += "\"coredomain\" attribute because they are executed off of "
+ ret += "/vendor or /system/vendor:\n"
+ ret += " ".join(str(x) for x in sorted(violators)) + "\n"
+
+ 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
+# specified.
+#
+class MultipleOption(Option):
+ ACTIONS = Option.ACTIONS + ("extend",)
+ STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
+ TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
+ ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
+
+ def take_action(self, action, dest, opt, value, values, parser):
+ if action == "extend":
+ values.ensure_value(dest, []).append(value)
+ else:
+ Option.take_action(self, action, dest, opt, value, values, parser)
+
+Tests = ["CoredomainViolators"]
+
+if __name__ == '__main__':
+ usage = "sepolicy-trebletests -f nonplat_file_contexts -f "
+ usage +="plat_file_contexts -p policy [--test test] [--help]"
+ parser = OptionParser(option_class=MultipleOption, usage=usage)
+ parser.add_option("-f", "--file_contexts", dest="file_contexts",
+ metavar="FILE", action="extend", type="string")
+ parser.add_option("-p", "--policy", dest="policy", metavar="FILE")
+ parser.add_option("-t", "--test", dest="test", action="extend",
+ help="Test options include "+str(Tests))
+
+ (options, args) = parser.parse_args()
+
+ if not options.policy:
+ sys.exit("Must specify monolithic policy file\n" + parser.usage)
+ if not os.path.exists(options.policy):
+ sys.exit("Error: policy file " + options.policy + " does not exist\n"
+ + parser.usage)
+
+ if not options.file_contexts:
+ sys.exit("Error: Must specify file_contexts file(s)\n" + parser.usage)
+ for f in options.file_contexts:
+ if not os.path.exists(f):
+ sys.exit("Error: File_contexts file " + f + " does not exist\n" +
+ parser.usage)
+
+ pol = policy.Policy(options.policy, options.file_contexts)
+ setup(pol)
+
+ results = ""
+ # If an individual test is not specified, run all tests.
+ if options.test is None or "CoredomainViolations" in options.tests:
+ results += TestCoredomainViolations()
+
+ if len(results) > 0:
+ sys.exit(results)
diff --git a/vendor/hal_sensors_default.te b/vendor/hal_sensors_default.te
index 8379c82..7fd8f85 100644
--- a/vendor/hal_sensors_default.te
+++ b/vendor/hal_sensors_default.te
@@ -5,3 +5,6 @@
init_daemon_domain(hal_sensors_default)
allow hal_sensors_default fwk_scheduler_hwservice:hwservice_manager find;
+
+allow hal_sensors_default hal_graphics_allocator_default:fd use;
+allow hal_sensors_default ion_device:chr_file r_file_perms;