溺的文档
KernelSU · 第 6 篇 / 共 8 篇

KernelSU 高级特性与安全

2026-06-30 · 阅读 2

本章探讨 KernelSU 的高级特性、安全设计与潜在风险,对应当前重构后的代码。基础实现请先参阅 内核层实现

1. App Profile 高级特性

App Profile 允许为每个应用定制独特的 root 环境,是 KernelSU 最强大的特性。结构定义见 用户空间实现 §2.3(uapi/app_profile.h,v4),提权应用见 内核层实现 §3.3(escape_with_root_profile)。

1.1 可定制项

维度 字段 说明
身份 uid / gid 提权后的目标 UID/GID(可不为 0,如以 shell=2000 运行受限 root)
附加组 groups[≤32] 硬件/资源访问(graphics=1003、audio=1005、inet=3003 等)
能力 capabilities.effective 精确裁剪 capabilities,默认 CAP_FULL_SET
SELinux selinux_domain 目标 domain,默认 u:r:ksu:s0(不再是 u:r:su:s0
命名空间 namespaces INHERITED(0) / GLOBAL(1) / INDIVIDUAL(2)(见 Android 安全机制与绕过 §6.2)
标志 flags 目前仅 FLAG_KSU_NO_NEW_PRIVS

最小权限示例(只给网络相关能力 + inet 组):

allow_su = true
uid = 0, gid = 0
groups = [0, 3003]                       // root + inet
capabilities.effective = CAP_NET_ADMIN | CAP_NET_RAW
selinux_domain = "u:r:ksu:s0"
namespaces = GLOBAL                       // 能看到模块挂载

1.2 NO_NEW_PRIVS 标志

FLAG_KSU_NO_NEW_PRIVSflags 首位):提权完成后,escape_with_root_profileset_thread_flag(TIF_KSU_DISABLE_ESCAPE_WITH_ROOT)(线程标志 bit 63),禁止该线程再次提权。这是给"拿一次 root 后就应降权固化"的场景用的防护。userspace 也可通过 IOCTL DISABLE_ESCAPE_TO_ROOT(ksud su --ksu-no-new-privs)主动设置。

1.3 模板系统

rp_configtemplate_name:多个应用可引用同一模板统一配置。注意:模板本身(以及 App Profile 的 sepolicy 文本 rules)存储在 ksud 一侧/data/adb/ksu/profile/templates//profile/selinux/),由 ksud profile list-templates/get-template/set-template 管理;而 profile 结构体(uid/caps/domain 等)经 JNI IOCTL 写入内核。这就是 用户空间实现 §5.4 提到的"双通路"。

1.4 Non-Root Profile 与全局默认

不授 root 的应用用 nrp_config,目前只有 umount_modules(是否对其卸载模块)。默认 umount_modules=true(默认对非 root 应用隐藏模块)。

特殊条目 uid=9999 / key="$" 承载"全局默认非 root profile":写它即修改 default_non_root_profile.umount_modules(Manager 的"默认卸载模块"开关)。该条目在 prune 时被保留。

2. Feature 系统(运行时可开关)

policy/feature.c 提供 feature 框架,userspace 经 IOCTL GET/SET_FEATURE 运行时开关五个特性。其中 su_compatlibsu 与 su 兼容层,此处详解其余四个。

2.1 kernel_umount(feature/kernel_umount.c,默认开)

内核态在每次 zygote→app/isolated 进程的 setresuid 后,于该进程的 mount namespace 中卸载模块挂载,实现"未授权应用看不到模块"。完整逻辑(前置 zygote 校验、mount_listoverride_creds(ksu_cred))见 Android 安全机制与绕过 §6.3。待卸载路径由 IOCTL ADD_TRY_UMOUNT 维护(通常由 metamodule 在挂载后登记)。

2.2 selinux_hide(feature/selinux_hide.c,默认关)

针对"检测 SELinux 是否被 KernelSU 篡改"的应用,对应用进程(uid≥10000)伪造 SELinux 视图。开启时做三件事(基于 backup_sepolicy——注入 ksu 规则之前的策略副本):

  1. hook selinuxfs 的 write_op:把 write_op[SEL_CONTEXT]/[SEL_ACCESS] 换成自定义实现,对 app 用 backup_sepolicy 而非当前内核策略来做 context↔sid 转换和 av 决策——使 /sys/fs/selinux/context/sys/fs/selinux/access 的校验结果与"未打补丁"一致;
  2. hook LSM selinux_setprocattr(KernelSU 唯一用到的 LSM hook):app 写 /proc/self/attr/current 时用 backup_sepolicy 校验;
  3. hook sel_handle_status_ops.open:对 app 返回伪造的 SELinux status 页(fake_status,late-load 且 permissive 时把 enforcing 显示为 1),骗过 mmap /sys/fs/selinux/status 的检测。

6.6+ 内核里 KernelSU 自带了一份 SELinux 内部函数(string_to_context_structsecurity_compute_av_user_with_policy 等)的复制实现,因为这些未导出,需要自己基于 backup_sepolicy 计算。boot_completed 后若未启用则 drop_backup_if_unused 释放副本省内存。

2.3 adb_root(feature/adb_root.c,默认关)

adb shell 默认获得 root。当检测到 init 派生进程 execve 目标以 /adbd 结尾时(ksu_adb_root_handle_execve):

  1. 校验 /data/adb/ksu/lib/libadbroot.so 存在;
  2. setup_ld_preload:在用户栈上构造并把 LD_PRELOAD=/data/adb/ksu/lib/libadbroot.soLD_LIBRARY_PATH=/data/adb/ksu/lib 追加进 adbd 的 envp;
  3. escape_to_root_for_adb_root() 给 adbd 提权。

libadbroot.so 由 Manager 的 adbroot.cc 编译,经 ksud install --libadbroot <path> 安装。

2.4 sulog(feature/sulog.c + sulog/,默认关)

su 操作审计日志。捕获三类事件(uapi/sulog.h):

事件 触发
ROOT_EXECVE (1) root 进程 execve(记录 filename + argv)
SUCOMPAT (2) su 兼容路径触发(escape 前捕获,escape 后 emit)
IOCTL_GRANT_ROOT (3) 经 IOCTL 授权 root

机制:内核把事件扁平化成定长 payload 推入 infra/event_queue(环形队列,上限 256 条、单条 2048 字节,满则记丢弃计数);userspace 经 IOCTL GET_SULOG_FD(only_root)拿到匿名只读 fd [ksu_sulog]单消费者)poll/read 消费。ksud 的 sulogd 守护进程读取并写入 /data/adb/ksu/log/sulog-*.log(日切+轮转)。开启 sulog feature 时 ksud 会自动拉起 sulogd

3. 模块系统进阶

早期实现是 ksud 直接用 OverlayFS 挂载模块;当前已改为 metamodule + meta-overlayfs 解耦架构。基础见 用户空间实现 §4。

3.1 metamodule 与 meta-overlayfs

  • ksud 自身不做 OverlayFS 挂载,而是委托给唯一活动的 metamodulemodule.propmetamodule=1,并在 /data/adb/metamodule 建 symlink);
  • metamodule 提供 metamount.sh(挂载/overlayfs 入口)、metainstall.sh(普通模块安装 hook)、metauninstall.sh 及各 stage 脚本;
  • 每个 init 阶段,metamodule 脚本优先于普通模块执行;
  • 这把"如何叠加模块到系统分区"变成可插拔策略(userspace/meta-overlayfs),让模块系统不绑死某种挂载方式。

3.2 模块状态与 preinit rc

模块状态用空文件标记(disable/remove/update/skip_mount);安装走 modules_update/ 暂存 → post-fs-data 搬到 modules/。各启用模块的 initrc/*.rc 由 ksud 拼接成 /metadata[/watchdog]/ksu/modules.rc,内核 init.rc 注入 hook 在下次开机把它拼进 init.rc(见 §4.1、内核层实现 runtime)。

3.3 模块配置与 feature 托管

ksud 的模块配置系统(/data/adb/ksu/module_configs/<id>/,persist + temp 两层)支持:

  • override.description:覆盖模块描述;
  • manage.<feature>=true:声明该模块"托管"某内核 feature——之后只有该模块(KSU_MODULE 环境变量匹配)能改这个 feature,ksud feature set 直接命令会被拒绝。用于让模块独占管理某项内核行为。

4. 启动形态:GKI 与 LKM

KernelSU 有两种安装形态,对应 内核层实现 §1.2 的两条初始化路径。

4.1 GKI 模式(boot 内置)

ksud boot-patch 用内嵌的 android-bootimg 修补 boot 镜像:

  1. 解包 boot,取 ramdisk cpio;
  2. ksuinit 替换 ramdisk 的 /init(原 init 改名 init.real),并把对应 KMI 的 <kmi>_kernelsu.ko 加为 /kernelsu.ko
  3. 维护 cpio 内 ksu_confignorc/allow_shell 等);
  4. 重打包,--flash 写回块设备(do_backup 按 sha1 备份原 boot),--ota 切 slot。

开机时 ksuinit#![no_main])先挂 /proc/sys,加载 /kernelsu.ko(此时模块以 pid==1 加载 → ksu_late_loaded=false,走正常路径并注入 init.rc),再 execve 真正的 init。boot-restore 从备份还原。

4.2 LKM 运行时加载(late-load)

ksud late-load 在系统已启动后加载内核模块:用 ksuinit::load_module(解析 ELF 未定义符号,逐行读 /proc/kallsyms 手动重定位init_module)加载 <kmi>_kernelsu.ko。此时 current->pid != 1ksu_late_loaded=true,走 late-load 路径(立即 apply rules / cache sid / escape / 强制 enforce,不注入 init.rc),随后跑全套 stage 并重启 Manager。

4.3 magica(adb root 越狱注入)

ksud late-load --magica <port>:在受限 root(magica 提供)下临时开启 adb tcp root(设 ro.debuggable=1 等 prop + 重启 adbd),用 adb_client 自连,再通过 adb shell 在完整 root + ksu 域下执行 late-load --post-magica 加载 ko,完成后还原 adb 相关 prop。用于不补 boot 的情况下注入 KernelSU。

5. 安全特性

5.1 Manager 认证(纯 V2 签名)

只接受纯 V2 签名的 Manager APK:V2 块必须恰好 1 个,存在 V1(JAR) 共存或任何 V3/V3.1 即拒绝。期望证书 SHA-256 与长度由构建脚本注入到 kernel/Makefile。详见 内核层实现 §5.2。Manager 身份以 appid(uid%100000)记录,支持更新/重装/多用户场景,并由 fsnotify 监听包变化自动重扫。

5.2 安全模式

按住音量下键开机触发:内核 kprobe input_event 统计 KEY_VOLUMEDOWN 按下次数,≥3 次即进入安全模式(IOCTL CHECK_SAFEMODE 查询)。ksud 在 post-fs-data 检测到安全模式时 disable_all_modules()(禁用所有模块),用于从模块导致的 bootloop 中恢复。

5.3 权限检查层级

supercall 的 4+1 类权限检查(always_allow/only_root/only_manager/manager_or_root/allowed_for_su)见 内核层实现 §4.3。关键约束:

  • App Profile 读写仅 Manager(only_manager);
  • sepolicy 注入、sulog fd、事件上报仅 root;
  • GRANT_ROOT 需 allowed_for_su(Manager 或已授权 uid)。

5.4 防提权约束

  • uid==0 域校验__ksu_is_allow_uid_for_current 在 uid==0 时返回 is_ksu_domain()——只有处于 ksu domain 的 root 才算"被允许",防止任意 root 进程冒用接口;
  • 系统 uid 保护forbid_system_uid(uid<2000 且 ≠1000 直接拒);
  • NO_NEW_PRIVS:见 §1.2,提权后可禁止再次提权;
  • zygote 前置校验:模块卸载前必须确认旧进程是 zygote(见 Android 安全机制与绕过 §6.3),防止误卸载破坏系统。

6. 反检测能力

手段 实现
selinux_hide 对 app 伪造 SELinux 状态页/上下文校验(§2.2)
模块卸载 未授权应用看不到模块修改(kernel_umount)
ext4 sysfs 清理 IOCTL NUKE_EXT4_SYSFSext4_unregister_sysfs,移除模块 ext4 镜像痕迹
匿名通信 [ksu_driver] 匿名 inode + IOCTL,无 /dev 节点
模块自隐藏 非 debug LKM 在 init 末尾 kobject_del/sys/module 摘除
file_wrapper [ksu_fdwrapper] 包装 fd,inode sid 设为 ksu_file_sid 绕 SELinux(su tty 用)
避开 hypervisor 内存改写用 fixmap+stop_machine 而非改 PTE,避开 MTK MKP 等保护

7. 潜在风险与缓解

风险 缓解
内核稳定性(panic/兼容) 构建期 check_symbol 校验 .ko 依赖符号都在 vmlinux;fixmap 避开 hypervisor;大量 LINUX_VERSION_CODE 版本分支;RCU + kref 保护数据结构
权限滥用 Manager 纯 V2 认证;per-app profile 限权;NO_NEW_PRIVS;可选 sulog 审计
检测对抗 selinux_hide、模块卸载、匿名通信、自隐藏;与检测方持续博弈
版本兼容 kallsyms + CFI 符号解析动态适配;GKI/LKM 双形态;KMI 检测

8. 最佳实践

应用开发者:遵循最小权限(只申请必要 capabilities/groups);明确告知用户用途;用完及时降权或 NO_NEW_PRIVS。

Manager 使用者:默认拒绝、按需授权;为不信任的敏感应用保持"卸载模块";用 sulog 审计授权;遇 bootloop 用安全模式恢复。

模块开发者:遵循 metamodule 约定;用 initrc/*.rc 做 preinit 注入;需要独占内核 feature 时用 manage.<feature> 托管;WebUI 用 kernelsu js 库(见 libsu 与 su 兼容层)。

9. 总结

特性 实现要点
App Profile v4 结构,可定制 uid/gid/groups/caps/domain/namespace/flags + 模板
Feature 系统 su_compat / kernel_umount / selinux_hide / adb_root / sulog 运行时开关
模块系统 metamodule + meta-overlayfs 解耦,空文件标记状态,preinit rc
启动形态 GKI(boot-patch + ksuinit)与 LKM(late-load / magica)
安全 纯 V2 认证、音量键安全模式、uid==0 域校验、NO_NEW_PRIVS、zygote 校验
反检测 selinux_hide、模块卸载、ext4 sysfs 清理、匿名通信、自隐藏

附录:文档导航

  1. 架构概述
  2. 内核层实现
  3. Android 安全机制与绕过
  4. 用户空间实现
  5. 关键流程分析
  6. 高级特性与安全(本文档)
  7. libsu 与 su 兼容层

评论

  • 还没有评论,来说点什么吧。

无需注册或登录,填个昵称即可评论。