
UNFINISHED/WIP - CVE-2026-43499 (IonStack/GhostLock) investigación POC para Samsung SM-T878U / gts7l. Disparador + geometría verificados, SIN root funcional todavía.
[!CAUTION] ESTE PROYECTO ESTÁ INACABADO — TODAVÍA NO FUNCIONA. A fecha de 2026-10-06 no existe root funcional en ningún dispositivo. No esperes que el inicio rápido de abajo funcione. Lee Estado actual antes de compilar o ejecutar cualquier cosa.
[!WARNING] ESTADO: TRABAJO EN CURSO — ring 1 no alcanzado
- No logrado:
rootpersistente ni siquiera de un solo uso en SM-T878U.- Último fallo verificado: el payload de recuperación de pila nunca llega a la ruta de escritura del kernel. A lo largo de ~470 ejecuciones instrumentadas, el lock falsificado nunca se observa tomado en
rtmutex.c:585, por lo que el store*(ASHMEM_MISC_FOPS) = fake_fopsnunca se ejecuta.- Bloqueador anterior, ahora resuelto: la forense de fallos no estaba disponible para
uid 2000 shell(/proc/kmsg,/proc/last_kmsg,/sys/fs/pstore,dmesg→ todosEACCES). Un espejo de log duradero conwrite()+fsync()(IONSTACK_LOG_MIRROR) ahora sobrevive aCONFIG_PANIC_ON_OOPS=y, de modo que una ejecución con pánico deja igualmente un rastro completo.- Consulta
docs/RTMUTEX_WEAPONIZATION.md§15.16–§15.18 para el rastro de evidencias completo.
Prueba de concepto de re-root en C puro asistida por host para Samsung Galaxy Tab S7 (SM-T878U / gts7l) contra CVE-2026-43499 (IonStack / GhostLock).
La cadena en tiempo de ejecución usa únicamente componentes nativos C/ELF. No requiere
Python, Java, DEX, app_process ni una JVM en el objetivo Android. Se usa ADB para el
despliegue y la verificación.
No se ha obtenido root. Esta sección es el relato autoritativo y actualizado de en
qué punto se encuentra la cadena (última revisión 2026-10-06). Todo lo que sigue está
medido sobre hardware real (SM-T878U, T878USQS8DXE1, kernel 4.19.113-27114284), no es
teoría.
| Etapa | Estado | Evidencia |
|---|---|---|
| Identidad del objetivo + fuga de KASLR | funciona | [reroot] LEAK_OK kaslr_base=… task=… (canal lateral de perf) |
Disparo de CVE: FUTEX_CMP_REQUEUE_PI → -EDEADLK | funciona | [*] requeue ret=-1 errno=35 — EDEADLK == 35 en Linux |
El rollback defectuoso deja un pi_blocked_on colgante | coincide con el fix upstream | upstream 3bfdc63936dd cambia current->pi_blocked_on → waiter->task->pi_blocked_on |
Disposición de struct rt_mutex_waiter (4.19) | verificada desde el código fuente | tree_entry@0x00 pi_tree_entry@0x18 task@0x30 lock@0x38 prio@0x40 deadline@0x48 |
Geometría de pila paint == rt_waiter + 0x28 | verificada 4× incl. objdump | rt_waiter = do_futex_sp+0xC0; address = ___sys_sendmsg_sp+0xB8 |
| Forense de fallos duradera | funciona | el rastro write()+fsync() de IONSTACK_LOG_MIRROR sobrevive a un reinicio por pánico |
| Etiqueta de identidad de frag-page por mensaje | funciona | reclaim-scan tag=1 sent=8201 range=1..8201 ok=8192 bad=0 dup=0 undecoded=0 absent=9 |
| Escaneo de cola: el kernel escribió 0 bytes en 8192 frag pages en cola | verificado | 256 MB comparados byte a byte contra el payload, hits=0 |
rt_mutex_adjust_prio_chain alcanza la ruta de escritura | verificado desde el desensamblado | top_waiter == NULL ⇒ requeue sigue siendo true ⇒ 664/682/685/716-725 estructuralmente alcanzables |
page-dump y las 45 de ring1-page reportan
first_diff=8000 (pristine), owner_cpu=00000000, case1_gate=0, y
lock_root/lock_leftmost exactamente iguales al valor del payload. Nunca se ha
visto que el recorrido tome fake_lock->wait_lock en rtmutex.c:585, por lo que
664/682/685/716-725 — la única rama que puede almacenar en
*(ASHMEM_MISC_FOPS) — nunca se ha ejecutado.
Nótese que _raw_spin_trylock()/_raw_spin_unlock() pasan por
helpers fuera de línea y este árbol de vendor no tiene una anulación de
queued_spin_unlock para arm64, por lo que wait_lock.val == 1 es el testigo
fiable de 585 y owner_cpu != 0 es solo uno secundario.prctl(PR_SET_MM, PR_SET_MM_MAP, …). Este kernel incluye
# CONFIG_CHECKPOINT_RESTORE is not set, por lo que esa syscall está compilada fuera.
Tampoco usa nunca sendmsg — nuestro vehículo — que muy probablemente es la causa
raíz de (1).ring1-read nunca se ha ejecutado. La única lectura de vuelta desde userspace del anillo 1
(configfs_read_once(fd, data_addr(ASHMEM_MISC_FOPS), …)) está detrás de la
compuerta de escaneo de cola y detrás del valor por defecto MARKER del harness, que se detiene 8 s
antes en ring1-page. Cada ejecución que alcanzó la compuerta murió entre
page-dump tag=pre-arm y page-dump tag=post-arm.664/682/685 pueden completarse dentro de nuestra
propia página — IONSTACK_FOPS_WAIT_LOCK_WORD=0 con
IONSTACK_PAINT_WAITER_TASK_MODE=fake-task — y leer
page-dump tag=post-arm / ring1-lock585 para wait_lock=00000001.ring1-read se ejecute: ejecutar con IONSTACK_RECLAIM_SCAN_QUEUE sin definir y
MARKER='ring1-read|…' para que el harness no se detenga en ring1-page.IONSTACK_RECLAIM_TAG=1 y comparar
pipe_tag con msg_tag en page-dump. Todas las páginas frag son copias idénticas byte a byte
del payload, por lo que first_diff por sí solo no puede distinguirlas.IONSTACK_FOPS_WAIT_LOCK_WORD sobre una base correctamente planteada
— wlw=0 frente a wlw=1 con IONSTACK_RECLAIM_TAG mantenido constante. La
correlación anterior estaba confundida por el movimiento conjunto de las dos variables.pselect6 de res_in/res_out desde el port de K40 4.19.fops.c:3157 reason=selinux_write ret=-1 errno=22 EINVAL — aún sin resolver.