
cve-2026-43499 — 已更新!
PD2229B的43499(ghostlock)可行性研究
GhostLock 在 PD2229 (SM8475, 5.10.233 GKI) 的利用失败总结
一、漏洞与设备事实
1.1 CVE-2026-43499 (GhostLock) 基本信息
| 项目 | 值 |
|---|---|
| 漏洞类型 | rt_mutex / futex PI 路径中的栈上 Use-After-Free |
| 引入版本 | Linux 2.6.39-rc1 (2011年5月,commit 8161239a8bcc) |
| 修复版本 | 主线 7.1 (commit 3bfdc63936dd),各稳定分支:6.1.175 / 6.6.140 / 6.12.86 / 6.18.27 / 7.0.4 |
| 前置条件 | CONFIG_FUTEX_PI=y(主流内核默认开启) |
| CVSS | 7.8 High |
| 利用稳定性 | NebuSec 原链 97%,约 5 秒获取 root |
| kernelCTF 奖金 | $92,337 USD |
受影响内核范围:
- 2.6.39 ≤ Linux < 6.1.175 ✅ 受影响
- 6.2 ≤ Linux < 6.6.140 ✅ 受影响
- 6.7 ≤ Linux < 6.12.86 ✅ 受影响
- 6.13 ≤ Linux < 6.18.27 ✅ 受影响
- 6.19 ≤ Linux < 7.0.4 ✅ 受影响
- Android GKI 5.10 未在任何修复分支中 → PD2229 的 5.10.233 理论上受影响
1.2 PD2229 设备实测
| 项目 | 值 |
|---|---|
| SoC | Qualcomm SM8475 (Snapdragon 8 Gen 1 Plus) |
| 内核版本 | 5.10.233-gki-g6e61de9f5b58 #1 SMP PREEMPT (Nov 24 2025) |
| Android 版本 | 15 (OriginOS 5) |
| 编译时间 | 2025/11/25 |
| 安卓补丁 | 2025/11/01 |
CONFIG_FUTEX_PI | y ✅ |
CONFIG_UNMAP_KERNEL_AT_EL0 | y (KPTI 开启) |
kptr_restrict | enforced |
CONFIG_IO_URING | y ✅(vmlinux 符号确认,且 seccomp 未拦截 io_uring_setup) |
二、理想利用链 vs PD2229 实际进度
2.1 NebuSec 原链(x86_64 / Pixel 10 成功)
1. KASLR 绕过 → prefetch timing / PR_SET_MM_MAP auxv
2. UAF 触发 → 三线程 PI 依赖死锁 → FUTEX_CMP_REQUEUE_PI 返回 -EDEADLK
3. 栈回收 → PR_SET_MM_MAP 将 auxv 拷贝到 waiter 栈帧
4. rb_erase 受限写 → 覆写 inet6_protos[IPPROTO_UDP]
5. CEA + ROP → 控制流劫持
6. core_pattern 翻转 → root shell (97% 成功率)
2.2 PD2229 各环节实际进度
| 阶段 | 状态 | 说明 |
|---|---|---|
| 1. KASLR 绕过 | ✅ 已实现 | perf_event_open + callchain sampling 侧信道(与 OPPO Find X6 Pro 5.15.149 适配方法一致) |
| 2. UAF 触发 | ✅ 已实现 | 三线程 PI 死锁成功,FUTEX_CMP_REQUEUE_PI 返回 -EDEADLK |
| 3. 栈回收原语 | ❌ 架构性失败 | 所有已知 syscall 的栈帧与 waiter 不重叠(详见第三节) |
| 4. rb_erase 受限写 | ❌ 阻塞中 | 前置条件未满足 |
| 5. inet6_protos 覆写 | ❌ 未开始 | 依赖阶段 4 |
| 6. ROP / 控制流劫持 | ❌ 未开始 | 依赖阶段 5 |
| 7. root shell | ❌ 未开始 | 依赖阶段 6 |
三、栈回收原语穷举结果(PD2229 实测)
3.1 栈帧布局关键计算
futex 路径总深度:
__arm64_sys_futex 0x90
+ do_futex 0xc0
+ futex_wait_requeue_pi 0x1b0
= 0x300
waiter 位置 = SYS_SP - 0x300 + 0x20 = SYS_SP - 0x2e0
pselect 路径:
core_sys_select 栈帧 0x1c0, stack_fds 在 sp+0x50
覆盖区间: SYS_SP - 0x1c0 + 0x50 = SYS_SP - 0x170 起
与 waiter (SYS_SP - 0x2e0) 差距 0x170 (368 字节) → 不重叠
3.2 已尝试的 17 种栈写入方法
| # | 方法 | 系统调用 | PD2229 结果 | 核心失败原因 |
|---|---|---|---|---|
| 1 | stamp_prctl | PR_SET_MM_MAP | ❌ EPERM | Android 硬拦截 |
| 2 | stamp_pselect | pselect6 (NFDS=320) | ❌ 不重叠 | waiter 在 fd_set 下方 120B |
| 3 | stamp_pselect | pselect6 (NFDS>336) | ❌ 堆分配 | kvmalloc 路径 |
| 4 | stamp_socket | MCAST_JOIN_SOURCE_GROUP | ❌ 覆盖不足 | 仅写 lock 字段 |
| 5 | stamp_sendmsg | sendmsg | ❌ 距 waiter 80B | 栈帧 0x90 深度不足 |
| 6 | stamp_sendmmsg | sendmmsg | ❌ 距 waiter 112B | 栈帧不足 |
| 7 | stamp_recvmmsg | recvmmsg | ❌ 清零 task/lock | 0x1d0 栈帧破坏关键指针 |
| 8 | stamp_process_vm | process_vm_writev | ❌ 不重叠 | 子线程栈独立分配 |
| 9 | stamp_keyctl | KEYCTL_INSTANTIATE_IOV | ❌ EOPNOTSUPP | 系统调用不支持 + 栈帧 0x40 |
| 10 | stamp_tcp | TCP_ZEROCOPY_RECEIVE | ❌ 栈帧不足 | 预估深度不够 |
| 11 | stamp_futex | FUTEX_CMP_REQUEUE_PI 递归 | ❌ 逻辑不可行 | 破坏 UAF 窗口 |
| 12 | binder ioctl | BINDER_WRITE_READ | ❌ EACCES | shell 无 /dev/binder 权限 |
| 13 | poll | poll | ❌ 堆分配 | pollfd 在堆上 |
| 14 | epoll_wait | epoll_wait | ❌ 帧太浅 | 栈帧 0xE0 |
| 15 | sched_setattr | sched_setattr | ❌ 深度不足 | 栈帧 0xb0 |
| 16 | timerfd_settime | timerfd_settime | ❌ 无栈复制 | 无大栈缓冲区 |
| 17 | io_uring_register | IORING_REGISTER_* | ❌ 双失败 | ①栈帧仅 0xF0,copy_from_user 目标固定 sp+0x8(与 waiter 的 sp+0x1D0 差 424 字节);②虽然 io_uring_setup 未被 seccomp 拦截(返回 EFAULT 而非 ENOSYS),但栈布局不匹配 |
17/17 全部失败。
3.3 失败的根本原因
PD2229 的 SM8475 5.10 GKI 编译器(PGO + LTO + BOLT)输出的栈布局,导致 core_sys_select 的 stack_fds 与 futex_wait_requeue_pi 的 rt_mutex_waiter 架构性不重叠。这是编译器决定的客观事实,而非利用技巧问题。
JoinChang 仓库明确说明:"The pselect stack overlay only works when the freed rt_mutex_waiter lands within the user-controllable region of the stack_fds buffer"——PD2229 不满足此条件。
四、公开参考仓库对比分析
NebuSec/CyberMeowfia — 原始利用框架
- 仓库:https://github.com/NebuSec/CyberMeowfia
- 目标:x86_64 Linux / Pixel 10 (6.x GKI)
- 栈回收:
PR_SET_MM_MAP将 auxv 拷贝到内核栈 - 成功率:97%,约 5 秒[root shell]
- PD2229 适用性:❌
PR_SET_MM_MAP在 Android 上被 EPERM 拦截
JoinChang/ghostlock-oneplus — 一加锁 BL jailbreak
- 仓库:https://github.com/JoinChang/ghostlock-oneplus
- 已验证设备:
- OnePlus Ace 6T (PLR110, SM8845) — 6.12.38 GKI ✅
- OnePlus 15 (PLK110, SM8845) — 6.12.23 GKI ✅
- 技术要点:
- 偏移自动提取:kallsyms (28) + BTF (57) + 派生 (9) + 常量 (12) = 103/103
- pselect 栈覆盖,SP diff = -64
PSELECT_SHIFT = -2- 利用链:futex UAF → 伪造 waiter → pselect 控制栈 → rb_erase 受限写 → selinux_state.enforcing=0 → cred 覆写为 init_cred
- 明确声明不可行:"Not Feasible (stack layout incompatible)" — 仅适用于 pselect stack_fds 与 waiter 重叠的内核
- PD2229 适用性:❌ 内核代次不符(6.12 vs 5.10),且栈布局不重叠
p2p3p/GhostLock-for-OnePlus — 一加 6.12 完整利用
- 仓库:https://github.com/p2p3p/GhostLock-for-OnePlus
- 已验证:OnePlus Ace 6T (SM8845, 6.12.38) ✅
- PD2229 适用性:❌ 同 JoinChang,内核代次不符
YuKongA/ghostlock-oplus — OPPO Find N5/X8
- 仓库:https://github.com/YuKongA/ghostlock-oplus
- 内核:6.6.118 GKI
- PD2229 适用性:❌ 内核代次不符
OPPO Find X6 Pro (PGEM10) 适配 — 5.15.149
- 设备:SM8550, 5.15.149-android13, Android 15
- 进展:✅ KASLR 绕过(perf_event_open + callchain sampling);后续阶段未公开完整利用
- 意义:证明 5.15 GKI 上 KASLR 绕过可行,但栈回收阶段未公开验证
pubglite55/oppo-ghostlock — OPPO Find N2
- 仓库:https://github.com/pubglite55/oppo-ghostlock
- 设备:OPPO Find N2 (CPH2413, SM8475)
- 内核:5.10.236-android12-9-o-g74d132f4467a
- Android:16 (BP2A.250605.015)
- 已实现:
- ✅ Firefox CVE-2026-10702 AAW(Stage 1)
- ✅ KASLR bypass(直接计算 kaslr_base)
- ✅ GhostLock FUTEX 触发(FUTEX_CMP_REQUEUE_PI ret=0)
- ✅ KernelSnitch mm_struct 泄漏
- ✅ sk_buff 堆喷射(4/4 send 成功)
- ✅ IDA Pro 70+ 偏移验证
- 核心阻塞:
"pselect 无法操纵 waiter 结构 — NFDS >336 时 fd_set 在堆上;configfs/ashmem 不支持(ashmem SET_NAME 被截断);所有其他内核写入路径被阻塞(/proc/self/mem, /dev/mem, binder)"
- PD2229 关系:同平台同代次(SM8475, 5.10.236 vs 5.10.233),仅差 3 个小版本,面临完全相同的架构性限制
harry1080/oppo-ghostlock — OPPO Find N2
- 仓库:https://github.com/harry1080/oppo-ghostlock
- 设备:OPPO Find N2 (CPH2413, SM8475)
- 内核:5.10.236-android12-9-o-g74d132f4467a
- Android:16 (BP2A.250605.015)
- 社区公开声明:
"pixel10 能利用的版本的 pselect stack_fds 正好和 rt_waiter 在内核栈上重合,这个部分实际上是最麻烦的地方,OPPO findN2 的内核这两个调用的栈部分完全不重合,或者重合也不可控,得找另外的控制栈的方法,要换其他可控内核栈的系统调用来构造栈,简单适配偏移是不可能成功的,oppo 的 rt_waiter 完全与 pselect stack_fds 不重合"
- PD2229 关系:与 PD2229 同为 SM8475 5.10 GKI,结论完全适用
4.3 参考仓库对比总表
| 仓库 | 设备 | SoC | 内核 | 栈回收方法 | 状态 | PD2229 可复用性 |
|---|---|---|---|---|---|---|
| NebuSec/CyberMeowfia | Pixel 10 | - | 6.x | PR_SET_MM_MAP | ✅ 97% | ❌ Android 拦截 |
| JoinChang/ghostlock-oneplus | OnePlus Ace 6T | SM8845 | 6.12.38 | pselect (SP diff=-64) | ✅ 已验证 | ❌ 内核代次不符 |
| p2p3p/GhostLock-for-OnePlus | OnePlus Ace 6T | SM8845 | 6.12.38 | pselect | ✅ 已验证 | ❌ 内核代次不符 |
| YuKongA/ghostlock-oplus | Find N5/X8 | - | 6.6.118 | pselect | ✅ | ❌ 内核代次不符 |
| OPPO Find X6 Pro 适配 | Find X6 Pro | SM8550 | 5.15.149 | perf KASLR + ? | 🟡 KASLR ✅, 后续未公开 | ❌ 平台不同 |
| pubglite55/oppo-ghostlock | Find N2 | SM8475 | 5.10.236 | 穷举失败 | ❌ 核心阻塞 | ⚠️ 同平台同代次,命运一致 |
| harry1080/oppo-ghostlock | Find N2 | SM8475 | 5.10.236 | 穷举失败 | ❌ 架构性不可行 | ⚠️ 同平台同代次,命运一致 |
| PD2229 (本报告) | PD2229 | SM8475 | 5.10.233 | 17 种候选全失败 | ❌ 架构性不可行 | — |
五、关键内核符号与偏移(PD2229 vmlinux 实测)
静态基址
0xffffffc008000000,运行时需加 KASLR slide。