
Note di ricerca e sviluppo di PoC per CVE-2026-43499 (GhostLock) kernel UAF su vivo Y200i Android 14, che coprono le primitive di stack-reclaim della catena PI futex e i limiti del layout dei frame.
Dispositivo: vivo Y200i (PD2354C), Snapdragon 4 Gen 2 (SM4450), Android 14 / OriginOS 4 Kernel: 5.10.218-gki-g3a51ea9d5834 (VA a 39 bit, pagine da 4K, KASLR attivo, STACKLEAK=y, senza SVE)
Obiettivo: root temporaneo tramite CVE-2026-43499 (GhostLock).
Funzionante finora:
Bloccato: la primitiva di stack-reclaim non riesce a raggiungere l'rb_node dell'rt_mutex_waiter.
Numeri chiave (identici su due pacchetti firmware indipendenti):
__arm64_sys_futex 0xe0
do_futex 0xc0 (NON inlined - esiste una bl do_futex)
futex_wait_requeue_pi 0x1b0 (waiter a sp+0x20)
=> profondità catena futex T0-0x330
__arm64_sys_pselect6 0xa0 core_sys_select 0x1c0 (fd_set a sp+0x50) => profondità catena pselect T0-0x210, finestra controllabile solo 120 byte => gap 0x120, architetturalmente non sovrapposto
layout del waiter (5.10 compatto, corrisponde a PFEM10): +0x18 pi_tree_entry.__rb_parent_color <- ciò che percorre rt_mutex_adjust_prio_chain +0x20 pi_tree_entry.rb_right +0x28 pi_tree_entry.rb_left +0x30 task +0x38 lock +0x40 prio +0x48 deadline
Evidenza da rt_mutex_adjust_prio_chain: ldr x8, [task, #0x888] ; task->pi_waiters.rb_leftmost sub x8, x8, #0x18 ; rb_entry(node, rt_mutex_waiter, pi_tree_entry)
Poiché copy_from_user scrive verso indirizzi più alti, coprire pi_tree_entry richiede che la base della copia sia <= T0-0x318.
Percorsi esauriti: pselect6/core_sys_select T0-0x210 -> mancano 0x120 poll/do_sys_poll la finestra termina a T0-0x344, max 0xf0B (N_STACK_PPS=30) -> mancano 0x14 rt_sigreturn (fpsimd) T0-0x300 -> raggiunge solo waiter+0x30 rt_sigreturn (SVE) T0-0x310 -> coprirebbe waiter+0x10, ma questa CPU non ha SVE; il kernel rifiuta i record sigframe SVE con -EINVAL compat rt_sigreturn / vfp T0-0x2c0 -> ancora più superficiale
Scansione dell'intero kernel di tutti i siti copy_from_user: 655 totali, 118 raggiungibili, profondità massima 0x300 (bpf_prog_get_info_by_fd, anch'esso vincolato da CAP_BPF). Servono 0x318.
Conclusione: la geometria dello stack di questo kernel si ferma a 0x300 per copy_from_user basato sullo stack; coprire pi_tree_entry richiede 0x318. Non è una questione di tuning - è una differenza di layout dei frame decisa in fase di compilazione. do_futex non è inlined qui, a differenza di PFEM10 (5.10.236, Clang 12.0.5), molto probabilmente per un diverso modello di costo di inlining.
Cerco:
Riferimento: https://github.com/x-spy/CVE-2026-43499-popsicle