From bacf36480dd935ee02c45a17eaaba3d4d6e397ce Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Fri, 1 Jun 2018 12:31:33 +0900 Subject: [PATCH 1/2] adbd is allowed to execute shell in recovery mode The shell is now available directly in the recovery ramdisk. We no longer need to mount system.img to /system as the recovery ramdisk is self-contained. However, there is a problem that every file in the ramdisk is labeled as rootfs because the ramdisk does not support xattr. This CL adds several recovery-only rules that are required to make the recovery ramdisk self-contained. Most importantly, adbd is allowed to domain_trans to shell. Also shell is allowe to execute files of type rootfs. Finally, the recovery is allowed to mount on tmpfs since it now mounts system.img to /mnt/system. Bug: 63673171 Test: `adb reboot recovery; adb devices` shows the device ID Test: `adb root && adb shell` and then $ lsof -p `pidof adbd` shows that libm.so, libc.so, etc. are loaded from the /lib directory. Change-Id: If21b069aee63541344a5ca8939fb9a46ffef4d3e --- private/adbd.te | 10 +++++++++- public/recovery.te | 1 + public/shell.te | 6 ++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/private/adbd.te b/private/adbd.te index bde6864ba..58038c70e 100644 --- a/private/adbd.te +++ b/private/adbd.te @@ -12,6 +12,14 @@ userdebug_or_eng(` allow adbd su:process dyntransition; ') +# When 'adb shell' is executed in recovery mode, adbd explicitly +# switches into shell domain using setcon() because the shell executable +# is not labeled as shell but as rootfs. +recovery_only(` + domain_trans(adbd, rootfs, shell) + allow adbd shell:process dyntransition; +') + # Do not sanitize the environment or open fds of the shell. Allow signaling # created processes. allow adbd shell:process { noatsecure signal }; @@ -148,4 +156,4 @@ allow adbd rootfs:dir r_dir_perms; # transitions to the shell domain (except when it crashes). In particular, we # never want to see a transition from adbd to su (aka "adb root") neverallow adbd { domain -crash_dump -shell }:process transition; -neverallow adbd { domain userdebug_or_eng(`-su') }:process dyntransition; +neverallow adbd { domain userdebug_or_eng(`-su') recovery_only(`-shell') }:process dyntransition; diff --git a/public/recovery.te b/public/recovery.te index 57ad2028b..48fffe645 100644 --- a/public/recovery.te +++ b/public/recovery.te @@ -30,6 +30,7 @@ recovery_only(` # Mount filesystems. allow recovery rootfs:dir mounton; + allow recovery tmpfs:dir mounton; allow recovery fs_type:filesystem ~relabelto; allow recovery unlabeled:filesystem ~relabelto; allow recovery contextmount_type:filesystem relabelto; diff --git a/public/shell.te b/public/shell.te index 4293f529a..8e6ae4cdd 100644 --- a/public/shell.te +++ b/public/shell.te @@ -199,6 +199,12 @@ allow shell sepolicy_file:file r_file_perms; # Allow shell to start up vendor shell allow shell vendor_shell_exec:file rx_file_perms; +# Everything is labeled as rootfs in recovery mode. Allow shell to +# execute them. +recovery_only(` + allow shell rootfs:file rx_file_perms; +') + ### ### Neverallow rules ### From 90b21ee4b4e231fbc2eb823abdc9a88201cf579d Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Fri, 1 Jun 2018 19:28:59 +0900 Subject: [PATCH 2/2] init is a dynamic executable init is now a dynamic executable. So it has to be able to execute the dynamic linker (/system/bin/linker) and shared libraries (e.g., /system/lib/libc.so). Furthermore, when in recovery mode, the files are all labeled as rootfs - because the recovery ramdisk does not support xattr, so files of type rootfs is allowed to be executed. Do the same for kernel and ueventd because they are executing the init executable. Bug: 63673171 Test: `adb reboot recovery; adb devices` shows the device ID Change-Id: Ic6225bb8e129a00771e1455e259ff28241b70396 --- public/kernel.te | 15 +++++++++++++++ public/ueventd.te | 6 ++++++ public/vendor_init.te | 6 ++++++ 3 files changed, 27 insertions(+) diff --git a/public/kernel.te b/public/kernel.te index b7a351cc8..cf913ba68 100644 --- a/public/kernel.te +++ b/public/kernel.te @@ -103,3 +103,18 @@ neverallow kernel *:file { entrypoint execute_no_trans }; # Instead of adding dac_{read_search,override}, fix the unix permissions # on files being accessed. neverallow kernel self:global_capability_class_set { dac_override dac_read_search }; + +# Allow the first-stage init (which is running in the kernel domain) to execute the +# dynamic linker when it re-executes /init to switch into the second stage. +# Until Linux 4.8, the program interpreter (dynamic linker in this case) is executed +# before the domain is switched to the target domain. So, we need to allow the kernel +# domain (the source domain) to execute the dynamic linker (system_file type). +# TODO(b/110147943) remove these allow rules when we no longer need to support Linux +# kernel older than 4.8. +allow kernel system_file:file execute; +# The label for the dynamic linker is rootfs in the recovery partition. This is because +# the recovery partition which is rootfs does not support xattr and thus labeling can't be +# done at build-time. All files are by default labeled as rootfs upon booting. +recovery_only(` + allow kernel rootfs:file execute; +') diff --git a/public/ueventd.te b/public/ueventd.te index 9b9eacb25..0cac32d48 100644 --- a/public/ueventd.te +++ b/public/ueventd.te @@ -39,6 +39,12 @@ allow ueventd self:process setfscreate; # Allow ueventd to read androidboot.android_dt_dir from kernel cmdline. allow ueventd proc_cmdline:file r_file_perms; +# Everything is labeled as rootfs in recovery mode. ueventd has to execute +# the dynamic linker and shared libraries. +recovery_only(` + allow ueventd rootfs:file { r_file_perms execute }; +') + ##### ##### neverallow rules ##### diff --git a/public/vendor_init.te b/public/vendor_init.te index ad69437a6..6307f2cf6 100644 --- a/public/vendor_init.te +++ b/public/vendor_init.te @@ -155,6 +155,12 @@ allow vendor_init self:global_capability_class_set sys_admin; # Raw writes to misc block device allow vendor_init misc_block_device:blk_file w_file_perms; +# Everything is labeled as rootfs in recovery mode. Vendor init has to execute +# the dynamic linker and shared libraries. +recovery_only(` + allow vendor_init rootfs:file { r_file_perms execute }; +') + not_compatible_property(` set_prop(vendor_init, { property_type