From bacf36480dd935ee02c45a17eaaba3d4d6e397ce Mon Sep 17 00:00:00 2001
From: Jiyong Park <jiyong@google.com>
Date: Fri, 1 Jun 2018 12:31:33 +0900
Subject: [PATCH] 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
 ###
-- 
GitLab