Add sepolicy for installing GSIs to external storage.
To install GSIs on external storage (such as sdcards), gsid needs some
additional privileges:
- proc_cmdline and device-tree access to call ReadDefaultFstab().
This is ultimately used to check whether system's dm-verity has
check_at_most_once enabled, which is disallowed with sdcards.
- vfat read/write access to write files to the sdcard. Note that
adopted sdcards are not supported here.
- read access to the sdcard block device. To enable this without
providing access to vold_block_device, a new sdcard_block_device
label was added. Devices must apply this label appropriately to
enable gsid access.
- FIBMAP access for VFAT filesystems, as they do not support FIEMAP.
This only appears to work by granting SYS_RAWIO.
Bug: 126230649
Test: adb shell su root gsi_tool install --install_dir=/mnt/media_rw/...
works without setenforce 0
Change-Id: I88d8d83e5f61d4c0490f912f226fe1fe38cd60ab
diff --git a/private/compat/28.0/28.0.ignore.cil b/private/compat/28.0/28.0.ignore.cil
index 8187e29..f4e2cd4 100644
--- a/private/compat/28.0/28.0.ignore.cil
+++ b/private/compat/28.0/28.0.ignore.cil
@@ -113,6 +113,7 @@
runas_app
runas_app_tmpfs
runtime_service
+ sdcard_block_device
sensor_privacy_service
server_configurable_flags_data_file
simpleperf_app_runner
diff --git a/private/domain.te b/private/domain.te
index f4fb407..037a7d5 100644
--- a/private/domain.te
+++ b/private/domain.te
@@ -297,3 +297,18 @@
-vold
-zygote
} { fs_type -sdcard_type }:filesystem { mount remount relabelfrom relabelto };
+
+# Limit raw I/O to these whitelisted domains. Do not apply to debug builds.
+neverallow {
+ domain
+ userdebug_or_eng(`-domain')
+ -kernel
+ -gsid
+ -init
+ -recovery
+ -ueventd
+ -healthd
+ -uncrypt
+ -tee
+ -hal_bootctl_server
+} self:global_capability_class_set sys_rawio;
diff --git a/private/gsid.te b/private/gsid.te
index 62ac06b..5dcf746 100644
--- a/private/gsid.te
+++ b/private/gsid.te
@@ -22,17 +22,39 @@
# file names.
allow gsid sysfs_dm:dir r_dir_perms;
+# Needed to read fstab, which is used to validate that system verity does not
+# use check_once_at_most for sdcard installs. (Note: proc_cmdline is needed
+# to get the A/B slot suffix).
+allow gsid proc_cmdline:file r_file_perms;
+allow gsid sysfs_dt_firmware_android:dir r_dir_perms;
+allow gsid sysfs_dt_firmware_android:file r_file_perms;
+
# Needed to stat /data/gsi/* and realpath on /dev/block/by-name/*
allow gsid block_device:dir r_dir_perms;
# liblp queries these block alignment properties.
-allowxperm gsid userdata_block_device:blk_file ioctl {
+allowxperm gsid { userdata_block_device sdcard_block_device }:blk_file ioctl {
BLKIOMIN
BLKALIGNOFF
};
+# When installing images to an sdcard, gsid needs to be able to stat() the
+# block device. gsid also calls realpath() to remove symlinks.
+allow gsid mnt_media_rw_file:dir r_dir_perms;
+
+# When installing images to an sdcard, gsid must bypass sdcardfs and install
+# directly to vfat, which supports the FIBMAP ioctl.
+allow gsid vfat:dir rw_dir_perms;
+allow gsid vfat:file create_file_perms;
+allow gsid sdcard_block_device:blk_file r_file_perms;
+# This is needed for FIBMAP unfortunately. Oddly FIEMAP does not carry this
+# requirement, but the kernel does not implement FIEMAP support for VFAT.
+allow gsid self:global_capability_class_set sys_rawio;
+
# gsi_tool passes the system image over the adb connection, via stdin.
allow gsid adbd:fd use;
+# Needed when running gsi_tool through "su root" rather than adb root.
+allow gsid adbd:unix_stream_socket rw_socket_perms;
neverallow { domain -gsid -init } gsid_prop:property_service set;
diff --git a/public/device.te b/public/device.te
index 41b4edb..e20a68b 100644
--- a/public/device.te
+++ b/public/device.te
@@ -105,3 +105,8 @@
# 'super' partition to be used for logical partitioning.
type super_block_device, super_block_device_type, dev_type;
+
+# sdcard devices; normally vold uses the vold_block_device label and creates a
+# separate device node. gsid, however, accesses the original devide node
+# created through uevents, so we use a separate label.
+type sdcard_block_device, dev_type;
diff --git a/public/domain.te b/public/domain.te
index 978c9bf..5a964c9 100644
--- a/public/domain.te
+++ b/public/domain.te
@@ -349,20 +349,6 @@
-vold
} self:global_capability_class_set mknod;
-# Limit raw I/O to these whitelisted domains. Do not apply to debug builds.
-neverallow {
- domain
- userdebug_or_eng(`-domain')
- -kernel
- -init
- -recovery
- -ueventd
- -healthd
- -uncrypt
- -tee
- -hal_bootctl_server
-} self:global_capability_class_set sys_rawio;
-
# No process can map low memory (< CONFIG_LSM_MMAP_MIN_ADDR).
neverallow * self:memprotect mmap_zero;