
(CVE-2026-43499)内核漏洞利用程序,适用于未解锁 Bootloader 的一加15T.
Kernel exploit targeting locked-bootloader OnePlus 15T devices. Uses CVE-2026-43499 to obtain root access without unlocking the bootloader or modifying boot.img.
Authorized security research and educational purposes only.
Modified from the original GhostLock-for-OnePlus repository, adapted for OnePlus 15T (PLZ110 / SM8850 / Snapdragon 8 Elite) physical memory layout and CPU timing.
| Item | Detail |
|---|---|
| CVE | CVE-2026-43499 |
| Type | Futex PI (Priority Inheritance) Use-After-Free |
| Scope | Linux kernel 2.6.39 ~ 7.1 |
| Fixed in | Mainline 7.1 (commit 3bfdc63936dd) |
| Android Status | GKI 6.12.x still vulnerable |
The pselect6 syscall copies fd_set to the kernel stack. When combined with the futex PI waiter mechanism, a freed stack frame can be reallocated as a rt_mutex_waiter struct. During PI chain traversal, rb-tree rebalancing writes controlled data to arbitrary kernel addresses.
futex PI UAF (CVE-2026-43499)
├─ Forge rt_mutex_waiter object
├─ Control kernel stack via pselect/select fd_set layout
├─ Trigger rt_mutex PI operation for arbitrary write
├─ Write 1: selinux_state.enforcing = 0
└─ Write 2: cred → init_cred (uid=0, full capabilities)
| Device | Codename | SoC | Kernel | Firmware | Status |
|---|---|---|---|---|---|
| OnePlus 15T | PLZ110 | SM8850 (Snapdragon 8 Elite) | 6.12.38-android16-5-g844001fb8721-ab14552068-4k | ColorOS 16.0.9.400 | ✅ Verified |
For Ace 6T and OnePlus 15, see the original repository.
GhostLock handles privilege escalation. KernelSU installation requires ksud (bundled with KMI-specific kernelsu.ko):
| Source | Notes |
|---|---|
| ReSukiSU APK (recommended) | Install ReSukiSU; the APK bundles libksud.so |
| CI Release | Download from ReSukiSU CI (ksud-aarch64-linux-android.zip) |
Without ksud, the exploit still gets uid=0 root shell, but KernelSU won't be installed and
suwon't persist.
ANDROID_NDK_HOME or ANDROID_NDK_ROOT# Default (API 35)
make
# Specify API level
make API=34
# Specify NDK path
NDK=/path/to/android-ndk make
ghostlock — statically linked ARM64 ELF executable.
# 1. Enable ADB TCP mode
adb tcpip 5555
# 2. Push ADB key (required for bootstrap mode)
adb push ~/.android/adbkey /data/local/tmp/a/adbkey
# 3. Push the exploit
adb push ghostlock /data/local/tmp/a/e
adb shell chmod 755 /data/local/tmp/a/e
After first success,
resetpropautomatically setspersist.adb.tcp.port=5555, allowing fully automatic runs on subsequent reboots.
/data/local/tmp/a/e
/data/local/tmp/a/e --bootstrap
setprop enable ADB TCP 5555127.0.0.1:5555/data/local/tmp/a/e --write1
Offsets stored in src/devices/offsets.h lookup table, keyed by uname -r. Program auto-matches at startup; unknown kernels are rejected.
static const struct kernel_offsets known_offsets[] = {
OFFSETS_ENTRY("6.12.38-android16-5-...-ab14275539-4k", ...),
OFFSETS_ENTRY("6.12.38-android16-5-...-ab14552068-4k", ...),
OFFSETS_ENTRY("6.12.23-android16-5-...-ab14541642-4k", ...),
{ .uname_r = NULL } /* sentinel */
};
| Type | Count | Extraction |
|---|---|---|
| kallsyms global symbols | 28 | tools/extract_target.py |
| BTF struct fields | 57 | tools/extract_btf.py |
| Derived values | 9 | Auto-calculated |
| Fixed constants | 12 | Hardcoded |
| Struct | Fields | Purpose |
|---|---|---|
task_struct | 17 | Process descriptor, cred, seccomp |
rt_mutex_waiter | 6 | UAF forge target |
cred | 4 | Credentials, capabilities |
seccomp | 3 | Seccomp filter state |
pipe_inode_info | 11 | Pipe buffer operations |
file_operations | 13 | Fake fops table |
mm_struct | 1 | Memory descriptor owner |
When kernel pointers are restricted (kptr_restrict), leak the base address via boot_id overwritten with a kernel address:
Read /proc/sys/kernel/random/boot_id
└─ UUID contains nfulnl_logger address
└─ KASLR slide = leaked_addr - image_offset
└─ kaslr_base
When ashmem device is accessible, use configfs read/write primitives to read function pointers from the ashmem fops table and compute KASLR offset.
Forge kernel objects on order-3 (32KB) pages:
file_operations — hijack ashmem miscdevice fops pointerrt_mutex_waiter — simulate PI chain waiter nodetask_struct — task reference during PI traversalrt_mutex (lock) — correct waiter/owner informationImplemented via SKB (socket buffer) + KernelSnitch:
mm_struct addressessendmsg to fill kernel heapAfter obtaining KASLR base, use pipe buffers for physical-level memory access:
1. Locate pipe buffer in physmap
2. Forge pipe_buffer ops table pointing to known pipe_buf_ops
3. Hijack pipe_buffer.page to target physical address
4. Arbitrary physical read/write via normal pipe operations
Supported: pipe_read64, pipe_write64, pipe_phys_read_data, pipe_phys_write_data
Target: selinux_state.enforcing (offset 0x00)
Method: child-node PI write → forge waiter __rb_parent_color
pointing to selinux_enforcing - 8
rb-tree rebalance writes 0x00
Target: child process cred pointer
Method: 1. fork child → perf_find_task() locate task_struct
2. calculate cred field offset
3. child-node PI write → cred = init_cred (uid=0, full caps)
4. clear seccomp (TIF_SECCOMP + seccomp struct zeroed)
Capability readback verification is performed after cred overwrite.
src/core/miniadb.c — lightweight ADB protocol client for bootstrap mode:
1. TCP connect 127.0.0.1:5555
2. A_CNXN → connection request
3. A_AUTH → RSA token challenge
4. dlopen("libcrypto.so") → PEM_read_bio_RSAPrivateKey → RSA_sign
5. A_AUTH (AUTH_SIGNATURE) → signed response
6. A_CNXN → connection established
7. A_OPEN "shell:/data/local/tmp/a/e" → full exploit
Supports SHA-1 and SHA-256 signature algorithms.