
UpdatedAug 8, 2026
cve-2026-43499 — Updated!
PD2229B的43499(ghostlock)可行性研究
Resumo da Falha de Exploração do GhostLock no PD2229 (SM8475, 5.10.233 GKI)
一、Fatos sobre a Vulnerabilidade e o Dispositivo
1.1 Informações Básicas do CVE-2026-43499 (GhostLock)
| Item | Valor |
|---|---|
| Tipo de vulnerabilidade | Use-After-Free na pilha no caminho rt_mutex / futex PI |
| Versão introduzida | Linux 2.6.39-rc1 (maio de 2011, commit 8161239a8bcc) |
| Versão corrigida | mainline 7.1 (commit 3bfdc63936dd), ramos estáveis: 6.1.175 / 6.6.140 / 6.12.86 / 6.18.27 / 7.0.4 |
| Pré-requisito | CONFIG_FUTEX_PI=y (ativado por padrão nos kernels convencionais) |
| CVSS | 7.8 Alta |
| Estabilidade da exploração | 97% na cadeia original da NebuSec, root em ~5 segundos |
| Recompensa kernelCTF | US$ 92.337 |
Faixa de kernels afetados:
- 2.6.39 ≤ Linux < 6.1.175 ✅ Afetado
- 6.2 ≤ Linux < 6.6.140 ✅ Afetado
- 6.7 ≤ Linux < 6.12.86 ✅ Afetado
- 6.13 ≤ Linux < 6.18.27 ✅ Afetado
- 6.19 ≤ Linux < 7.0.4 ✅ Afetado
- Android GKI 5.10 não está em nenhum ramo de correção → 5.10.233 do PD2229 teoricamente afetado
1.2 Testes reais no dispositivo PD2229
| Item | Valor |
|---|---|
| SoC | Qualcomm SM8475 (Snapdragon 8 Gen 1 Plus) |
| Versão do kernel | 5.10.233-gki-g6e61de9f5b58 #1 SMP PREEMPT (24 de nov. de 2025) |
| Versão do Android | 15 (OriginOS 5) |
| Data de compilação | 25/11/2025 |
| Patch do Android | 01/11/2025 |
CONFIG_FUTEX_PI | y ✅ |
CONFIG_UNMAP_KERNEL_AT_EL0 | y (KPTI ativado) |
kptr_restrict | aplicado |
CONFIG_IO_URING | y ✅ (confirmado por símbolos vmlinux, e o seccomp não bloqueia io_uring_setup) |
二、Cadeia de exploração ideal vs. progresso real no PD2229
2.1 Cadeia original da NebuSec (bem-sucedida em x86_64 / Pixel 10)
1. Bypass do KASLR → timing de prefetch / PR_SET_MM_MAP auxv
2. Gatilho do UAF → deadlock de dependência PI de três threads → FUTEX_CMP_REQUEUE_PI retorna -EDEADLK
3. Reciclagem da pilha → PR_SET_MM_MAP copia auxv para o frame da pilha do waiter
4. Escrita restrita rb_erase → sobrescreve inet6_protos[IPPROTO_UDP]
5. CEA + ROP → sequestro do fluxo de controle
6. Inversão do core_pattern → shell root (97% de sucesso)
2.2 Progresso real de cada etapa no PD2229
| Etapa | Status | Descrição |
|---|---|---|
| 1. Bypass do KASLR | ✅ Implementado | Canal lateral perf_event_open + amostragem de callchain (mesmo método de adaptação do OPPO Find X6 Pro 5.15.149) |
| 2. Gatilho do UAF | ✅ Implementado | Deadlock PI de três threads bem-sucedido, FUTEX_CMP_REQUEUE_PI retorna -EDEADLK |
| 3. Primitiva de reciclagem da pilha | ❌ Falha arquitetural | Os frames de pilha de todas as syscalls conhecidas não se sobrepõem ao waiter (ver Seção 3) |
| 4. Escrita restrita rb_erase | ❌ Bloqueada | Pré-requisitos não atendidos |
| 5. Sobrescrita do inet6_protos | ❌ Não iniciada | Depende da etapa 4 |
| 6. ROP / sequestro do fluxo de controle | ❌ Não iniciada | Depende da etapa 5 |
| 7. shell root | ❌ Não iniciada | Depende da etapa 6 |
三、Resultados da enumeração exaustiva da primitiva de reciclagem da pilha (testes reais no PD2229)
3.1 Cálculos-chave do layout do frame de pilha
Profundidade total do caminho futex:
__arm64_sys_futex 0x90
+ do_futex 0xc0
+ futex_wait_requeue_pi 0x1b0
= 0x300
Posição do waiter = SYS_SP - 0x300 + 0x20 = SYS_SP - 0x2e0
Caminho pselect:
frame de pilha core_sys_select 0x1c0, stack_fds em sp+0x50
Intervalo coberto: SYS_SP - 0x1c0 + 0x50 = a partir de SYS_SP - 0x170
Diferença para o waiter (SYS_SP - 0x2e0) é 0x170 (368 bytes) → sem sobreposição
3.2 17 métodos de escrita na pilha testados
| # | Método | Syscall | Resultado no PD2229 | Motivo principal da falha |
|---|---|---|---|---|
| 1 | stamp_prctl | PR_SET_MM_MAP | ❌ EPERM | Bloqueio rígido do Android |
| 2 | stamp_pselect | pselect6 (NFDS=320) | ❌ Sem sobreposição | waiter 120B abaixo do fd_set |
| 3 | stamp_pselect | pselect6 (NFDS>336) | ❌ Alocação no heap | Caminho kvmalloc |
| 4 | stamp_socket | MCAST_JOIN_SOURCE_GROUP | ❌ Cobertura insuficiente | Escreve apenas o campo lock |
| 5 | stamp_sendmsg | sendmsg | ❌ 80B do waiter | Profundidade do frame 0x90 insuficiente |
| 6 | stamp_sendmmsg | sendmmsg | ❌ 112B do waiter | Frame de pilha insuficiente |
| 7 | stamp_recvmmsg | recvmmsg | ❌ Zera task/lock | Frame 0x1d0 corrompe ponteiros críticos |
| 8 | stamp_process_vm | process_vm_writev | ❌ Sem sobreposição | Pilha da thread filha alocada separadamente |
| 9 | stamp_keyctl | KEYCTL_INSTANTIATE_IOV | ❌ EOPNOTSUPP | Syscall não suportada + frame 0x40 |
| 10 | stamp_tcp | TCP_ZEROCOPY_RECEIVE | ❌ Frame insuficiente | Profundidade estimada insuficiente |
| 11 | stamp_futex | FUTEX_CMP_REQUEUE_PI recursivo | ❌ Logicamente inviável | Corrompe a janela do UAF |
| 12 | binder ioctl | BINDER_WRITE_READ | ❌ EACCES | shell sem permissão em /dev/binder |
| 13 | poll | poll | ❌ Alocação no heap | pollfd no heap |
| 14 | epoll_wait | epoll_wait | ❌ Frame muito raso | Frame de pilha 0xE0 |
| 15 | sched_setattr | sched_setattr | ❌ Profundidade insuficiente | Frame de pilha 0xb0 |
| 16 | timerfd_settime | timerfd_settime | ❌ Sem cópia na pilha | Sem buffer grande na pilha |
| 17 | io_uring_register | IORING_REGISTER_* | ❌ Dupla falha | ①Frame de pilha de apenas 0xF0, destino do copy_from_user fixo em sp+0x8 (diferença de 424 bytes do sp+0x1D0 do waiter); ②Embora io_uring_setup não seja bloqueado pelo seccomp (retorna EFAULT em vez de ENOSYS), o layout da pilha não corresponde |
17/17 todas falharam.
3.3 Causa raiz da falha
O layout da pilha gerado pelo compilador do SM8475 5.10 GKI do PD2229 (PGO + LTO + BOLT) faz com que o stack_fds do core_sys_select e o rt_mutex_waiter do futex_wait_requeue_pi sejam arquiteturalmente não sobrepostos. Este é um fato objetivo determinado pelo compilador, não um problema de técnica de exploração.
O repositório JoinChang afirma explicitamente: "The pselect stack overlay only works when the freed rt_mutex_waiter lands within the user-controllable region of the stack_fds buffer" — o PD2229 não atende a essa condição.
四、Análise comparativa dos repositórios de referência públicos
NebuSec/CyberMeowfia — Framework de exploração original
- Repositório: https://github.com/NebuSec/CyberMeowfia
- Alvo: Linux x86_64 / Pixel 10 (6.x GKI)
- Reciclagem da pilha:
PR_SET_MM_MAPcopia auxv para a pilha do kernel - Taxa de sucesso: 97%, ~5 segundos para [shell root]
- Aplicabilidade ao PD2229: ❌
PR_SET_MM_MAPbloqueado por EPERM no Android
JoinChang/ghostlock-oneplus — Jailbreak do bootloader OnePlus
- Repositório: 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 ✅
- Pontos técnicos:
- Extração automática de offsets: kallsyms (28) + BTF (57) + derivados (9) + constantes (12) = 103/103
- Sobreposição de pilha pselect, SP diff = -64
PSELECT_SHIFT = -2- Cadeia de exploração: futex UAF → waiter falsificado → pselect controla a pilha → escrita restrita rb_erase → selinux_state.enforcing=0 → sobrescrita do cred para init_cred
- Declaração explícita de inviabilidade: "Not Feasible (stack layout incompatible)" — aplicável apenas a kernels onde pselect stack_fds e waiter se sobrepõem
- Aplicabilidade ao PD2229: ❌ Geração do kernel incompatível (6.12 vs 5.10) e layout de pilha sem sobreposição
p2p3p/GhostLock-for-OnePlus — Exploração completa do OnePlus 6.12
- Repositório: https://github.com/p2p3p/GhostLock-for-OnePlus
- Verificado: OnePlus Ace 6T (SM8845, 6.12.38) ✅
- Aplicabilidade ao PD2229: ❌ Igual ao JoinChang, geração do kernel incompatível