Resumen del fallo de explotación de GhostLock en PD2229 (SM8475, 5.10.233 GKI)
1. Hechos sobre la vulnerabilidad y el dispositivo
| Elemento | Valor |
|---|
| Tipo de vulnerabilidad | Use-After-Free en la pila en la ruta rt_mutex / futex PI |
| Versión introducida | Linux 2.6.39-rc1 (mayo de 2011, commit 8161239a8bcc) |
| Versión corregida | mainline 7.1 (commit 3bfdc63936dd), ramas estables: 6.1.175 / 6.6.140 / 6.12.86 / 6.18.27 / 7.0.4 |
| Requisito previo | CONFIG_FUTEX_PI=y (habilitado por defecto en kernels principales) |
| CVSS | 7.8 High |
| Estabilidad de explotación | Cadena original de NebuSec 97%, root en ~5 segundos |
| Recompensa kernelCTF | $92,337 USD |
Rango de kernels afectados:
- 2.6.39 ≤ Linux < 6.1.175 ✅ Afectado
- 6.2 ≤ Linux < 6.6.140 ✅ Afectado
- 6.7 ≤ Linux < 6.12.86 ✅ Afectado
- 6.13 ≤ Linux < 6.18.27 ✅ Afectado
- 6.19 ≤ Linux < 7.0.4 ✅ Afectado
- Android GKI 5.10 no está en ninguna rama corregida → el 5.10.233 de PD2229 teóricamente afectado
1.2 Pruebas reales en el dispositivo PD2229
2. Cadena de explotación ideal vs progreso real en PD2229
2.1 Cadena original de NebuSec (exitosa en x86_64 / Pixel 10)
1. Bypass de KASLR → prefetch timing / PR_SET_MM_MAP auxv
2. Disparo de UAF → deadlock de dependencia PI de tres hilos → FUTEX_CMP_REQUEUE_PI devuelve -EDEADLK
3. Reciclaje de pila → PR_SET_MM_MAP copia auxv al marco de pila del waiter
4. Escritura restringida rb_erase → sobrescribe inet6_protos[IPPROTO_UDP]
5. CEA + ROP → secuestro del flujo de control
6. Cambio de core_pattern → shell root (97% de éxito)
2.2 Progreso real por etapa en PD2229
3. Resultados de enumeración exhaustiva de la primitiva de reciclaje de pila (pruebas reales en PD2229)
3.1 Cálculos clave del diseño del marco de pila
Profundidad total de la ruta futex:
__arm64_sys_futex 0x90
+ do_futex 0xc0
+ futex_wait_requeue_pi 0x1b0
= 0x300
Posición del waiter = SYS_SP - 0x300 + 0x20 = SYS_SP - 0x2e0
Ruta pselect:
marco de pila core_sys_select 0x1c0, stack_fds en sp+0x50
Rango cubierto: SYS_SP - 0x1c0 + 0x50 = desde SYS_SP - 0x170
Diferencia con waiter (SYS_SP - 0x2e0) de 0x170 (368 bytes) → sin superposición
3.2 17 métodos de escritura en pila probados
17/17 fallaron todos.
3.3 Causa raíz del fallo
El diseño de pila generado por el compilador del SM8475 5.10 GKI de PD2229 (PGO + LTO + BOLT) hace que stack_fds de core_sys_select y rt_mutex_waiter de futex_wait_requeue_pi no se superpongan arquitectónicamente. Este es un hecho objetivo determinado por el compilador, no un problema de técnica de explotación.
El repositorio de JoinChang establece claramente: "The pselect stack overlay only works when the freed rt_mutex_waiter lands within the user-controllable region of the stack_fds buffer" — PD2229 no cumple esta condición.
4. Análisis comparativo de repositorios de referencia públicos
NebuSec/CyberMeowfia — Framework de explotación original
- Repositorio: https://github.com/NebuSec/CyberMeowfia
- Objetivo: x86_64 Linux / Pixel 10 (6.x GKI)
- Reciclaje de pila:
PR_SET_MM_MAP copia auxv a la pila del kernel
- Tasa de éxito: 97%, ~5 segundos para [shell root]
- Aplicabilidad a PD2229: ❌
PR_SET_MM_MAP bloqueado con EPERM en Android
JoinChang/ghostlock-oneplus — Jailbreak de BL OnePlus
- Repositorio: https://github.com/JoinChang/ghostlock-oneplus
- Dispositivos verificados:
- OnePlus Ace 6T (PLR110, SM8845) — 6.12.38 GKI ✅
- OnePlus 15 (PLK110, SM8845) — 6.12.23 GKI ✅
- Puntos técnicos clave:
- Extracción automática de offsets: kallsyms (28) + BTF (57) + derivados (9) + constantes (12) = 103/103
- Superposición de pila pselect, SP diff = -64
PSELECT_SHIFT = -2
- Cadena de explotación: futex UAF → waiter falsificado → pselect controla la pila → escritura restringida rb_erase → selinux_state.enforcing=0 → sobrescritura de cred con init_cred
- Declaración explícita de inviabilidad: "Not Feasible (stack layout incompatible)" — solo aplicable a kernels donde pselect stack_fds se superpone con el waiter
- Aplicabilidad a PD2229: ❌ Generación de kernel incompatible (6.12 vs 5.10), y diseño de pila sin superposición
p2p3p/GhostLock-for-OnePlus — Explotación completa OnePlus 6.12
YuKongA/ghostlock-oplus — OPPO Find N5/X8
Adaptación OPPO Find X6 Pro (PGEM10) — 5.15.149
- Dispositivo: SM8550, 5.15.149-android13, Android 15
- Progreso: ✅ Bypass de KASLR (perf_event_open + muestreo de callchain); etapas posteriores sin explotación completa publicada
- Importancia: demuestra que el bypass de KASLR es viable en 5.15 GKI, pero la etapa de reciclaje de pila no está verificada públicamente
pubglite55/oppo-ghostlock — OPPO Find N2
- Repositorio: https://github.com/pubglite55/oppo-ghostlock
- Dispositivo: OPPO Find N2 (CPH2413, SM8475)
- Kernel: 5.10.236-android12-9-o-g74d132f4467a
- Android: 16 (BP2A.250605.015)
- Implementado:
- ✅ Firefox CVE-2026-10702 AAW (Stage 1)
- ✅ Bypass de KASLR (cálculo directo de kaslr_base)
- ✅ Disparo de GhostLock FUTEX (FUTEX_CMP_REQUEUE_PI ret=0)
- ✅ Fuga de mm_struct con KernelSnitch
- ✅ Heap spray de sk_buff (4/4 envíos exitosos)
- ✅ Verificación de 70+ offsets con IDA Pro
- Bloqueo principal:
"pselect no puede manipular la estructura del waiter — con NFDS >336 fd_set está en el heap; configfs/ashmem no soportados (SET_NAME de ashmem truncado); todas las demás rutas de escritura al kernel bloqueadas (/proc/self/mem, /dev/mem, binder)"
- Relación con PD2229: Misma plataforma y misma generación (SM8475, 5.10.236 vs 5.10.233), solo 3 versiones menores de diferencia, enfrenta exactamente las mismas limitaciones arquitectónicas
harry1080/oppo-ghostlock — OPPO Find N2
- Repositorio: https://github.com/harry1080/oppo-ghostlock
- Dispositivo: OPPO Find N2 (CPH2413, SM8475)
- Kernel: 5.10.236-android12-9-o-g74d132f4467a
- Android: 16 (BP2A.250605.015)
- Declaración pública de la comunidad:
"En la versión explotable de pixel10, pselect stack_fds coincide exactamente con rt_waiter en la pila del kernel; esta parte es en realidad la más problemática. En el kernel del OPPO findN2, las pilas de estas dos llamadas no coinciden en absoluto, o si coinciden no es controlable; hay que encontrar otro método para controlar la pila, y se necesitan otras syscalls con pila del kernel controlable para construir la pila. Una simple adaptación de offsets es imposible que tenga éxito. El rt_waiter de oppo no coincide en absoluto con pselect stack_fds"
- Relación con PD2229: Al igual que PD2229, es SM8475 5.10 GKI, la conclusión es totalmente aplicable
4.3 Tabla comparativa general de repositorios de referencia
5. Símbolos clave del kernel y offsets (medidos en vmlinux de PD2229)
Base estática 0xffffffc008000000, se debe añadir el slide de KASLR en tiempo de ejecución.
Estructura rt_mutex_waiter (personalizada de vivo 5.10.233)
struct rt_mutex_waiter {
uint64_t private; // +0x00 (campo privado de vivo)
struct rb_node {
uint64_t rb_parent_color; // +0x08
uint64_t rb_right; // +0x10 (vivo invierte el orden)
uint64_t rb_left; // +0x18
} tree;
struct task_struct *task; // +0x20
struct rt_mutex *lock; // +0x28
};
// Tamaño total 0x30 (48 bytes)
6. Implementado vs pendiente de implementar
✅ Infraestructura implementada
- Bypass de KASLR —
perf_event_open + muestreo de callchain (mismo método que OPPO Find X6 Pro 5.15.149)
- Disparo de UAF — Deadlock PI de tres hilos, FUTEX_CMP_REQUEUE_PI devuelve -EDEADLK
- Tabla de símbolos completa — 103+ símbolos verificados con IDA (siguiendo la metodología de extracción 103/103 de JoinChang)
- Diseño de la estructura rt_mutex_waiter — offsets personalizados de vivo confirmados
- Análisis preciso del diseño de marcos de pila — cálculo de profundidad de rutas futex y pselect/io_uring completado
- Exclusión exhaustiva de 17 candidatos de reciclaje de pila — matriz completa de "inviabilidad" establecida
❌ No implementado (bloqueo principal)
- Primitiva de reciclaje de pila — el diseño de pila del compilador SM8475 5.10 GKI lo hace arquitectónicamente inutilizable
- Primitiva de escritura restringida — no se puede disparar rb_erase debido al fallo del reciclaje de pila
- Todas las etapas posteriores — bloqueo en cascada
7. Conclusión final
⚠️ GhostLock (CVE-2026-43499) no es explotable en PD2229 (vivo X Fold+, SM8475, 5.10.233 GKI, Android 15 OriginOS 5).
La causa raíz es el diseño de pila generado por el compilador SM8475 5.10 GKI (PGO+LTO+BOLT), que hace que los marcos de pila de todas las syscalls conocidas no se superpongan arquitectónicamente con rt_mutex_waiter. Este es un hecho objetivo determinado por el compilador, no un problema de técnica de explotación.
Todos los casos de explotación exitosa son en 6.6/6.12 GKI, porque la salida del compilador en estos kernels más nuevos hace que pselect fd_set se superponga perfectamente con el waiter (SP diff=-64). El 5.10 GKI no tiene esta condición.
Infraestructura establecida
- ✅ Primitiva de bypass de KASLR (canal lateral perf_event_open)
- ✅ 103+ símbolos del kernel y offsets
- ✅ Diseño de la estructura rt_mutex_waiter
- ✅ Capacidad de disparo de UAF
- ✅ Matriz de exclusión de 17 candidatos de reciclaje de pila
9. Índice de repositorios de referencia