Android system (67)---The difference between root permission of android apk and USB adb permission

The difference between root permission of android apk and USB adb permission

USB adb permission means that when adb is connected to the phone, the permission of the daemon process adbd in the phone is root permission, so its child process also has root permission, usually if the adb shell sees:
Android 4.0 and later:
C:\ >adb shell
root@android:/  #
Android 2.3 version:
C:\>adb shell
#
That means that the connection of adb is root permission, on the contrary, if you see $, it indicates that it is shell permission
Android APK itself does not have root permission. If you want to enable root permission, you must use a process with root permission or a file with s bit. At present, the more common method is, after the phone is rooted, built-in su to system /bin, and then ordinary APP can use the su command to achieve root privilege switching. 
Some colleagues on the network have modified the su command and controlled the permission control of the su command through an APK.
 SuperSU:  http://forum.xda-developers.com/showthread.php?t=1538053  (fast update speed, recommended)
 
To sum up, if adb already has root permissions, it is very simple to make apk exercise root permissions.
For example on JB version or previous version:
adb remount
adb push su /system/bin
adb push Superuser.apk /system/app
adb shell chmod 0644 /system/app/Superuser.apk
adb shell chmod 6755 /system/bin/su
adb reboot

Later versions of KK:
 

* The root permission of adb is controlled in system/core/adb/adb.c. It is mainly controlled by system properties such as ro.secure and ro.debuggable.
By default, when ro.secure is 0, the root permission is enabled. When it is 1, check whether the root permission can be enabled according to options such as ro.debuggable. To this end, if you want to permanently enable the root privilege of adb, there are two ways to modify it:
1. Modify the system property ro.secure, and let ro.secure=0.
2. Modify the judgment logic for enabling root permission in adb.c.

* On L version, adb will be affected by SELinux, so you need to adjust SELinux policy settings.

The two modification methods are described in detail below:
The first method. Modify the system property ro.secure, and let ro.secure=0.
(1) Modify alps/build/core/main.mk 
ifneq (,$(user_variant))
  # Target is secure in user builds.
  ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=1

Change ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=1 to ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=0.

(2) After the android JB version (4.1), google directly removes the root permission of the user version of adbd from the compilation, so you need to modify the compilation option ALLOW_ADBD_ROOT in system/core/adb/Android.mk, if this is not enabled option, then adb.c will not choose root or shell authority according to ro.secure, and return to shell authority directly. So you must need line 126 in Android.mk:
    ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
    ===> ifneq (,$(filter userdebug user eng,$(TARGET_BUILD_VARIANT)))

(3)在android L (5.0) 以后, google 默认开启SELinux enforce mode, 需要在user build 上将su label 默认build 进SEPolicy.
   放开SELinux 的限制. 更新alps/external/sepolicy/Android.mk 116 行,  将su label 默认编译进入sepolicy.
 sepolicy_policy.conf := $(intermediates)/policy.conf
 $(sepolicy_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
 $(sepolicy_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
 $(sepolicy_policy.conf) : $(call build_policy, $(sepolicy_build_files))
  @mkdir -p $(dir $@)
  $(hide) m4 -D mls_num_sens=$(PRIVATE_MLS_SENS) -D mls_num_cats=$(PRIVATE_MLS_CATS) \
   -D target_build_variant=$(TARGET_BUILD_VARIANT) \
   -D force_permissive_to_unconfined=$(FORCE_PERMISSIVE_TO_UNCONFINED) \
   -s $^ > $@
  $(hide) sed '/dontaudit/d' $@ > [email protected]
 
 将-D target_build_variant=$(TARGET_BUILD_VARIANT) 改成 -D target_build_variant=eng

如果是N 版本, selinux policy 已经搬移到 alps/system/sepolicy.
 
即第一种方法在android L(5.0) 以后你需要改(1),(2),(3). 
    
第二种方法. 修改adb.c 中开启root 权限的判断逻辑。这里针对4.1 以后版本 和4.1以前版本有所区别。
(1).如果是JB 4.1 以后版本,直接修改函数should_drop_privileges() 函数, 清空这个函数,直接返回 0 即可。返回0 即开启root 权限。

(2).如果是JB 4.1 以前版本,直接修改函数adb_main 函数,在
    /* don't listen on a port (default 5037) if running in secure mode */
    /* don't run as root if we are running in secure mode */
    if (secure) {
        struct __user_cap_header_struct header;
        struct __user_cap_data_struct cap;

        if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
            exit(1);
        }
  
在这段代码前加一行:

    secure = 0;  //mtk71029 add for root forever.

    /* don't listen on a port (default 5037) if running in secure mode */
    /* don't run as root if we are running in secure mode */
    if (secure) {
        struct __user_cap_header_struct header;
        struct __user_cap_data_struct cap;

        if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
            exit(1);
        }
  
(3)在android L (5.0) 以后, google 默认开启SELinux enforce mode, 需要在user build 上将su label 默认build 进SEPolicy.
   放开SELinux 的限制. 更新alps/external/sepolicy/Android.mk 116 行,  将su label 默认编译进入sepolicy.
 sepolicy_policy.conf := $(intermediates)/policy.conf
 $(sepolicy_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
 $(sepolicy_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
 $(sepolicy_policy.conf) : $(call build_policy, $(sepolicy_build_files))
  @mkdir -p $(dir $@)
  $(hide) m4 -D mls_num_sens=$(PRIVATE_MLS_SENS) -D mls_num_cats=$(PRIVATE_MLS_CATS) \
   -D target_build_variant=$(TARGET_BUILD_VARIANT) \
   -D force_permissive_to_unconfined=$(FORCE_PERMISSIVE_TO_UNCONFINED) \
   -s $^ > $@
  $(hide) sed '/dontaudit/d' $@ > [email protected]
 
 将-D target_build_variant=$(TARGET_BUILD_VARIANT) 改成 -D target_build_variant=eng  

如果是N 版本, selinux policy 已经搬移到 alps/system/sepolicy.
  
即第二种方法在android L(5.0) 以后你需要改(1),(3).   
  
[测试与确认]
当修改完成后,只需要重新build bootimage ,然后download 即可,然后到setting 中开启debug 选项,adb 连接后,会显示 #, 即root 成功。


(1). adbd 的root 权限
我们通常在debug user 版本问题时, 或者进行user 版本的monkey test 时都会这个工作,以便debug. 可以参考FAQ. 
如果你想user 版本adb root 权限默认关闭, 而在想开启时, 可以通过工程模式中的设置项开启, 那么请USER2ROOT 功能 (L 版本不再支持此功能)。
此功能默认关闭, 如果开启, 需要在ProjectConfig.mk 中设置: MTK_USER_ROOT_SWITCH = yes
同样注意此项功能通常只用于debug 或者 cmcc 送测, 在正式出货版本, 强烈要求关闭, 否则有安全风险.
 
(2). app 的root 权限
app 的root 权限通常是通过执行su 命令来获取。注意的是KK 上, 因为多种限制, 普通的su 难以直接拿到root 权限, 需要做针对性的改动.
通常我们会内置具有控制端的第三方su, 下面以内置SuperSU, 以及使用Google default su 为例进行说明。
 
(3). 如何内置第三方SuperSU
该方式可以绕过zygote 和 adbd 对Root Capabilities BoundSet 的限制. MTK 目前仅测试KK 以及以前的版本, L 版本后因为SuperSU 还在持续更新中, 请客户查看它官网的说明.
3.1. 下载SuperSU
 SuperSU:  http://forum.xda-developers.com/showthread.php?t=1538053
 
3.2. 内置Superuser.apk 到 system/app
   将su 复制并改名成: daemonsu
   内置su 到 system/xbin
   内置daemonsu 到 system/xbin
   内置chattr 到 system/xbin
   内置chattr.pie 到 /system/xbin
 
3.3. 内置install-recovery.sh 到system/etc
并且按照FAQ:  FAQ09021 如何修改系统内置文件的权限, 用户,属性  https://online.mediatek.com/Pages/FAQ.aspx?List=SW&FAQID=FAQ09021
更新alps/system/core/inlcude/private/android_filesystem_config.h
在android_files 数组的最开始新增.
{ 00755, AID_ROOT,      AID_ROOT,      0, "system/etc/install-recovery.sh" },
 
(4). 如何内置Google default su
4.1 放开Google default su 只准shell/root 用户使用的限制.
    system/extras/su/su.c 中删除下面3行代码
    if (myuid != AID_ROOT && myuid != AID_SHELL) {
        fprintf(stderr,"su: uid %d not allowed to su\n", myuid);
        return 1;
    }
 
4.2 首先将此编译出的su 内置到system/bin, 然后修改su 的内置权限,启用sbit 位.
按照FAQ:  FAQ09021 如何修改系统内置文件的权限, 用户,属性  https://online.mediatek.com/Pages/FAQ.aspx?List=SW&FAQID=FAQ09021
更新alps/system/core/inlcude/private/android_filesystem_config.h
在android_files 数组中
增加
{ 06755, AID_ROOT,      AID_ROOT,      0, "system/bin/su" },
注意这行要放在
{ 00755, AID_ROOT,      AID_SHELL,     0, "system/bin/*" },
之前
 
4.3 如果是KK 版本(非KK2 MT6752/MT6732), 需要强行解除zygote 和 adbd 对Root Capabilities BoundSet 的限制
更新kernel/security/commoncap.c 中 cap_prctl_drop 函数为:
static long cap_prctl_drop(struct cred *new, unsigned long cap)
{
  //mtk71029 add begin: Let 'zygote' and 'adbd' drop Root Capabilities BoundSet ineffectively
        if (!strncmp(current->comm, "zygote", 16)) {
                return -EINVAL;
        }
        if (!strncmp(current->comm, "adbd", 16)) {
                return -EINVAL;
        }
        // add end
        if (!capable(CAP_SETPCAP))
                return -EPERM;
        if (!cap_valid(cap))
                return -EINVAL;
        cap_lower(new->cap_bset, cap);
        return 0;
}
 
4.4 如果贵司一定要在K2(MT6752/MT6732) 上开启, 请提交eService, 申请定制的DVM, 放开相关的权限限制.
 
 
4.5 如果贵司在L 版本操作, 请按下面的流程:
 4.5.1 更新alps/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp  
  将 DropCapabilitiesBoundingSet(JNIEnv* env) 这个函数置空.

 4.5.2 更新alps/frameworks/base/cmds/app_process/app_main.cpp 的main 函数, 注释掉main函数开始的下面这段代码
  if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
   // Older kernels don't understand PR_SET_NO_NEW_PRIVS and return
   // EINVAL. Don't die on such kernels.
   if (errno != EINVAL) {
    LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
    return 12;
   }
  }

 4.5.3 更新alps/system/core/adb/adb.c 将should_drop_privileges() 函数, 清空这个函数,直接返回 0 即可.

 4.5.4 将SELinux 调整到permissve mode, 参考FAQ11484:  http://online.mediatek.inc/Pages/FAQ.aspx?List=SW&FAQID=FAQ11484
  
 
重新编译系统, 重新download 后, adb shell 进入后再输入su 看看是否命令行由$切换到#, 如果切换即成功。
 
(5). 在KK 版本后app 使用root 权限受到更加严格的限制, 可以参考FAQ
[FAQ11414] android KK 4.4 版本后,user 版本su 权限严重被限制问题说明
http://online.mediatek.inc/Pages/FAQ.aspx?List=SW&FAQID=FAQ11414
FAQ11538:android KK 4.4 版本后,app 使用root(su) 权限受到严格限制说明
https://online.mediatek.com/Pages/FAQ.aspx?List=SW&FAQID=FAQ11538
 


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325430612&siteId=291194637