一、 需求
客户需要一个App应用能使用root权限的版本。
二、 误解
以为编译Eng版本,adb root和 adb shell #就可以。实际上这至少其中一部分。
工作中我们一般会编译针对开发人员的eng版本以方便调试,按说eng版本应该开放了所有的系统权限,几乎应该是等同于root版本的,而实际上eng版本的root权限主要是给予了adb,对于上层应用依旧保持封闭状态(使用root助手等检测显示未root)。我们这里通过修改开放针对上层应用的root权限。
三、解决方案
1. system\core\libcutils\fs_config.c
这个06755 权限配置非常重要和关键
由于su文件的权限位中有rws,所以:运行su的进程的EUID,在运行su期间,变成了su的所有者的UID。而上文已述,su的所有者是root用户,所以运行su的进程的EUID,在运行su期间,变成了root用户的UID。
需要特别注意的是,当shell进程开始运行su的时候,shell进程的EUID,就已经是root用户的UID了。换言之,此时的shell进程,已经拥有root用户权限了。但是,这种EUID变为root用户UID的情况,是有时效性的,在su文件运行完毕后就失效了。而之所以运行过一次su文件,进程就能持久性地获得root用户权限,归功于su文件的内容。
其实,只要shell进程,运行的是一个owner是root用户,且权限位为4775的可执行文件,shell进程都能获取到(短暂的)root用户权限。之所以必须要运行su文件,而不是其他文件,就是因为su文件中的代码,能赋予shell进程持久性的root用户权限。
//修改用户与权限
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/su" },
2. build/make/core/main.mk ---- 这里比较好理解,就是对比debug的参数配置
\system\core\init\Android.mk
ifneq (,$(user_variant))
# Target is secure in user builds.
ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=0
ADDITIONAL_DEFAULT_PROPERTIES += security.perf_harden=0
ifeq ($(user_variant),user)
ADDITIONAL_DEFAULT_PROPERTIES += ro.adb.secure=0
endif
ifeq ($(user_variant),userdebug)
# Pick up some extra useful tools
tags_to_install += debug
else
# Disable debugging in plain user builds.
enable_target_debugging :=
endif
3. 修改selinux
/code/1-android8.1/system/core/
diff --git a/init/init.cpp b/init/init.cpp
index 6ecd88c..cfeef46 100755
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -588,6 +588,7 @@ static selinux_enforcing_status selinux_status_from_cmdline() {
static bool selinux_is_enforcing(void)
{
+return false;
if (ALLOW_PERMISSIVE_SELINUX) {
return selinux_status_from_cmdline() == SELINUX_ENFORCING;
}
4. 消除Capabilities机制
kernel-4.4/security/commoncap.c添加
@@ -881,6 +881,14 @@ static int cap_prctl_drop(unsigned long cap)
{
struct cred *new;
+if (!strncmp(current->comm, "zygote", 16)) {
+return -EINVAL;
+}
+
+if (!strncmp(current->comm, "adbd", 16)) {
+return -EINVAL;
+}
framework
cmds/webview_zygote/webview_zygote.cpp
这个所谓的Capabilities机制对于Root权限是另一种控制
\frameworks\base\core\jni\com_android_internal_os_Zygote.cpp
将DropCapabilitiesBoundingSet(JNIEnv* env)函数清空
\frameworks\base\cmds\app_process\app_main.cpp
其中的Main方法删除如下代码块
5. 修改 system 分区权限为可读写
Dear customer,开启完整的root 权限需要开通SELinux 权限,这部分修改无法通过CTS 测试。
我司目前不会提供类似的方案给贵司。目前我们只支持USB adb权限。这是 MTK 的官方回复。
vendor/mediatek/proprietary/hardware/fstab/mt6765/fstab.in.mt6765
#endif
-DEVPATH(system) SYS_MOUNT_POINT __MTK_SYSIMG_FSTYPE ro FSMGR_FLAG_SYSTEM
+DEVPATH(system) SYS_MOUNT_POINT __MTK_SYSIMG_FSTYPE rw FSMGR_FLAG_SYSTEM
#ifdef __VENDOR_PARTITION_SUPPORT
-DEVPATH(vendor) /vendor __MTK_VNDIMG_FSTYPE ro FSMGR_FLAG_SYSTEM
+DEVPATH(vendor) /vendor __MTK_VNDIMG_FSTYPE rw FSMGR_FLAG_SYSTEM
#endif
#ifdef __ODM_PARTITION_SUPPORT
-DEVPATH(odm) /odm __MTK_ODMIMG_FSTYPE ro FSMGR_FLAG_SYSTEM
+DEVPATH(odm) /odm __MTK_ODMIMG_FSTYPE rw FSMGR_FLAG_SYSTEM
#endif
DEVPATH(userdata) /data __MTK_DATAIMG_FSTYPE FS_FLAG_DATA FSMGR_FLAG_DATA
6. busybox 安装问题解决
安装 busybox.apk 安装成功