
Repositorio de investigación que documenta intentos de explotación de CVE-2026-43499 futex UAF en Honor YLP-W00 kernel 6.12.38, incluyendo fuentes de PoC, offsets del kernel y análisis de cadenas fallidas de escalada de privilegios.
Estado de la investigación: vulnerabilidad confirmada como desencadenable, PI walk exitoso sin fallos, pero no se ha logrado una cadena de escalada de privilegios completa. A la espera de actualizaciones upstream.
Este repositorio documenta el proceso completo de investigación para la escalada de privilegios temporal mediante CVE-2026-43499 en la tablet Honor YLP-W00 (kernel 6.12.38, +pgo+bolt+lto+mlgo).
El desencadenamiento de la vulnerabilidad fue exitoso (EDEADLK), el PI chain walk fue exitoso (sched_setattr=0, sin fallos), pero la compilación PGO provocó la inserción en línea de do_futex, y todos los portadores de recuperación de pila fallaron; la primitiva de escritura late_refs de CyberMeowfiaNS tampoco pudo alcanzar el objetivo debido a la falta de coincidencia en la geometría del slab.
| Elemento | Valor |
|---|---|
| Modelo | Honor YLP-W00 (tablet) |
| Sistema | HONORYLP-W00/10DLDLD170SP3C00E144 |
| Versión del sistema | 10.0.0.170 (MagicOS 10.0) |
| Kernel | 6.12.38-android16-5-gfde7767f6ef6-abogki481467632-4k |
| Compilación | +pgo,+bolt,+lto,+mlgo (clang 19.0.1) |
| Kernel SHA-256 | 48b622a20a700cdde0b8f2f6e83959df00a7efedf52f347377cf542f7b58948e |
| Bootloader | Bloqueado |
| SELinux | Enforcing |
| Aleatorización de kstack | Desactivada |
| ashmem | Reescrito en Rust |
| MTE | Soporte de hardware pero KASAN no habilitado |
La auditoría de CyberMeowfiaNS confirmó VULNERABLE_PATTERN_PRESENT. Existen dos casos exitosos con el mismo kernel SHA-256 (honor-mt6993, honor8e5), pero utilizaron la primitiva de escritura late_refs, que no puede reproducirse en este dispositivo (ver más abajo).
El kernel Honor 6.12.38 se compiló con +pgo+bolt+lto+mlgo, lo que provoca que __arm64_sys_futex llame directamente a futex_wait_requeue_pi, omitiendo la capa intermedia do_futex. La cadena de llamadas de futex pasa de tres capas estándar a dos capas:
GKI estándar: __arm64_sys_futex -> do_futex -> futex_wait_requeue_pi
Este dispositivo: __arm64_sys_futex -> futex_wait_requeue_pi (do_futex insertado en línea)
Esto provoca que el waiter se encuentre en una posición de pila más superficial (profundidad 0x130 en lugar de la estándar 0x1b0+), y la geometría de cobertura de todos los portadores de recuperación de pila estándar no coincide.
| Campo | Desplazamiento | Tamaño |
|---|---|---|
| tree_entry (rb_node) | +0x00 | 24B |
| pi_tree_entry (rb_node) | +0x18 | 24B |
| lock | +0x38 | 8B |
| prio | +0x44 | 4B |
| deadline | +0x48 | 8B |
| task | +0x50 | 8B |
| ww_ctx | +0x58 | 8B |
| Tamaño total | 0x70 | 112B |
| Símbolo | Desplazamiento |
|---|---|
| init_task | 0x023ecf00 |
| init_cred | 0x02402cb0 |
| root_task_group | 0x0261a740 |
| selinux_state.enforcing | 0x026663c8 |
| rb_erase | 0x00bce274 |
| rt_mutex_adjust_prio_chain | 0x115060c |
| commit_creds | 0x00b89c10 |
| worker_thread | 0x00adfef8 |
| remove_waiter | 0x0112b20 |
En modo seguro se confirmó el desencadenamiento de UAF y el éxito del PI walk:
[futex] CMP_REQUEUE_PI ret=-1 errno=35 (EDEADLK) ← Desencadenamiento de UAF exitoso
[futex] consumer sched_setattr ret=0 errno=0 ← PI walk exitoso, sin fallos
El dispositivo permaneció en línea, boot_id sin cambios, SELinux aún en Enforcing. rb_erase escribió en una dirección válida pero inútil.
Portadores de recuperación de pila intentados:
| Portador | Principio | Resultado |
|---|---|---|
| pselect | Copia de pila de fd_set | shift=26 (PGO inline), capacidad de fd_set insuficiente |
| MCAST_JOIN_SOURCE_GROUP | Copia de pila de 0x108 bytes | WAITER_OFF=0x308 >> 0x108, sin solapamiento |
| adjtimex | Copia de pila de estructura timex | buf depth 0x118 < waiter 0x130, sin solapamiento |
| io_submit | Cobertura de pila de struct iocb | Cubre waiter[0x28..0x67], lock@0x58 fuera de rango |
| PR_SET_MM_MAP | Escritura en pila de prctl | EPERM |
| Entrega de señales (do_signal) | Guardado en pila de pt_regs | El marco cubre waiter[0x00..0x28], task@0x50 y lock@0x58 son sobrescritos por otros marcos con valores inválidos, fallo |
| rt_sigreturn | fpsimd vregs 512B | En 6.12.38 se carga con ldtr en el área per-cpu, sin pasar por la pila del kernel |
Obstáculo principal: el waiter está en profundidad 0x130, tree_entry(+0x00) y pi_tree_entry(+0x18) pueden ser cubiertos parcialmente por portadores, pero task(+0x50) y lock(+0x58) están más profundo, y ningún portador conocido puede alcanzarlos. Cubrir tree_entry solo hace que rb_erase tome la ruta vacía (escribe NULL), sin poder dirigirse a la dirección objetivo.
CyberMeowfiaNS utiliza un método completamente diferente, evitando el problema de recuperación de pila:
Toda la cadena previa fue exitosa:
--info aprobado: verificación de identidad del kernel exitosa--check aprobado: verificación previa del carrier DSO (libdumpstateaidl.so) confirmada
Carrera late_refs fallida:
reclaim_hits=0Causa raíz del fallo: falta de coincidencia en la geometría del slab.
La función ep_get_upwards_depth_proc no existe en 6.12.38 (específica del kernel de referencia 6.12.58). Pero ep_loop_check_proc sí escribe en eventpoll.gen (+0xa8), así que esta no es la causa directa.
El tamaño de la estructura eventpoll es 0xdc0 (3520 bytes), asignada desde kmalloc-4k (order=3, slab de 32KB, 8 objetos). La suposición del código de eventpoll_size=0xd0 (208 bytes) es incorrecta.
eventpoll_epi (epitem) es de 128 bytes, order=0, página de 4KB, 32 objetos por página. late_refs solo libera 1-2 epitem por ronda, insuficiente para vaciar toda la página de 4KB y permitir que el page allocator la recupere.
late_refs requiere recuperación de página entre cachés (cross-cache page reclaim): página de epitem liberada → page allocator → página SKB order-3. Pero esto requiere que los 32 epitem de la misma página sean liberados, y el diseño del grafo epoll del código no puede garantizarlo.
El kernel de referencia 6.12.58 puede tener una configuración SLUB o diseño de slab diferente, lo que facilita la recuperación entre cachés.
| Archivo | Descripción | Tamaño |
|---|---|---|
firmware/boot_10.0.0.170.img | boot.img de la versión de sistema 10.0.0.170 | 96 MB |
firmware/honor_kernel_6.12.38.img | ELF del kernel extraído de boot.img (con tabla de símbolos) | 44 MB |
firmware/libdumpstateaidl_honor.so | Carrier DSO (extraído del dispositivo) | 52 KB |