RK3288 android 6.0 user release 获取 root 权限

编译 RK3288 user 版本后,固件不会安装su,也就无法使用root权限,导致很多功能无法调试,非常不便。

为此,我想办法把 su 重新加到系统里了。

准备su

先使用 userdebug 模式编译系统,将 out/target/product/rk3288/system/xbin/su 保存到别的地方,因为改用 user 模式编译后会覆盖掉。

mkdir ~/backup
cp out/target/product/rk3288/system/xbin/su ~/backup/

删除 su Android.mk

rm system/extras/su/Android.mk

删除后,固件编译就不会遍历到这个目录了。

拷贝su

为了把前面保存的 su 安装到系统中,可以通过在某个系统app的android.mk 添加一个拷贝操作。

比如我们使用的 demo-app

$ cp ~/backup/su packages/apps/demo-app/
$ cd packages/apps/demo-app/
$ ls
Android.mk  demo-app.apk  lib  su
$ cat Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := demo-app
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_BUILT_MODULE_STEM := package.apk
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk

$(shell mkdir -p $(PRODUCT_OUT)/system/lib)
$(shell cp -rf $(LOCAL_PATH)/lib/armeabi/*  $(PRODUCT_OUT)/system/lib)
# install su
$(shell mkdir -p $(PRODUCT_OUT)/system/xbin)
$(shell cp -f $(LOCAL_PATH)/su  $(PRODUCT_OUT)/system/xbin/)

LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_PRIVILEGED_MODULE := false
LOCAL_CERTIFICATE := PRESIGNED

其中包含的以下两行便是拷贝操作,这样可以将 su 安装到系统。

$(shell mkdir -p $(PRODUCT_OUT)/system/xbin)
$(shell cp -f $(LOCAL_PATH)/su  $(PRODUCT_OUT)/system/xbin/)

修改权限

安装后执行 su 会报各种权限问题,需要修改 external/sepolicy/ 中的 shell.te, domain.te 予以支持。

diff --git a/app.te b/app.te
index 5f8f648..6658222 100755
--- a/app.te
+++ b/app.te
@@ -213,7 +213,7 @@ selinux_check_context(appdomain)
 
 # Superuser capabilities.
 # bluetooth requires net_admin and wake_alarm.
-neverallow { appdomain -bluetooth } self:capability *;
+neverallow { appdomain -bluetooth -shell } self:capability *;
 neverallow { appdomain -bluetooth } self:capability2 *;
 
 # Block device access.
diff --git a/domain.te b/domain.te
index 25b5ffb..ad765e7 100755
--- a/domain.te
+++ b/domain.te
@@ -338,7 +338,7 @@ neverallow domain default_android_service:service_manager add;
 
 # Require that domains explicitly label unknown properties, and do not allow
 # anyone but init to modify unknown properties.
-neverallow { domain -init } default_prop:property_service set;
+neverallow { domain -init -rild } default_prop:property_service set;
 
 neverallow { domain -init -recovery -system_server } frp_block_device:blk_file rw_file_perms;
 
@@ -398,7 +398,7 @@ neverallow domain { file_type fs_type dev_type }:{ lnk_file fifo_file sock_file
 # Nobody should be able to execute su on user builds.
 # On userdebug/eng builds, only dumpstate, shell, and
 # su itself execute su.
-neverallow { domain userdebug_or_eng(`-dumpstate -shell -su') } su_exec:file no_x_file_perms;
+# neverallow { domain userdebug_or_eng(`-dumpstate -shell -su') } su_exec:file no_x_file_perms;
 
 # Do not allow the introduction of new execmod rules. Text relocations
 # and modification of executable pages are unsafe.
diff --git a/shell.te b/shell.te
index 0350b7a..e94a8dc 100644
--- a/shell.te
+++ b/shell.te
@@ -40,6 +40,8 @@ allow shell input_device:chr_file rw_file_perms;
 allow shell system_file:file { entrypoint x_file_perms };
 allow shell shell_exec:file rx_file_perms;
 allow shell zygote_exec:file rx_file_perms;
+allow shell su_exec:file rx_file_perms;
+allow shell shell:capability { net_admin net_raw dac_override setgid setuid };
 
 r_dir_file(shell, apk_data_file)

关于添加权限,需要根据 avc: denied 相关错误信息去逐条添加。添加权限后可能出现编译失败并提示 neverallow 的信息,这个时候根据提示去修改相应文件,比如 external/sepolicy/domain.te,将所添加的项目排查在外即可,或者直接注释掉对应的 neverallow 条例。不过修改neverallow 条例可能会导致 Google CTS 测试失败,这个不确定后续会不会有影响,但如果只是为了调试,后续再revert就好了。

最后,由于 Android 6.0 严格的 sepolicy 权限管理,即使使用 su 获得了root权限,也不是无所不能的,很多权限仍旧受限,比如默认的 ifconfigiptables 等指令都无法使用,这时候还是需要根据提示去添加相应权限才行。