首页
社区
课程
招聘
[原创]安卓root方案APatch SELinux_hide mmap ABI漏洞分析
发表于: 2026-10-13 13:11 1543

[原创]安卓root方案APatch SELinux_hide mmap ABI漏洞分析

2026-10-13 13:11
1543

=# KP 0.13.9 SELinux 隐藏功能漏洞技术分析

——/sys/fs/selinux/status mmap ABI 违规分析(检测验证示例见附录)

分析对象:KP(KernelPatch)0.13.9 内置 selinux_hide 功能,kernel/patch/common/selinux_hide.c。

影响范围:当前所有AP系管理器root方案(APatch、FolkPatch、Aster...)

结论:selinux_hide 在替换 sel_mmap_handle_status 时未保留上游全部四项 ABI 检查,普通权限 app 通过发送"stock 内核必然拒绝、hook 实现必然放行"的请求组合即可判定该功能是否存在。判定依据为上游内核源码的规格约束(对参考值测量无依赖),因此在任何设备、任何内核版本上都不会对干净内核产生误报。此外,其中一项违规伴随内核内存可写性问题,属于应按安全缺陷处理的问题。

KP 0.13.9 的 SELinux 隐藏功能(selinux_hide.c,约 980 行)目标是使 uid >= 10000 的 app 在 SELinux 层面观察到修改前的系统状态,掩盖 APatch/KernelSU 类方案留下的痕迹。核心机制四条:

启用路径:/data/adb/ap/selinux_hide 控制文件存在 → post-fs-data before 快照策略、after 安装 hook。仅支持 kernel >= 4.19。

hook 安装方式分两档:符号解析成功时走 inline hook;失败时对 write_op[] 表和 sel_handle_status_ops fops 结构做数据指针替换(不修改内核 text,规避 text 完整性校验)。本文的分析范围限于替换后的 handler 是否保留了上游 ABI,问题集中在该环节。

/sys/fs/selinux/status 是 libselinux 做 avc 无锁 fast-path 查询的节点。本地核对的 security/selinux/selinuxfs.c 4.19 与 5.10 源码中 sel_mmap_handle_status() 逐字一致(4.19 :246-266,5.10 :246-266):

四项检查(6.x 内核该函数的检查块与此相同):

同文件 sel_write_access()(5.10 :813-862)的应答格式:

security_compute_av_user() 从 avd_init() 出发(allowed=0, auditallow=0, auditdeny=0xffffffff),tclass==0 时直接返回。因此对探测串 u:r:untrusted_app:s0 u:r:untrusted_app:s0 0,真内核的 6 字段应答必然满足 field[1]==ffffffff 且 field[3]==ffffffff。该推导构成 /access 查询面的检测依据(见附录 A Oracle [2])。

KP 的替换实现(selinux_hide.c :570-625)核心逻辑:

实现只检查 vm_start 页对齐和假页物理地址可解析,然后直接 remap_pfn_range 一页假 status 到 vma 上:

对照上游,四项检查全部缺失。能 open 该节点的进程发送任一非法请求,stock 内核返回 -EIO/-EPERM、KP 返回成功,应答差异构成检测依据。

以基线映射(mmap(0, 4096, PROT_READ, MAP_PRIVATE),libselinux 自身使用的参数)为参照,以下四个探测请求在 stock 与 KP 下行为不同:

探测设计需遵守的判定规则(避免误报):

该判定为对上游内核源码行为的规格断言,跨设备可移植,对干净内核不产生误报。附件检测工程实现了上述探测组合,验证结果与本节一致。

KP 下,app 对 status fd 执行 read(buf, n) 且 pos=4096 时返回 EOF(假页有效内容 20 字节),而 mmap(fd, ..., offset=4096) 却成功并展示完整 status 头部。"offset 4096 读为空、mmap offset 4096 却有内容"这一组合没有任何真内核会产生——即使不做 3.2 的四项探测,单对比 read/mmap 语义也能判定替换实现存在。这是 3.1 中"不检查 vm_pgoff"的直接推论。

上游清除 VM_MAYWRITE 是安全边界的一部分。KP 的映射由 remap_pfn_range 建立(VM_PFNMAP,页背后无 struct page),且 KP 将读取自 vma 的 vm_page_prot 原样传给该函数。两条路径的行为不同:

综合:探测 c 使 uid >= 10000 的普通 app 可能获得对内核 vmalloc 内存的写映射。当前可写范围限于假 status 页本身(20 字节有效内容),破坏面有限,但这破坏了"status 节点对用户态只读"的上游保证,应按内核安全缺陷处理。

对照 bmax121/KernelPatch master 分支(最新提交 f36f3d1377004871f8c964f7cd3276712eeba943,2026-10-10 "refine selinux_hide",已拉取该提交 patch 及 master 全文核对):

本文 3.1 的问题未修复。 master 的 my_sel_mmap_handle_status(master 版 selinux_hide.c :711-766)与本地 0.13.9 版本一致——仍只检查 vm_start 页对齐和假页物理地址可解析,vm_pgoff、vm_end - vm_start、VM_WRITE 三项检查缺失,VM_MAYWRITE 未清除。3.2 的四项探测(a/b/c/d)在 master 上仍然全部命中,fill_fake_status_bytes(master :188-208)的硬编码常量也未修改。

master 近期两次 selinux_hide 相关提交修复的是其他类别的可观测差异:

总结:上游在收敛语义/时序类可观测差异,但 status mmap 的 ABI 级问题未处理,3.2 的探测组合对当前 master 仍然有效。

KP 0.13.9 selinux_hide 的策略快照/seqno 补丁链路设计合格——应答形状保持内核一致。但 status mmap 路径的替换实现丢弃了上游 handler 的全部输入校验与 vma flag 副作用:四项 ABI 违规均可被无 root 探测,其中 mprotect 项单项即可判定;且探测 c 的路径使普通 app 可能获得对内核 vmalloc 内存的直接写映射,已超出"可检测"范畴构成安全缺陷。

核心结论:替换内核 handler 时,原 handler 对用户态输入的全部校验与 vma flag 修改均需逐项保留;返回值与安全边界同属被替换行为的组成部分,二者都须维持与上游一致。

附件工程 KP139_SElinux-hide-check 为本文漏洞的验证示例,包含 libkpsc.so(native 探测,native/check.c)与 App 载体两部分。判定逻辑概要:
849K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6x3N6h3&6Q4x3X3c8a6f1#2)9J5c8V1c8G2N6$3&6D9L8$3q4V1i4K6u0r3M7X3g2D9k6h3q4K6k6i4y4Q4x3V1k6@1j5h3N6Q4x3V1k6$3K9i4m8Q4x3X3g2D9N6h3&6G2M7#2)9J5k6h3E0H3M7$3g2D9K9h3&6#2P5r3S2A6k6r3g2Q4x3X3g2U0K9r3g2U0K9#2)9J5k6h3c8W2L8h3)9I4

对基线映射执行探测 a/b/c/d,任一 GRANTED 即判定 KP 0.13.9 的 selinux_hide 存在。判定规则与 3.2 节一致:拒绝视为通过、基线失败报 UNTESTABLE(值 2),三态结果为 0=clean / 1=detected / 2=untestable。

老版 SELinux_hook KPM 1.1.7 对 /access 查询固定应答 "0 0 0 0 1 0":field[1](decided)= 0、field[3](auditdeny)= 0。按第 2 节推导,真内核对 tclass=0 探测只能给出 ffffffff/ffffffff,存活节点返回该形状即表明 hook 存在且为老版本。

防误报与防交叉干扰设计:

static int sel_mmap_handle_status(struct file *filp,
				  struct vm_area_struct *vma)
{
	struct page    *status = filp->private_data;
	unsigned long	size = vma->vm_end - vma->vm_start;

	BUG_ON(!status);

	/* only allows one page from the head */
	if (vma->vm_pgoff > 0 || size != PAGE_SIZE)
		return -EIO;
	/* disallow writable mapping */
	if (vma->vm_flags & VM_WRITE)
		return -EPERM;
	/* disallow mprotect() turns it into writable */
	vma->vm_flags &= ~VM_MAYWRITE;

	return remap_pfn_range(vma, vma->vm_start,
			       page_to_pfn(status),
			       size, vma->vm_page_prot);
}
	length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
			  "%x %x %x %x %u %x",
			  avd.allowed, 0xffffffff,
			  avd.auditallow, avd.auditdeny,
			  avd.seqno, avd.flags);
start = vm[KP_VMA_VM_START_OFF / sizeof(unsigned long)];   /* 按偏移读取 vma 字段 */
prot  = vm[kp_vma_page_prot_off() / sizeof(unsigned long)];

ret = kp_remap_pfn_range(vma, start, pa >> page_shift, KP_PAGE_SIZE, prot);

分析对象:KP(KernelPatch)0.13.9 内置 selinux_hide 功能,kernel/patch/common/selinux_hide.c。

影响范围:当前所有AP系管理器root方案(APatch、FolkPatch、Aster...)

结论:selinux_hide 在替换 sel_mmap_handle_status 时未保留上游全部四项 ABI 检查,普通权限 app 通过发送"stock 内核必然拒绝、hook 实现必然放行"的请求组合即可判定该功能是否存在。判定依据为上游内核源码的规格约束(对参考值测量无依赖),因此在任何设备、任何内核版本上都不会对干净内核产生误报。此外,其中一项违规伴随内核内存可写性问题,属于应按安全缺陷处理的问题。

机制 挂载点 效果
干净策略快照 post-fs-data before 深拷贝 boot policy context/access/setprocattr 对 app 按快照作答,Magisk/apd 之后的 policy reload 不可见
假 status 页 hook sel_read_handle_status + sel_mmap_handle_status app 读/mmap /sys/fs/selinux/status 观察到 enforcing=1、干净 seqno
seqno 补丁 hook sel_write_access DirtySepolicy 探针(untrusted_app → untrusted_app, tclass=0)的应答 seqno 被改写为 1,其余字段原样保留
setprocattr 净化 hook selinux_setprocattr app 切 context 时按干净快照校验

[招生]科锐逆向工程师培训(2026年11月13日实地,远程教学同时开班, 第57期)

上传的附件:
收藏
点赞 ・45
打赏
分享
最新回复 (19)
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2 楼
感谢分享
2026-10-13 17:01
0
雪    币: 1901
活跃值: (6078)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3 楼
111
2026-10-13 20:21
0
雪    币: 4325
活跃值: (4315)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4 楼
kk
2026-10-14 14:40
0
雪    币: 178
活跃值: (3991)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
5 楼
666
2026-10-14 14:44
0
雪    币: 9463
活跃值: (6383)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6 楼
看看
2026-10-14 15:01
0
雪    币: 0
活跃值: (1205)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7 楼
6666
2026-10-14 18:58
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8 楼
66666
2026-10-15 13:55
0
雪    币: 158
活跃值: (5931)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9 楼
感谢分享。
2026-10-15 15:44
0
雪    币: 1057
活跃值: (973)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
10 楼
kk
2026-10-15 16:02
0
雪    币: 0
活跃值: (730)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11 楼
666
2026-10-20 16:07
0
雪    币: 12
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12 楼
666
2026-10-20 22:49
0
雪    币: 10
活跃值: (90)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13 楼
5天前
0
雪    币: 3
活跃值: (235)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14 楼
感谢
5天前
0
雪    币: 5
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15 楼
3天前
0
雪    币: 1869
活跃值: (4743)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
16 楼
3天前
0
雪    币: 48
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17 楼
谢谢楼主分享
3天前
0
雪    币: 484
活跃值: (813)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18 楼
学习
2天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19 楼
感谢分享
1天前
0
雪    币: 710
活跃值: (2561)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20 楼
学习
3小时前
0
游客
登录 | 注册 方可回帖
返回