[Description]
android KK 4.4 版本后,user 版本su 权限严重被限制, 如无法直接访问data 区域,无法直接remount system image, 无法设置system property
[Keyword]
KK, 4.4, user 版本, su, root
[Solution]
Google 不遗余力的提高android系统的安全性, 而针对su 这个即令人恨,又令人爱的命令,就痛下杀手。下面我从三个方面说明.
1. 限制user 版本adbd process 的capabilities bound set. 循环CAPBSET_DROP 动作,将Process 的root capabilities 进行了强行限制。仅仅保留了CAP_SETUID, CAP_SETGID 这两项,用于run-as 使用,可参考alps/system/core/adb/adb.c 中的 drop_capabilities_bounding_set_if_need 函数。
这样导致的情况是,在user 版本中usb debug 的su 受到极大的限制,仅仅能够模拟对应的uid/gid, 而无法拿去真正的root 权限.
2. 限制所有app 的capabilities bound set, 在android 4.4 上,zygote fork app 时,特意对所有fork 出来的子进程,进行了CAPBSET_DROP 动作,将Process 的root capabilities 进行了强行限制。 使得即使这些APK 徒有Root 权限,而无真实的capabilites. 在4.4.4 以及L 版本上, 还会使用prctl 下PR_SET_NO_NEW_PRIVS 指令, 限制子进程权限的提升.
这样导致的情况是, app 执行su 时,其权限受到了严格的管控,比如无法逃脱DAC 权限管控。但因为依旧具有root uid/gid, 所以在framework 层的permission 限制上依旧畅通无阻。
详情请参考FAQ: https://online.mediatek.com/Pages/FAQ.aspx?List=SW&FAQID=FAQ11538
3. SElinux 权限限制。 在user 版本上,没有导入有效的SU SElinux policy, 这样一旦本身受SElinux 限制的process 使用su 时,同样会受到SElinux 的限制。
(3.1). 在KK 版本只有4个process 会受到此影响,即zygote, netd, installd, vold.
消除这种限制的手法即是external/sepolicy/android.mk 里面的
ifeq ($(TARGET_BUILD_VARIANT),user)
BOARD_SEPOLICY_IGNORE+=external/sepolicy/su.te
else
BOARD_SEPOLICY_IGNORE+=external/sepolicy/su_user.te
endif
更新成:
ifeq ($(TARGET_BUILD_VARIANT),user)
BOARD_SEPOLICY_IGNORE+=external/sepolicy/su_user.te
else
BOARD_SEPOLICY_IGNORE+=external/sepolicy/su_user.te
endif
(3.2). 在L 版本则所有的Process 都会受到这样的影响.
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' $@ > $@.dontaudit
将-D target_build_variant=$(TARGET_BUILD_VARIANT) 改成 -D target_build_variant=eng