从 CVE-2026-43074 eventpoll UAF 利用中独立提取的 SELinux 禁用阶段。它竞态利用 eventpoll 循环深度检查(ep_get_upwards_depth_proc),将一个零写入 selinux_state.enforcing,通过单字节内核写入将设备切换到 Permissive 模式。这仅包含 MAC 禁用原语——不包含提权。
[!WARNING] 内核漏洞概念验证。可能导致内核崩溃、数据损坏或设备状态不一致。仅在你拥有或有权测试的设备上运行。请先备份。
从 NebuSec 的完整 PoC 中裁剪而来(源代码树)。UAF 位于 eventpoll 循环深度检查(ep_get_upwards_depth_proc)中,该函数在 RCU 下遍历 epi->ep,而 ep_free() 可能从并发线程释放 struct eventpoll。上游通过将释放推迟到 RCU 宽限期修复(提交 07712db8;NVD,OSV)。
这与 "Bad Epoll"(CVE-2026-46242)不同,后者是同一 eventpoll 代码中 ep_remove() 的另一个释放后使用;此处的竞态特指由 07712db8 修复的循环深度检查生命周期 bug。
根据 kernel.org CNA(通过 OSV/NVD),存在漏洞的稳定分支及修复版本:
6.4.0 – <6.6.136(在 6.6.136 修复)6.7.0 – <6.12.83(在 6.12.83 修复)6.13.0 – <6.18.24(在 6.18.24 修复)6.19.0 – <6.19.14(在 6.19.14 修复)固定目标内核 6.6.118-android15-8 属于受影响的 6.6 版本范围(在 6.6.136 修复)。向后移植了修复但未更新上游版本号的厂商内核不受影响——请验证实际补丁是否存在,而非仅依赖 uname -r。
固定到一个精确构建版本——enforcing 字节通过硬编码的 KVA 别名访问,且竞态依赖于该内核的 slab 布局:
6.6.118-android15-8-g53e6e091166e-ab15266607-4kgoogle/blazer/blazer:17/CP2A.260705.006/15641320:user/release-keysTARGET_SELINUX_ENFORCING_ALIAS = 0xffffff800236a2e0重新定位到其他构建版本需要重新计算别名(selinux_state 的镜像偏移 + 映射基址 + 加载地址),在 src/target.h 中修改。
需要 Android NDK 及 aarch64 clang 工具链。默认使用 NDK_ROOT=/opt/android-ndk,API=35:
make # → build/disabler
根据需要覆盖:
make API=35 NDK_ROOT=/path/to/android-ndk
将 build/disabler 推送到设备并以 shell 用户(uid 2000)身份运行。SELinux 必须在启动时处于 Enforcing 状态;否则二进制文件将跳过。成功时输出:
SELINUX_AFTER Permissive
RESULT PASS selinux_zero attempt=N
使用 getenforce 验证 → Permissive。
原始利用在此原语基础上增加了管道缓冲区 flags 重定向(类似 DirtyPipe 的写入只读页缓存页的方式),用于修补 /system/bin/dumpstate 以生成 root 守护进程。这些阶段(pipe.c、patch.c、su.c、payloads.S 和原始 main.c 编排)在此被移除,late_refs.c 缩减为仅包含零字节重定向路径。单独禁用 SELinux 并不会获得 root 权限——它仅移除 MAC 强制,使携带的有效负载能够不受限制地运行。