
Exploit local de root para CVE-2025-21479 (Adreno KGSL) no iQOO Neo8 (SM8475) - leitura/escrita de memória física, desativa o SELinux, abre um shell root.
Código de experimento de escalada local de privilégios para CVE-2025-21479, direcionado à GPU Qualcomm Adreno (KGSL) no vivo V2301A (iQOO Neo8 / PD2301, Snapdragon 8+ Gen 1 / SM8475, Adreno A730, Android 14, kernel GKI 5.10).
Em princípio, a exploração da vulnerabilidade utiliza o comando CP_SMMU_TABLE_UPDATE do KGSL para controlar a SMMU da GPU,
obtendo capacidade de leitura e escrita arbitrária na memória física, e assim desativar o SELinux, localizar símbolos do kernel e obter um
shell root — sem necessidade de flash em todo o processo, nem dependência de desbloqueio do Bootloader.
Pesquisa de segurança apenas em dispositivos que você possui ou para os quais tem autorização.
and $12, 0x3) tem uma falha que faz com que pacotes Self-Draw-State (SDS) sejam
erroneamente classificados como RingBuffer (RB). Assim, ao enviar um CP_SMMU_TABLE_UPDATE forjado
em um bloco SDS a partir do espaço do usuário, é possível sobrescrever o TTBR0 da GPU, fazendo com que a tabela de páginas da GPU aponte para qualquer página física — a partir daí a GPU
pode ler e escrever em qualquer memória física.stabilize_rw, o mapeamento é reforçado como uma região auto-mapeada de 2 MB,
permitindo leituras rápidas em grandes volumes (fast_pread_bytes etc.).selinux_state.enforcing na memória física.
Em seguida, extrair a imagem do kernel a partir do endereço físico fixo 0xA8000000 (limite padrão de 43 MB) —
o SM8475 não possui KASLR físico — e analisar a estrutura kallsyms diretamente do dump bruto
(detecção automática de endianness), de modo que o KASLR virtual também não afeta.prepare_kernel_cred(0) →
commit_creds(), e desativar o seccomp) para aplicar patch em __do_sys_capset. O processo filho criado por fork
chama capset() → torna-se uid 0 → restaura o código do kernel sobrescrito → o processo filho reexecuta o comando que você especificar no domínio
u:r:shell:s0 (padrão sh). O código do kernel, ao final,
fica byte a byte idêntico ao de antes da execução.| Modelo | vivo V2301A (iQOO Neo8, codinome PD2301, placa taro) |
| SoC | SM8475 (Snapdragon 8+ Gen 1) + Adreno 730 |
| Android | 14 (UP1A.231005.007, SDK 34, qssi-user) |
| Kernel | 5.10.198-gki-gfb2f5774872c |
| SELinux | Enforcing (desativado em tempo de execução por esta ferramenta) |
As informações completas do dispositivo estão em device_info.txt.
├── source/
│ ├── cheese.c # 漏洞利用主程序(include 了下面两个文件)
│ ├── kallsyms_lookup.c # 针对原始内核映像的 kallsyms 解析器
│ └── adrenaline.h # KGSL ioctl / 命令定义(作者 hawkes)
├── exploit # 预编译 arm64 二进制(动态链接,minSdk 21,
│ # NDK r30-beta2)
├── device_info.txt # 用于调参的目标设备信息
└── README.md
注意:cheese.c 会 #include kallsyms_lookup.c 和 adrenaline.h,
编译时三个文件需要放在同一目录。
Qualquer Android NDK razoavelmente recente (r25+) serve, exemplo:
# 静态链接(自包含、任意 API 等级可运行;体积较大)
aarch64-linux-android34-clang -o cheese source/cheese.c -static
# 动态链接(体积小,依赖设备自带的 libc;API 等级需匹配设备)
aarch64-linux-android34-clang -o exploit_dyn source/cheese.c
# 若要兼容 API 21+ 设备,请改用 aarch64-linux-android21-clang
#推送exploit
adb push exploit /data/local/tmp/
#运行exploit
adb shell
chmod +x /data/local/tmp/exploit
/data/local/tmp/exploit
Clique aqui para o tutorial detalhado (contém uma ferramenta tudo-em-um)
Após o sucesso, você obterá um shell com uid=0, e o SELinux desta sessão já estará desativado. O processo, após concluir a
escalada de privilégios, reexecutará argv[1..] (padrão sh). A cada execução haverá uma contagem regressiva
("pte wait 3 second") e um progresso de leitura do kernel de 43 MB ("Read X / 43 MB").

| Variável | Função |
|---|---|
CHEESE_PHYADDR=<phys> | Força a especificação do endereço físico base do kernel (ignora a tabela de detecção interna gPhyAddrs). |
CHEESE_ATTEMPT=<n> | Usa gPhyAddrs[n] em vez de gPhyAddrs[0]; após falha na inicialização da GPU, maybe_retry incrementa e tenta novamente automaticamente. |
CHEESE_SWAPPER_PG_DIR_OFF=<off> | Ignora a varredura de swapper_pg_dir e usa diretamente esse deslocamento absoluto. |
CHEESE_READ_FULL_KERNEL=1 | Lê a imagem completa do kernel (o limite padrão de leitura é DEFAULT_KERNEL_SIZE_MB = 43 MB). |
CHEESE_KALLSYMS_MAX_MB=<MB> | Substitui o limite de leitura de kallsyms. |
CHEESE_FORCE_MANUAL_PATCHFINDER=1 | Força o uso do patchfinder manual como fallback (init_cred, prepare_kernel_cred). |
CHEESE_SKIP_GPU=1 | Ignora a fase de leitura/escrita da GPU (apenas para depuração). |
CHEESE_NO_RETRY=1 | Sai diretamente após falha, sem tentar novamente com outro número. |
Devido ao mecanismo especial dos modelos vivo, no iQOO Neo8 é necessário desativá-lo para manter a estabilidade das permissões de root (o princípio específico não será explicado aqui. Outros modelos vivo e versões de kernel podem não ser compatíveis, sendo necessário extrair o vr.ko e realizar análise reversa por conta própria). Antes de executar as operações a seguir, certifique-se de que a sessão de shell atual já obteve permissões de root.
#备份原始apanic
dd if="$(readlink -f /dev/block/by-name/apanic)" of=/sdcard/apanic_full.bin
#adb shell内执行
adb pull /sdcard/apanic_full.bin ./
#主机端执行
#禁用vr.ko(风险自行评估)
printf '\370\037\000\000\000\000\000\000\000\000\000\000' | dd of=$(readlink -f /dev/block/by-name/apanic) bs=1 seek=$(( $(blockdev --getsize64 /dev/block/by-name/apanic) - 65472 )) conv=notrunc && sync
Depois, se reiniciar o telefone a frio fizer com que a permissão root deixe de funcionar, basta executar novamente o exploit e então realizar o jailbreak
$(find /data/app -type f -name "libksud.so" | grep resukisu) late-load --kmi android12-5.10
As constantes específicas do dispositivo estão no topo de source/cheese.c:
KERNEL_PHYS_BASE — endereço físico base do kernel (padrão 0xA8000000, SM8475)IDMAP_PG_DIR_OFFSET — deslocamento de idmap_pg_dir (padrão 0x245a000)selinux_state_offset — deslocamento usado para localizar selinux_state (padrão
0x729030, endereço físico real = endereço físico de idmap_pg_dir + esse deslocamento)gPhyAddrs[] — endereços físicos base candidatos, tentados em sequênciaDEFAULT_KERNEL_SIZE_MB — valor de fallback / limite máximo para a leitura do kernelPré-requisitos: GPU da série Adreno A730/A7xx (firmware afetado) e sistema do dispositivo sem o patch de segurança da Qualcomm lançado em junho de 2025, kernel cujo kallsyms possa ser resolvido a partir do dump físico, e ausência de KASLR físico.