Android U user+root实现方案
背景
由于项目(MTK平台)上要实现user+root的版本,供特殊用户使用。Android T上的方案无效,经历了各种搜索查看资料,和bsp大佬一起通宵奋战,整出了方案。梳理记录下,有需要的同学可以参考。
(图片来源网络,侵删)
Root代码实现原理
系统判断是否有root权限的地方在system/packages/modules/adb/daemon/main.cpp里面,
should_drop_privileges()函数返回false,表明可以root。
auth_required 是否需要adb鉴权(adb弹框确认),false时默认授权adb鉴权权限,不需要弹框确认。
userdebug 版本可以root是因为ro.secure = 0,代码路径build/core/main.mk 在should_drop_privileges()里面有判断
else # !user_variant # Turn on checkjni for non-user builds. ADDITIONAL_SYSTEM_PROPERTIES += ro.kernel.android.checkjni=1 # Set device insecure for non-user builds. ADDITIONAL_SYSTEM_PROPERTIES += ro.secure=0
static bool should_drop_privileges() { // The properties that affect `adb root` and `adb unroot` are ro.secure and // ro.debuggable. In this context the names don't make the expected behavior // particularly obvious. // // ro.debuggable: // Allowed to become root, but not necessarily the default. Set to 1 on // eng and userdebug builds. // // ro.secure: // Drop privileges by default. Set to 1 on userdebug and user builds. bool ro_secure = android::base::GetBoolProperty("ro.secure", true); bool ro_debuggable = __android_log_is_debuggable(); // Drop privileges if ro.secure is set... bool drop = ro_secure; // ... except "adb root" lets you keep privileges in a debuggable build. std::string prop = android::base::GetProperty("service.adb.root", ""); bool adb_root = (prop == "1"); bool adb_unroot = (prop == "0"); if (ro_debuggable && adb_root) { drop = false; } // ... and "adb unroot" lets you explicitly drop privileges. if (adb_unroot) { drop = true; } return drop; }
实现中遇到的问题
1,selinux问题(主要解决问题);
2,缺少su 和remount执行的bin文件;
具体实现方案和步骤
1),特殊版本标识,CUSTOM_ROOT_VERSION=yes,编译版本时需要export下该环境变量
2),添加flag,路径build/core/soong_config.mk
--- a/core/soong_config.mk +++ b/core/soong_config.mk @@ -58,6 +58,9 @@ $(call add_json_bool, Debuggable, $(filter userdebug eng,$(TARGET_BUILD_VARIANT))) $(call add_json_bool, Eng, $(filter eng,$(TARGET_BUILD_VARIANT))) +$(call add_json_bool, ROOTVersion, $(filter yes,$(CUSTOM_ROOT_VERSION))) $(call add_json_str, DeviceName, $(TARGET_DEVICE))
3),添加root版本的数据声明,设置root相关的flag需要
--- a/android/variable.go +++ b/android/variable.go @@ -151,6 +151,14 @@ } } + ROOTVersion struct { + Cflags []string + Cppflags []string + Init_rc []string + } Pdk struct { Enabled *bool `android:"arch_variant"` } `android:"arch_variant"` @@ -315,6 +323,9 @@ UseRBED8 *bool `json:",omitempty"` Debuggable *bool `json:",omitempty"` Eng *bool `json:",omitempty"` + ROOTVersion *bool `json:",omitempty"` Treble_linker_namespaces *bool `json:",omitempty"`
4),添加su 和 remount 模块,在产品的mk文件中添加
PRODUCT_PACKAGES +=remount
PRODUCT_PACKAGES +=su
5),在文件系统模块fs_mgr中添加ROOTVersion相应的flag,property_service中设置ro.secure和ro.debuggable的值
--- a/fs_mgr/Android.bp +++ b/fs_mgr/Android.bp @@ -118,6 +118,14 @@ "-DALLOW_ADBD_DISABLE_VERITY=1", ], }, + ROOTVersion: { + cppflags: [ + "-UALLOW_ADBD_DISABLE_VERITY", + "-DALLOW_ADBD_DISABLE_VERITY=1", + ], + }, }, header_libs: [ "libfiemap_headers", @@ -248,6 +256,17 @@ "clean_scratch_files.rc", ], }, + ROOTVersion: { + cppflags: [ + "-UALLOW_ADBD_DISABLE_VERITY", + "-DALLOW_ADBD_DISABLE_VERITY=1", + ], + init_rc: [ + "clean_scratch_files.rc", + ], + }, }, symlinks: [ "clean_scratch_files", --- a/init/Android.bp +++ b/init/Android.bp @@ -149,6 +149,13 @@ "-DSHUTDOWN_ZERO_TIMEOUT=1", ], }, + ROOTVersion: { + cppflags: [ + "-DROOT_VERSION", + ], + }, uml: { cppflags: ["-DUSER_MODE_LINUX"], }, --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -1328,6 +1328,19 @@ } } + bool adbAuthorized = false; +#ifdef ROOT_VERSION + adbAuthorized = true; +#endif + if (adbAuthorized) { + InitPropertySet("ro.adb.secure", "0"); + InitPropertySet("ro.debuggable", "1"); + } + for (const auto& [name, value] : properties) {
6)adb模块添加权限的判断,和5)中设置属性的值有重复,此处是为了确保生效。有时间的同学可以验证下去掉这一步看是否生效。
should_drop_privileges()函数最后添加
#ifdef CUSTON_ROOT_VERSION return false; #endif
drop_privileges()函数最后添加
#ifdef CUSTON_ROOT_VERSION auth_required=false; #endif
7),最重要的一步,更换sepolicy文件为debug版本的
(1)添加sepolicy,src文件是debug版本的,修改路径system/sepolicy/android.bp
--- a/Android.bp +++ b/Android.bp }, } +se_policy_cil { + name: "userdebug_plat_sepolicy_root.cil", + src: ":userdebug_plat_sepolicy.conf", + additional_cil_files: [":sepolicy_technical_debt{.plat_private}"], + dist: { + targets: ["droidcore"], + }, +} + // A copy of the userdebug_plat_policy in GSI.
(2),同路径下mk文件加入编译
--- a/Android.mk +++ b/Android.mk LOCAL_REQUIRED_MODULES += \ userdebug_plat_sepolicy.cil \ +ifeq ($(strip $(CUSTOM_ROOT_VERSION)),yes) +LOCAL_REQUIRED_MODULES += \ + userdebug_plat_sepolicy_root.cil +endif
(3)代码中加载sepolicy地方GetUserdebugPlatformPolicyFile()也使用上面生成的sepolicy文件,代码路径system/core/init/selinux.cpp
std::optional GetUserdebugPlatformPolicyFile() { +#ifdef DF_VERSION + return "/system/etc/selinux/userdebug_plat_sepolicy_root.cil"; +#endif
至此,Android U版本user+root+remount方案修改完成。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。