KernelSU 深度解析:基于内核的 Android root 方案与可定制特权架构
【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU
KernelSU 是一款运行在 Linux 内核态的 Android root 解决方案,面向 GKI(Generic Kernel Image)设备设计。本文以其官方站点首页(website/docs/pt_BR/index.md)所归纳的四大核心特性为主线——基于内核的实现、root 访问控制、可定制的 root 特权、Metamodule 元模块系统——结合仓库内核源码与用户态实现,逐层拆解其架构设计与实战配置,帮助读者理解 KernelSU 与 Magisk 等传统方案的差异,并掌握 App Profile、Metamodule 等核心机制的配置方法。
一、基于内核:root 能力全部在内核态实现
KernelSU 的核心设计理念是Kernel-based——正如站点首页所述:"KernelSU 运行在 Linux 内核中,从而对用户态应用拥有更强的控制能力"(website/docs/pt_BR/index.md)。
与传统在用户态(如通过 init 进程或 daemon)实现 root 的方案不同,KernelSU 将权限判定、su 实现、SELinux 规则加载等逻辑全部下沉到内核态。官方介绍文档指出,这种"内核模式"提供了一系列以往难以获得的内核接口能力,例如:
- 在内核态为任意进程添加硬件断点;
- 以不可见的方式访问任意进程的物理内存;
- 在内核空间拦截任意系统调用(syscall)。
这些能力在仓库源码中均有对应实现:系统调用拦截逻辑位于 kernel/hook/arm64/syscall_hook.c 与 kernel/hook/x86_64/syscall_hook.c,通过 kernel/hook/syscall_hook_manager.c 统一管理;LSM(Linux Security Module)挂钩与 setuid 挂钩分别位于 kernel/hook/lsm_hook.c 与 kernel/hook/setuid_hook.c。可见,KernelSU 的能力边界直接建立在内核机制之上,这也是它与用户态 root 方案在检测面、稳定性上产生本质差异的根源。
二、Root 访问控制:只有被允许的应用才能感知 su
首页将"Root access control"列为第二大特性:只有被授权的应用可以访问或看到su,其余应用对此一无所知。这意味着 root 权限的授予不是"应用主动申请、系统被动放行",而是由内核根据白名单主动判定。
从源码看,这一机制由内核策略模块实现,核心文件为 kernel/policy/allowlist.c:
- 白名单数据结构:内核以 RCU 哈希表
allow_list维护所有应用配置文件(struct app_profile),并在变更时通过ksu_persistent_allow_list()将整个白名单序列化写入/data/adb/ksu/.allowlist文件(包含文件魔数0x7f4b5355与格式版本号),下次启动时由ksu_load_allow_list()重新加载; - 权限判定入口:
__ksu_is_allow_uid()是核心判定函数——系统级 UID(小于 2000 且非 1000)直接拒绝;Manager 应用(is_uid_manager)永远放行;其余应用只在白名单中存在且allow_su == true时才被允许; - Manager 身份识别:在 kernel/manager/manager_identity.h 中,内核通过
ksu_manager_appid记录 Manager 应用的 appid,以current_uid().val % KSU_PER_USER_RANGE的方式识别(KSU_PER_USER_RANGE为 100000,对应 Android 多用户 UID 分段),is_manager()用于判定当前进程是否为 Manager 进程; - 默认非 root 行为:在
init_default_profiles()中,默认非 root 配置的umount_modules = true(见 kernel/policy/allowlist.c),即默认对未授权应用卸载模块挂载点。
从"默认非 root 应用完全感知不到 root 与模块改动"这一设计可以看出,KernelSU 将"隐藏"与"最小暴露"作为访问控制的基本盘,而不仅是简单的授权开关。
三、可定制的 root 特权:App Profile / Root Profile
首页第三大特性是Customizable root privileges:"KernelSU 允许定制 su 的 uid、gid、groups、capabilities 与 SELinux 规则,从而加固 root 特权"。
这套机制在官方文档中被称为App Profile(website/docs/pt_BR/guide/app-profile.md)。对于被授予 root 权限的应用,其对应的配置文件即Root Profile,可定制执行su后进程的uid、gid、groups、capabilities与 SELinux 域,实现最小权限原则。
3.1 内核中的数据结构
App Profile 的完整结构定义在 UAPI 头文件 kernel/include/uapi/app_profile.h(manager 侧的镜像位于 manager/app/src/main/cpp/uapi/app_profile.h),关键字段如下:
version:配置文件版本号,当前为KSU_APP_PROFILE_VER 4;key:通常是应用包名,最长KSU_MAX_PACKAGE_NAME(256 字节);curr_uid:应用当前 UID;allow_su:是否允许使用 su;rp_config(root 配置):包含use_default(是否使用默认 root 配置)、template_name(可引用模板)、以及root_profile结构;nrp_config(非 root 配置):use_default与umount_modules(是否卸载模块挂载)。
struct root_profile则具体承载可定制项:
uid/gid:__s32类型,指定 su 后进程的用户与组;groups[KSU_MAX_GROUPS]:补充组列表,最多支持 32 个组(KSU_MAX_GROUPS);capabilities:effective / permitted / inheritable 三组 64 位能力位图;selinux_domain[KSU_SELINUX_DOMAIN]:SELinux 域字符串,最长 64 字节;namespaces:命名空间策略(默认KSU_NS_INHERITED);flags:可启用FLAG_KSU_NO_NEW_PRIVS(1ULL << 0)。
内核在ksu_set_app_profile()中对配置进行校验(版本、key 长度、groups 数量、SELinux 域合法性),并通过ksu_get_root_profile()在 su 授权时读取生效配置(见 kernel/policy/allowlist.c)。
3.2 uid / gid / groups:把"root"降级为 shell
在 Linux/Android 中,UID 0 是 root 用户,GID 0 是 root 组;Android 每个应用是一个独立用户:0为 root、1000为 system、2000为 ADB shell、10000~19999为普通应用区间(工作资料通过 UID 区间分段实现,如110000~119999)。官方文档给出了一个典型示例——在 ADB shell 中执行id:
oriole:/ $ id uid=2000(shell) gid=2000(shell) groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid),3012(readtracefs) context=u:r:shell:s0Root Profile 可以做到:某 root 应用的 Root Profile 将 uid 设为2000,则它执行su后实际权限只是 ADB shell 级别;再移除inet组(对应网络访问权限),则该 su 进程无法访问网络。需要特别注意的是,App Profile只控制 su 进程本身的权限,不控制应用自身权限——应用若已申请网络权限,即使不给 su 加inet组,它自己仍能联网。
3.3 Capabilities:拆分 root 特权
Linux 2.2 起将超级用户的特权拆分为独立的能力单元(capabilities)。例如CAP_DAC_READ_SEARCH表示绕过文件读取及目录读/执行权限检查的能力;若 UID 为 0 的进程缺少该能力,即使是 root 也无法随意读取文件。
Root Profile 的capabilities三组位图(effective / permitted / inheritable)正是为此设计:某些 root 应用必须保持 UID 0,此时通过裁剪 capabilities 限制其操作集合,比"一刀切"的全量 root 更安全。官方强烈建议先阅读 Linux capabilities 手册(man capabilities)再定制。
3.4 SELinux 域:MAC 级细粒度控制
SELinux 是强制访问控制(MAC)机制,遵循默认拒绝原则。Root Profile 可将 su 进程从默认的无限制域(如u:r:ksu:s0)切换到自定义域(如u:r:app1:s0),并为该域编写专用规则:
type app1 enforce app1 typeattribute app1 mlstrustedsubject allow app1 * * *注意:allow app1 * * *仅用于演示,实际不应大规模使用,否则与 Permissive 模式无异。内核侧的默认域常量定义在 kernel/policy/allowlist.c 中:KSU_DEFAULT_SELINUX_DOMAIN "u:r:" KERNEL_SU_DOMAIN ":s0"。
3.5 提权风险(Escalation)与 NO_NEW_PRIVS
Root Profile 配置不当可能引发提权逃逸。官方给出的典型案例:若已授予 ADB shell(UID 2000)root 权限,同时将一个普通应用的 Root Profile 的 uid 设为 2000,则该应用可连续执行两次su获得完整 root:第一次su切换到 UID 2000,第二次su因 UID 2000 已被授权而获得完整 root。
缓解手段是开启FLAG_KSU_NO_NEW_PRIVS(对应app_profile.h中的flags位)。但该标志只能阻止 KernelSU 再次为该进程提权,进程仍可能通过其他 Linux 机制逃逸,因此权限设置务必谨慎。
3.6 非 root 配置:Umount modules
对于未获 root 权限的普通应用,App Profile 可控制内核与模块系统对它们的表现——典型配置项是umount_modules(卸载模块挂载)。由于模块通过 OverlayFS 等方式修改/system,部分对系统完整性敏感的应用会因此异常,可通过"卸载模块挂载"来规避。Manager 设置中提供"默认卸载模块"选项(默认开启),两种策略:
- 保持默认开启,在需要加载模块的应用的 App Profile 中单独关闭(白名单思路);
- 关闭默认选项,在需要卸载模块的应用中单独开启(黑名单思路)。
从源码看,内核通过ksu_uid_should_umount()决策(见 kernel/policy/allowlist.c):Manager 永不卸载;有白名单记录且允许 su 的应用不卸载;其余按默认配置或应用专属配置决定。官方文档还提示:内核 5.10 及以上版本内核会直接执行卸载动作,低于 5.10 的设备需自行 backportpath_umount(fs/namespace.c)才有实际效果。
四、Metamodule:可插拔的模块基础设施
首页第四大特性是Metamodule system:"可插拔的模块基础设施允许对 /system 进行 systemless 修改;安装 meta-overlayfs 之类的 metamodule 即可启用模块挂载"。这一机制在 website/docs/pt_BR/guide/metamodule.md 中有完整论述。
4.1 什么是 Metamodule
Metamodule 是一种特殊的 KernelSU 模块,为普通模块提供基础设施服务:普通模块负责"修改什么文件",metamodule 负责"如何安装与挂载"(metamount.sh、metainstall.sh、metauninstall.sh三个 hook 脚本分别覆盖挂载、安装、清理)。核心特征:
- 基础设施角色:普通模块的运行依赖 metamodule 提供的服务;
- 单实例约束:同一时刻只能安装一个 metamodule;
- 优先执行:metamodule 脚本先于普通模块脚本执行;
- 三个 hook:覆盖安装、挂载与清理三个阶段。
设计动机在于:传统 root 方案把挂载逻辑内置在核心中,既容易被检测、又难以演进。KernelSU 通过"关注点分离"把挂载实现外包给插件:内核自身不做挂载(降低检测面)、核心 daemon 保持稳定、社区可以独立演进挂载策略(overlayfs / magic mount / FUSE / 自定义 VFS 挂载等),用户按需选择实现。
4.2 用户视角:安装、验证与卸载
安装 metamodule 与安装普通模块完全一致:下载 ZIP(如meta-overlayfs.zip)→ 打开 KernelSU Manager → 点击悬浮按钮(➕)→ 选择 ZIP → 重启设备。安装后可在 Manager 的模块列表页看到带特殊标记的 metamodule。卸载时有醒目的危险提示:卸载 metamodule 会影响所有模块——重启后模块将不再挂载,直到安装新的 metamodule。由于单实例约束,切换 metamodule 需按"卸载全部普通模块 → 卸载 metamodule → 重启 → 安装新 metamodule → 重装普通模块 → 重启"的顺序进行。
关键提醒:没有安装 metamodule 时,模块不会被挂载。因此全新安装 KernelSU 后,若需使用带文件改动的模块,必须先行安装 metamodule;仅使用脚本、sepolicy 或 system.prop 的模块则不需要。
4.3 开发者视角:如何编写 Metamodule
一个 metamodule 由module.prop中的metamodule=1(或metamodule=true)标识,无该属性即视为普通模块。文件结构:
my_metamodule/ ├── module.prop (必须包含 metamodule=1) │ │ *** Metamodule 专属 hook *** ├── metamount.sh (可选:自定义挂载处理器) ├── metainstall.sh (可选:普通模块安装 hook) ├── metauninstall.sh (可选:普通模块清理 hook) │ │ *** 标准模块文件(全部可选)*** ├── customize.sh (安装定制) ├── post-fs-data.sh (post-fs-data 阶段脚本) ├── service.sh (late_start service 脚本) ├── boot-completed.sh (开机完成脚本) ├── uninstall.sh (metamodule 自身的卸载脚本) ├── system/ (systemless 修改,如需) └── [其他附加文件]三个 hook 脚本的职责与时机:
- metamount.sh(挂载处理器):在
post-fs-data阶段、所有模块脚本执行之前运行,负责以 systemless 方式挂载所有已启用模块,需检查skip_mount/disable标记。⚠️ 关键要求:挂载操作的 source/device 必须命名为"KSU"(如mount -t overlay -o lowerdir=... KSU /target,或 Rust 侧fsconfig_set_string(fs, "source", "KSU")?),内核卸载与 zygisksu 的卸载依赖此标识; - metainstall.sh(安装 hook):在模块安装时、文件解压后由内置安装器source执行(类似
customize.sh),继承install.sh的全部变量与函数(MODPATH、TMPDIR、ZIPFILE、ARCH、API、IS64BIT、KSU、KSU_VER、KSU_VER_CODE、KSU_UAPI_VER、KSU_RUNTIME_MODE、KSU_LATE_LOAD、BOOTMODE等,以及ui_print、abort、set_perm、set_perm_recursive、install_module等函数);注意安装 metamodule 自身时不会调用该 hook; - metauninstall.sh(清理 hook):在普通模块被卸载、目录删除之前运行,通过
MODULE_ID环境变量获知被卸载模块,用于清理文件、symlink 与内部追踪。
4.4 执行顺序
metamodule 的存在改变了系统启动脚本的执行时序,官方文档给出了完整顺序:
post-fs-data 阶段: 1. 公共 post-fs-data.d 脚本 2. 清理模块、restorecon、加载 sepolicy.rule 3. metamodule 的 post-fs-data.sh(如存在) 4. 普通模块的 post-fs-data.sh 5. 加载 system.prop 6. metamodule 的 metamount.sh └─> 以 systemless 方式挂载所有模块 7. post-mount.d 阶段 - 公共 post-mount.d 脚本 - metamodule 的 post-mount.sh(如存在) - 普通模块的 post-mount.sh service 阶段: 1. 公共 service.d 脚本 2. metamodule 的 service.sh(如存在) 3. 普通模块的 service.sh boot-completed 阶段: 1. 公共 boot-completed.d 脚本 2. metamodule 的 boot-completed.sh(如存在) 3. 普通模块的 boot-completed.sh要点:metamount.sh在所有 post-fs-data 脚本(含 metamodule 与普通模块)之后执行;metamodule 的生命周期脚本始终先于普通模块;.d公共脚本先于 metamodule。
另外,metamodule 安装后内核会创建稳定 symlink:/data/adb/metamodule -> /data/adb/modules/<metamodule_id>,无论 metamodule 的 id 是什么,都能通过固定路径访问当前激活的 metamodule。
4.5 参考实现:meta-overlayfs
meta-overlayfs是官方参考实现(完整指南见 website/docs/pt_BR/guide/metamodule.md),采用双目录架构:
- 元数据目录
/data/adb/modules/:存放module.prop、disable、skip_mount标记,启动时扫描快、占用小; - 内容目录
/data/adb/metamodule/mnt/:存放模块真实文件(system、vendor、product 等),保存在 ext4 镜像modules.img中,利用 ext4 特性优化空间。
其metamount.sh的核心逻辑是先挂载 ext4 镜像,再导出双目录环境变量并执行 Rust 编写的挂载二进制:
#!/system/bin/sh MODDIR="${0%/*}" IMG_FILE="$MODDIR/modules.img" MNT_DIR="$MODDIR/mnt" # 若尚未挂载则挂载 ext4 镜像 if ! mountpoint -q "$MNT_DIR"; then mkdir -p "$MNT_DIR" mount -t ext4 -o loop,rw,noatime "$IMG_FILE" "$MNT_DIR" fi # 为双目录支持设置环境变量 export MODULE_METADATA_DIR="/data/adb/modules" export MODULE_CONTENT_DIR="$MNT_DIR" # 执行挂载二进制(真实挂载逻辑在 Rust 二进制中) "$MODDIR/meta-overlayfs"其挂载特性包括:使用内核 overlayfs 实现真正的 systemless 修改;支持 system、vendor、product、system_ext、odm、oem 多分区;通过/data/adb/modules/.rw/提供读写层;所有 overlay 挂载设置dev=KSU以便识别。
五、安装与运行模式概览
KernelSU 自 0.9.0 起支持两种运行模式(详见 website/docs/pt_BR/guide/installation.md):
- LKM 模式(Loadable Kernel Module):以可加载内核模块方式注入,不替换设备原内核。优点是不触发 AVB、可临时卸载、OTA 升级便利、更新时可在 Manager 中直接安装;适合日常使用的手机。
- GKI 模式(Generic Kernel Image):用 KernelSU 提供的通用内核镜像替换设备原内核。通用性强(Samsung KNOX 等设备 LKM 无法工作,只能走 GKI)、不依赖厂商固件更新;适合模拟器、WSA、Waydroid 等场景。
安装层面,LKM 模式可经由 Manager(选择文件 / 直接安装 / 安装到非活动 slot)或命令行工具ksud完成,核心命令为:
ksud boot-patch -b <boot.img> --kmi android13-5.10boot-patch支持-b/--boot、-k/--kernel、-m/--module、-i/--init、-u/--ota、-f/--flash、-o/--out、--magiskboot、--kmi等选项(实现在 userspace/ksud/src/boot_patch.rs)。GKI 模式则可通过 KernelSU 提供的通用 boot.img、AnyKernel3 ZIP(配合 Kernel Flasher 或 TWRP 等)、或手工 magiskboot 修补等方式安装。无论何种方式,安装前务必确认设备 KMI 与安全补丁级别兼容,并备份原始 boot/init_boot 镜像(备份存放于/data/adb/ksu/ksu_backup_$SHA1)。
六、进一步阅读
围绕本文涉及的四个核心特性,可在仓库中继续深入:
- O que é KernelSU?(什么是 KernelSU):内核模式能力总览;
- App Profile 指南:uid/gid/groups/capabilities/SELinux 完整配置说明;
- Metamodule 指南:metamodule 开发与 meta-overlayfs 详解;
- 安装指南:LKM / GKI 两种模式的完整安装流程;
- 与 Magisk 的差异:模块格式、BusyBox 路径、
.replace与REMOVE/REPLACE变量、boot-completed 与 post-mount 阶段等差异; - 模块指南:普通模块开发规范;
- 源码级实现:白名单与 App Profile 见 kernel/policy/allowlist.c,结构定义见 kernel/include/uapi/app_profile.h,Manager 身份识别见 kernel/manager/manager_identity.h,syscall 挂钩见 kernel/hook/arm64/syscall_hook.c。
整体来看,KernelSU 通过"内核态实现 + 内核白名单 + 可裁剪 root 特权 + 可插拔挂载基础设施"四层架构,把 root 能力从"全有或全无"推进到了"按应用、按维度精细控制"的粒度——这也是其首页四大特性相互咬合、共同构成完整设计哲学的核心所在。
【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考