针对锁定引导加载程序的 Android 设备的内核漏洞利用。无需解锁引导加载程序或修改启动镜像,即可实现临时 root + KernelSU 安装。运行时自动检测内核版本,并配有支持多设备的偏移表。
CVE-2026-43499 — Futex PI(优先级继承)释放后使用
影响 Linux 内核 5.7 ~ 7.1。已在稳定版 6.1.175、6.6.140、6.12.86 中修复。截至 2026 年 9 月,大多数 Android 设备仍未修补。
pselect6 系统调用会将 fd_set 数据复制到内核栈上。当与 futex PI 等待者机制结合时,已释放的栈帧可被回收为 rt_mutex_waiter 结构。随后在 PI 链遍历期间进行的红黑树再平衡会将受控值写入任意内核地址。
| 设备 | SoC | 内核 | GKI 分支 | SHIFT |
|---|---|---|---|---|
| OnePlus Ace 6T (PLR110) | SM8845 | 6.12.38 | android16-5 | 0 |
| OnePlus 15 (CPH2745/2747/2749) | SM8850 | 6.12.23 | android16-5 | 0 |
| OnePlus 15 (PLK110) | SM8850 | 6.12.58 | android16-6 | 0 |
| Xiaomi 17 (pudding) | SM8850 | 6.12.23 / 6.12.69 | android16-5 / android16-6 | 0 |
| OnePlus 13 (IN2060) | SM8750 | 6.6.89 | android15-8 | -2 |
| OPPO Pad 4 Pro | SM8750 | 6.6.89 | android15-8 | -2 |
| 设备 | SoC | 内核 | 备注 |
|---|---|---|---|
| OnePlus 15T (PLZ110) | SM8845 | 6.12.38 | 与 Ace 6T 相同内核 |
| OPPO Reno10 Pro+ (CPH2521) | SM8475 | 5.10.236 | 5.10 紧凑等待者,waiter word=0 |
| Sony Xperia 1 IV (nagara) | SM8450 | 5.10.218 | 5.10 紧凑等待者,waiter word=0 |
| OPPO Find X9 Pro (PLG110) | D9400 | 6.12.23 | MediaTek,android16-5 |
| Vivo X200 Ultra (V2454A) | SM8750 | 6.6.89 | C ashmem,传统钩子 |
| Vivo X Fold3 Pro (PD2337) | SM8650 | 6.1.124 | 6.1 紧凑等待者,waiter word=3 |
| Vivo T4 | SM8650 | 6.1.145 | 6.1 紧凑等待者,waiter word=3 |
pselect 栈覆盖要求已释放的 rt_mutex_waiter 落在用户可控的 stack_fds 区域内(word 0–14)。其落点由编译器的 PGO/LTO 配置决定,而非内核版本。参见栈布局。
| 设备 | SoC | 内核 | 根本原因 |
|---|---|---|---|
| OPPO Find X9 Ultra | SM8750 | 6.12.58 | PGO 消除了 do_futex → waiter word=14 |
| OnePlus 15 (PLK110) | SM8850 | 6.12.69 | PGO 内联了 do_futex → waiter word=20 |
| OnePlus 12 | SM8650 | 6.1.141 | PGO 内联了 do_futex → waiter word=13/19 |
| OnePlus 13R / Ace 5 | SM8650 | 6.1.x | OPLUS 6.1:waiter word=13 |
| realme RMX5070 | SM6650 | 6.1.141 | OPLUS 6.1:waiter word=13 |
| OPPO Pad 5 (OPD2502) | MT6878 | 6.1.134 | OPLUS 6.1:waiter word=13 |
| Motorola Edge 60 Fusion | MT6878 | 6.1.145 | 非 OPLUS 6.1:结果相同 |
| iQOO Neo 10 CN | SM8650 | 6.1.84 | do_futex 帧 0xD0 → waiter word=-11 |
| OPPO PKW110 | — | 5.15.180 | do_futex 帧 0x140 → waiter word=-29 |
| iQOO Z9 5G | — | 5.15.178 | do_futex 帧过大 |
| CPH2763 (OPPO) | — | 6.1.115 | OPLUS 6.1:PGO 内联,waiter word=24 |
| iQOO 12 | SM8650 | 6.1.145 | 6.1:waiter word=9,task/lock 位于清零区域 |
关于 6.1 可行性的说明: OPLUS 6.1 内核由于 PGO 内联
do_futex,始终不可行。然而,一些非 OPLUS 6.1 内核(vivo)保留了标准调用链,因此可行(vivo T4、X Fold3 Pro)。可行性必须按设备逐一检查。
两条 root 路径,根据设备能力自动选择:
要求 off_ashmem_misc_fops != 0(C ashmem,BSS 中带有静态 miscdevice)。
PI write (mode=4) → redirect miscdevice fops to fake fops
→ configfs r/w → pipe physrw (1-byte precise kernel r/w)
→ SELinux enforcing = 0 (single byte, no policycap corruption)
→ UMH: inject work_struct into system_unbound_wq
→ root script → ksud late-load → KSU installed
适用于:OnePlus 13、OPPO Pad 4 Pro、5.10/6.1 C ashmem 设备。 不适用于 Rust ashmem(6.12 GKI)——堆分配的 miscdevice。
Write 1 (mode=1) → SELinux enforcing = 0 (8-byte write, corrupts adjacent bytes)
Write 2 (mode=2) → task->cred = init_cred (uid=0, all capabilities)
Root shell → ksud late-load → KSU → SELinux policy fix
在 W1+W2 之后,漏洞利用程序会修补 SELinux 策略二进制文件的 config 字段(对 ANDROID_NETLINK_ROUTE + GETNEIGH 执行 |= 0xC0000000),并通过 /sys/fs/selinux/load 重新加载,以恢复网络连接。
App (seccomp) → Write 1 → mini-adb TCP → adb shell: full exploit → root
启动时启动器由独立的 GhostLock Anchor 应用 提供。
在 NFDS=320 的情况下,core_sys_select 会在内核栈上分配一个 256 字节的 stack_fds 缓冲区:
stack_fds: 0 5 10 14 | 15 20 25 29
├─in─┤─out─┤─ex──┤ ├res_in┤res_out┤res_ex┤
◄── USER CONTROLLED ──►│◄── KERNEL ZEROED ──►
该漏洞利用将伪造的 waiter 字段(task、lock)放入 fd_set 输入位图中。对于 6.12 嵌套 waiter(14 个字):最大可行 waiter 字 = 3。对于 5.10/6.1 紧凑 waiter(10 个字):最大可行 waiter 字 = 7。
waiter 位置取决于调用链深度:
| 模式 | 调用链 | 是否可行 |
|---|---|---|
| android16-5 (6.12) | sys_futex → do_futex → fwrpi | ✅ waiter 字=2 |
| android16-6 (6.12.58) | sys_futex → do_futex → fwrpi | ✅ waiter 字=2 |
| android16-6 (6.12.69 OPLUS) | sys_futex → fwrpi(PGO 内联) | ❌ waiter 字=20 |
| android16-6 (X9 Ultra) | sys_futex → fwrpi(PGO 内联) | ❌ waiter 字=14 |
| android15-8 (6.6) | sys_futex → do_futex → fwrpi | ✅ waiter 字=2 (SHIFT=-2) |
| vivo 6.1 | sys_futex → do_futex → fwrpi | ✅ waiter 字=3 |
| OPLUS 6.1 | sys_futex → fwrpi(PGO 内联) | ❌ waiter 字=13+ |
| 5.10 OPLUS | sys_futex → do_futex → fwrpi | ✅ waiter 字=0 |
所有内核写入均使用线性映射别名。引导加载程序会选择 kernel_phys_load,该值因 SoC 而异:
| SoC | kernel_phys_load |
|---|---|
| SM8845 (Ace 6T, 15T) | 0xa8000000 |
| SM8750 (OnePlus 13, OPPO Pad 4 Pro) | 0xa8000000 |
| SM8650 (vivo T4, X Fold3 Pro) | 0xa8000000 |
| SM8850 (OnePlus 15, Xiaomi 17) | 0xc7800000 |
错误的值会静默失败。在已 root 的设备上读取该值:
su -c 'grep -i "Kernel code" /proc/iomem' # c7810000-... → 0xc7800000
在运行时覆盖:KPHYS=0xc7800000 /data/local/tmp/a/e
/data/local/tmp/a/e # Default (shift=0)
PSELECT_SHIFT=-2 /data/local/tmp/a/e # OnePlus 13 (6.6)
5.10 内核使用 0xffffffc008000000(VA_BITS=39,与 6.x 默认的 0xffffffc080000000 不同)。这通过设备偏移条目中的 kimage_text_base 字段自动处理。
make NDK_ROOT=/path/to/android-ndk
或直接:
NDK=/path/to/android-ndk
"$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android35-clang" \
-O2 -Wall -Isrc/core -Isrc/devices -DTARGET_CONFIG_H=\"target.h\" \
src/core/main.c src/core/util.c src/core/slide.c \
src/core/fops.c src/core/pipe_physrw.c src/core/root.c \
src/core/miniadb.c src/core/umh_root.c \
-o ./ghostlock -fPIE -pie -pthread
GhostLock 提供临时 root。KernelSU 安装需要 ksud,它为每个 KMI 版本捆绑了 kernelsu.ko。
| 方法 | 步骤 |
|---|---|
| ReSukiSU APK(推荐) | 安装 ReSukiSU 或此 fork。捆绑了 libksud.so。 |
| CI 发布版 | 从 ReSukiSU CI 下载 |
adb shell mkdir -p /data/local/tmp/a
adb push ./ghostlock /data/local/tmp/a/e
adb shell chmod 755 /data/local/tmp/a/e
adb shell /data/local/tmp/a/e
在启动完成且 ADB 就绪后运行。
只需要 boot.img —— 无需 root,无需访问设备。
完整工作流程请参阅 kallsyms 工具指南,或:
python tools/extract_target.py --kallsyms kallsyms.txt
python tools/extract_btf.py kernel
在 kernel 二进制中搜索所有指向 futex_wait_requeue_pi 的分支指令,检查 do_futex 是否被 PGO 内联。如果 __arm64_sys_futex 直接调用它(绕过 do_futex),则该设备很可能不可行。
添加 src/devices/<name>/offsets.h,写入提取到的偏移量,并将其包含到 src/devices/offsets.h 中。使用合适的结构体偏移宏:
| 内核 | Waiter 布局 | 宏 |
|---|---|---|
| 6.12.x | 嵌套(14 字) | STRUCT_OFFSETS_6_12 |
| 6.6.x | 嵌套(14 字) | STRUCT_OFFSETS_6_6 |
| 6.1.x (vivo) | 紧凑(10 字) | STRUCT_OFFSETS_6_1 |
| 5.10.x | 紧凑(10 字) | STRUCT_OFFSETS_5_10 |
对于 5.10/6.1 紧凑 waiter 设备,还需设置 .kimage_text_base=0xffffffc008000000ULL。