• [SM6225][Android13]user版本默认允许root和remount


    开发平台基本信息

    芯片: 高通SM6225
    版本: Android 13
    kernel: msm-5.15

    问题描述

           刚刚从Framework踏入性能的小殿堂,User版本默认是不会开启root权限的,而且一般调试需要设置一下CPU GPU DDR performance模式或者修改一些schedule util等调核调频节点去对比复测,userdebug版本的话本身整机性能就比user卡很多,有时候使用userdebug去复测会对测试结果有较大影响,与user测试结果存在很大差距。

          基于以上,user+root闪亮登场,性能与user一致,而且还有root和remount权限,可以自主执行修改节点或者push等操作。话不多说,让我们进入整体,看看如何实现user+root+remount.

    基线代码判断逻辑:


    1.adb代码会检测相关属性

    ro.secure
    ro.debuggable (通过调用__android_log_is_debuggable()获取返回值)

    2.代码path

    2.1 adbd启动时检查属性,决定是否进行权限降级到AID_SHELL
    path:system/adb/core/daemon/main.cpp line:121
    if (should_drop_privileges()){
    … …

    2.2 system/adb/core/下搜索__android_log_is_debuggable()

    3.修改思路

    3.1 should_drop_privileges() 修改强制返回false,保持adb root用户级别
    3.2 __android_log_is_debuggable() 返回true
     

    1. packages/modules/adb/daemon/main.cpp
    2. static bool should_drop_privileges() {
    3. // The properties that affect `adb root` and `adb unroot` are ro.secure and
    4. // ro.debuggable. In this context the names don't make the expected behavior
    5. // particularly obvious.
    6. //
    7. // ro.debuggable:
    8. // Allowed to become root, but not necessarily the default. Set to 1 on
    9. // eng and userdebug builds.
    10. //
    11. // ro.secure:
    12. // Drop privileges by default. Set to 1 on userdebug and user builds.
    13. bool ro_secure = android::base::GetBoolProperty("ro.secure", true);
    14. bool ro_debuggable = __android_log_is_debuggable();
    15. // Drop privileges if ro.secure is set...
    16. bool drop = ro_secure;
    17. std::string build_prop = android::base::GetProperty("ro.build.type", "");
    18. bool adb_build_root = (build_prop == "userdebug");
    19. if (adb_build_root) {
    20. return false;
    21. }
    22. // ... except "adb root" lets you keep privileges in a debuggable build.
    23. std::string prop = android::base::GetProperty("service.adb.root", "");
    24. bool adb_root = (prop == "1");
    25. bool adb_unroot = (prop == "0");
    26. if (ro_debuggable && adb_root) {
    27. drop = false;
    28. }
    29. // ... and "adb unroot" lets you explicitly drop privileges.
    30. if (adb_unroot) {
    31. drop = true;
    32. }
    33. return drop;
    34. }

    解决方案:

    1.注释掉DropCapabilitiesBoundingSet

    说明:这个文件负责创建应用程序进程,并设置它们的权限和能力。需要注释掉DropCapabilitiesBoundingSet函数中的代码,以防止它删除adbd进程的任何能力。

    文件路径:qssi/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
    详细修改:

    1. --- a/core/jni/com_android_internal_os_Zygote.cpp
    2. +++ b/core/jni/com_android_internal_os_Zygote.cpp
    3. @@ -681,7 +681,7 @@
    4. }
    5. static void DropCapabilitiesBoundingSet(fail_fn_t fail_fn) {
    6. - for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {;
    7. + /*for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {;
    8. if (prctl(PR_CAPBSET_DROP, i, 0, 0, 0) == -1) {
    9. if (errno == EINVAL) {
    10. ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify "
    11. @@ -690,7 +690,7 @@
    12. fail_fn(CREATE_ERROR("prctl(PR_CAPBSET_DROP, %d) failed: %s", i, strerror(errno)));
    13. }
    14. }
    15. - }
    16. + }*/
    17. }
    18. static void SetInheritable(uint64_t inheritable, fail_fn_t fail_fn) {

    2.启用abdb root模式添加remount,保持adb root用户级别

    2.1 启用adbd进程的root模式,并添加remount到required中

    说明:这个文件定义了adbd模块的编译选项和依赖项。需要添加-DALLOW_ADBD_ROOT=1到cflags中,以启用adbd进程的root模式,并添加remount到required中,以允许adbd进程重新挂载系统分区。

    文件路径:qssi/packages/modules/adb/Android.bp
    详细修改:

    1. --- a/Android.bp
    2. +++ b/Android.bp
    3. @@ -50,6 +50,7 @@
    4. "-Wvla",
    5. "-DADB_HOST=1", // overridden by adbd_defaults
    6. "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION=1",
    7. + "-DALLOW_ADBD_ROOT=1",
    8. ],
    9. cpp_std: "experimental",
    10. @@ -112,7 +113,14 @@
    11. name: "adbd_defaults",
    12. defaults: ["adb_defaults"],
    13. - cflags: ["-UADB_HOST", "-DADB_HOST=0"],
    14. + cflags: [
    15. + "-UADB_HOST",
    16. + "-DADB_HOST=0",
    17. + "-UALLOW_ADBD_ROOT",
    18. + "-DALLOW_ADBD_ROOT=1",
    19. + "-DALLOW_ADBD_DISABLE_VERITY",
    20. + "-DALLOW_ADBD_NO_AUTH",
    21. + ],
    22. }
    23. cc_defaults {
    24. name: "host_adbd_supported",
    25. host_supported: true,
    26. target: {
    27. linux: {
    28. enabled: true,
    29. host_ldlibs: [
    30. @@ -606,6 +614,8 @@
    31. "libcrypto_utils",
    32. "libcutils_sockets",
    33. // APEX dependencies.
    34. "libadbd_auth",
    35. "libadbd_fs",
    36. "libcrypto",
    37. "liblog",
    38. ],
    39. + required: ["remount",],
    40. target: {
    41. android: {
    42. srcs: [
    43. "daemon/abb_service.cpp",
    44. "daemon/framebuffer_service.cpp",
    45. "daemon/mdns.cpp",
    46. "daemon/restart_service.cpp",
    47. ],
    48. shared_libs: [
    49. "libmdnssd",
    2.2 保持adb root用户级别

    说明:这个文件是adbd进程的主要入口点。我们需要修改should_drop_privileges函数,让它总是返回false,以防止它降低adbd进程的权限。should_drop_privileges() 修改强制返回false,保持adb root用户级别

    文件路径:qssi/packages/modules/adb/daemon/main.cpp
    详细修改:

    1. --- a/daemon/main.cpp
    2. +++ b/daemon/main.cpp
    3. @@ -74,6 +74,7 @@
    4. //
    5. // ro.secure:
    6. // Drop privileges by default. Set to 1 on userdebug and user builds.
    7. + return false;
    8. bool ro_secure = android::base::GetBoolProperty("ro.secure", true);
    9. bool ro_debuggable = __android_log_is_debuggable();

    3.允许adbd进程关闭Verity检查,关闭selinux

    3.1 允许adbd进程关闭Verity检查

    说明:这个文件定义了fs_mgr模块的编译选项和依赖项。fs_mgr模块负责管理设备上的文件系统。我们需要修改-DALLOW_ADBD_DISABLE_VERITY=0-DALLOW_ADBD_DISABLE_VERITY=1,以允许adbd进程关闭Verity检查。

    文件路径:qssi/system/core/fs_mgr/Android.bp
    详细修改:

    1. --- a/fs_mgr/Android.bp
    2. +++ b/fs_mgr/Android.bp
    3. @@ -109,7 +109,8 @@
    4. "libfstab",
    5. ],
    6. cppflags: [
    7. - "-DALLOW_ADBD_DISABLE_VERITY=0",
    8. + "-UALLOW_ADBD_DISABLE_VERITY",
    9. + "-DALLOW_ADBD_DISABLE_VERITY=1",
    10. ],
    11. product_variables: {
    12. debuggable: {
    13. @@ -237,7 +238,8 @@
    14. "fs_mgr_remount.cpp",
    15. ],
    16. cppflags: [
    17. - "-DALLOW_ADBD_DISABLE_VERITY=0",
    18. + "-UALLOW_ADBD_DISABLE_VERITY",
    19. + "-DALLOW_ADBD_DISABLE_VERITY=1",
    20. ],
    21. product_variables: {
    22. debuggable: {
    3.2 允许init进程编译方式

    说明:这个文件定义了init模块的编译选项和依赖项。init模块是设备启动时运行的第一个进程,负责初始化系统服务和属性。

    -DALLOW_FIRST_STAGE_CONSOLE=1:允许init进程在第一阶段打开控制台输出
    -DALLOW_LOCAL_PROP_OVERRIDE=1:允许init进程覆盖本地属性
    -DALLOW_PERMISSIVE_SELINUX=1:允许init进程设置SELinux为permissive模式
    -DREBOOT_BOOTLOADER_ON_PANIC=1:允许init进程在发生内核崩溃时重启到bootloader模式
    -DWORLD_WRITABLE_KMSG=1:允许init进程设置kmsg文件为可写
    -DDUMP_ON_UMOUNT_FAILURE=1:允许init进程在卸载分区失败时生成内存转储
    -DSHUTDOWN_ZERO_TIMEOUT=1:允许init进程在收到关机命令时立即执行

    文件路径:qssi/system/core/init/Android.bp

    详细修改:

    1. --- a/init/Android.bp
    2. +++ b/init/Android.bp
    3. @@ -136,13 +136,20 @@
    4. "-Wno-unused-parameter",
    5. "-Werror",
    6. "-Wthread-safety",
    7. - "-DALLOW_FIRST_STAGE_CONSOLE=0",
    8. - "-DALLOW_LOCAL_PROP_OVERRIDE=0",
    9. - "-DALLOW_PERMISSIVE_SELINUX=0",
    10. - "-DREBOOT_BOOTLOADER_ON_PANIC=0",
    11. - "-DWORLD_WRITABLE_KMSG=0",
    12. - "-DDUMP_ON_UMOUNT_FAILURE=0",
    13. - "-DSHUTDOWN_ZERO_TIMEOUT=0",
    14. + "-UALLOW_FIRST_STAGE_CONSOLE",
    15. + "-DALLOW_FIRST_STAGE_CONSOLE=1",
    16. + "-UALLOW_LOCAL_PROP_OVERRIDE",
    17. + "-DALLOW_LOCAL_PROP_OVERRIDE=1",
    18. + "-UALLOW_PERMISSIVE_SELINUX",
    19. + "-DALLOW_PERMISSIVE_SELINUX=1",
    20. + "-UREBOOT_BOOTLOADER_ON_PANIC",
    21. + "-DREBOOT_BOOTLOADER_ON_PANIC=1",
    22. + "-UWORLD_WRITABLE_KMSG",
    23. + "-DWORLD_WRITABLE_KMSG=1",
    24. + "-UDUMP_ON_UMOUNT_FAILURE",
    25. + "-DDUMP_ON_UMOUNT_FAILURE=1",
    26. + "-USHUTDOWN_ZERO_TIMEOUT",
    27. + "-DSHUTDOWN_ZERO_TIMEOUT=1",
    28. "-DINIT_FULL_SOURCES",
    29. "-DINSTALL_DEBUG_POLICY_TO_SYSTEM_EXT=0",
    30. ],
    31. @@ -394,13 +401,20 @@
    32. "-Wextra",
    33. "-Wno-unused-parameter",
    34. "-Werror",
    35. - "-DALLOW_FIRST_STAGE_CONSOLE=0",
    36. - "-DALLOW_LOCAL_PROP_OVERRIDE=0",
    37. - "-DALLOW_PERMISSIVE_SELINUX=0",
    38. - "-DREBOOT_BOOTLOADER_ON_PANIC=0",
    39. - "-DWORLD_WRITABLE_KMSG=0",
    40. - "-DDUMP_ON_UMOUNT_FAILURE=0",
    41. - "-DSHUTDOWN_ZERO_TIMEOUT=0",
    42. + "-UALLOW_FIRST_STAGE_CONSOLE",
    43. + "-DALLOW_FIRST_STAGE_CONSOLE=1",
    44. + "-UALLOW_LOCAL_PROP_OVERRIDE",
    45. + "-DALLOW_LOCAL_PROP_OVERRIDE=1",
    46. + "-UALLOW_PERMISSIVE_SELINUX",
    47. + "-DALLOW_PERMISSIVE_SELINUX=1",
    48. + "-UREBOOT_BOOTLOADER_ON_PANIC",
    49. + "-DREBOOT_BOOTLOADER_ON_PANIC=1",
    50. + "-UWORLD_WRITABLE_KMSG",
    51. + "-DWORLD_WRITABLE_KMSG=1",
    52. + "-UDUMP_ON_UMOUNT_FAILURE",
    53. + "-DDUMP_ON_UMOUNT_FAILURE=1",
    54. + "-USHUTDOWN_ZERO_TIMEOUT",
    55. + "-DSHUTDOWN_ZERO_TIMEOUT=1",
    56. "-DLOG_UEVENTS=0",
    57. "-DSEPOLICY_VERSION=30", // TODO(jiyong): externalize the version number
    58. ],
    3.3 关闭selinux 将enforce置为Permissive

    说明:这个文件实现了一些与SELinux相关的函数。我们需要修改IsEnforcing函数,让它总是返回false,以防止它检查系统属性或内核参数是否设置了SELinux的强制执行。

    文件路径:qssi/system/core/init/selinux.cpp
    详细修改:

    1. --- a/init/selinux.cpp
    2. +++ b/init/selinux.cpp
    3. @@ -123,6 +123,7 @@
    4. }
    5. bool IsEnforcing() {
    6. + return false;
    7. // close selinux for user version with root
    8. #if defined(LCT_BUILD_TYPE_FACTORY)
    9. return false;

    4.user 版本不允许 permissive domains

    说明:user 版本启用 overlayfs 来装载 remount 对应分区 user 版本不允许 permissive domains

    文件路径:system/sepolicy/Android.mk
    详细修改:

    1. --- a/Android.mk
    2. +++ b/Android.mk
    3. @@ -613,7 +613,7 @@
    4. ifneq ($(filter address,$(SANITIZE_TARGET)),)
    5. local_fc_files += $(wildcard $(addsuffix /file_contexts_asan, $(PLAT_PRIVATE_POLICY)))
    6. endif
    7. -ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
    8. +ifneq (,$(filter user userdebug eng,$(TARGET_BUILD_VARIANT)))
    9. local_fc_files += $(wildcard $(addsuffix /file_contexts_overlayfs, $(PLAT_PRIVATE_POLICY)))
    10. endif

    5.打开 USB 调试时默认授权,默认user版本编译remount。

    5.1 默认开启usb调试

    说明:默认开启usb调试。

    文件路径:build/make//core/main.mk
    详细修改:

    1. --- a/core/main.mk
    2. +++ b/core/main.mk
    3. @@ -365,11 +365,11 @@
    4. tags_to_install :=
    5. ifneq (,$(user_variant))
    6. # Target is secure in user builds.
    7. - ADDITIONAL_SYSTEM_PROPERTIES += ro.secure=1
    8. + ADDITIONAL_SYSTEM_PROPERTIES += ro.secure=0
    9. ADDITIONAL_SYSTEM_PROPERTIES += security.perf_harden=1
    10. ifeq ($(user_variant),user)
    11. - ADDITIONAL_SYSTEM_PROPERTIES += ro.adb.secure=1
    12. + ADDITIONAL_SYSTEM_PROPERTIES += ro.adb.secure=0
    13. endif
    14. ifeq ($(user_variant),userdebug)
    15. @@ -377,7 +377,7 @@
    16. tags_to_install += debug
    17. else
    18. # Disable debugging in plain user builds.
    19. - enable_target_debugging :=
    20. + enable_target_debugging := true
    21. endif
    22. # Disallow mock locations by default for user builds
    23. @@ -399,7 +399,7 @@
    24. ADDITIONAL_SYSTEM_PROPERTIES += dalvik.vm.lockprof.threshold=500
    25. else # !enable_target_debugging
    26. # Target is less debuggable and adbd is off by default
    27. - ADDITIONAL_SYSTEM_PROPERTIES += ro.debuggable=0
    28. + ADDITIONAL_SYSTEM_PROPERTIES += ro.debuggable=1
    29. endif # !enable_target_debugging
    30. ## eng ##
    5.2 添加remount

    说明:user版本默认不会编译remount,即system/bin/remount不存在,需要将remount添加到默认编译列表里面。

    文件路径:build/make/target/product/base_system.mk
    详细修改:

    1. --- a/target/product/base_system.mk
    2. +++ b/target/product/base_system.mk
    3. @@ -287,6 +287,7 @@
    4. wificond \
    5. wifi.rc \
    6. wm \
    7. + remount \
    8. ifneq ($(TARGET_HAS_LOW_RAM), true)
    9. PRODUCT_PACKAGES += \
    10. @@ -388,7 +389,6 @@
    11. procrank \
    12. profcollectd \
    13. profcollectctl \
    14. - remount \
    15. servicedispatcher \
    16. showmap \
    17. sqlite3 \

    总结

    通过以上的修改,我们可以在Android 13上实现root功能。

    希望这篇博客能对你有所帮助,如果你有任何问题或建议,欢迎留言讨论。谢谢!

  • 相关阅读:
    Web前端开发的五大核心技能
    L1-035 情人节 c++解法
    【工程光学】光度学&色度学
    函数指针与回调函数
    1.servlet规范简单整理
    哈希冲突概念及其四种解决方案
    在 React 中创建带有突出显示的目录
    王道链表综合题(下)
    RestTemplate上传文件
    grpc多语言通信之GO和DART
  • 原文地址:https://blog.csdn.net/mafei852213034/article/details/132765910