FlawOpen

flawopen.com/Teardowns/cve-2026-49878-android-wpa-supplicant-oob-write

● CVE-2026-49878 · CVSS 7.2 · Alta
Pesquisa · FlawOpen

CVE-2026-49878: escrita fora dos limites no Wi-Fi do Android

O boletim Android de outubro de 2026 classifica como Alta esta falha de execução remota no Wi-Fi. O AOSP corrigiu duas alocações de arrays int feitas em bytes, não em elementos. O registro informa que são necessários privilégios de sistema.

💡 Explicação em Linguagem Simples (ELI5)

Imagine uma prateleira para uma caixa por item, mas o funcionário reserva apenas um centímetro por caixa. As caixas acabam ultrapassando o espaço. Em CVE-2026-49878, o wpa_supplicant reservava bytes usando a quantidade de inteiros e depois gravava inteiros completos. O patch do Google reserva cada elemento pelo tamanho correto.

Conceitos Centrais e Termos

wpa_supplicant
Componente Wi-Fi do Android que gerencia a autenticação sem fio e interações 802.11.
Resposta SCS
Quadro de ação de resposta do Stream Classification Service. O handler só o processa se houver solicitação pendente e o token de diálogo corresponder.
Escrita fora dos limites (CWE-787)
Gravação além da região de memória reservada. Aqui a alocação conta bytes, mas o código indexa elementos int.
os_zalloc / os_calloc
Auxiliares de alocação do wpa_supplicant. O patch usa contagem e tamanho do elemento para reservar o array completo.
Nível do patch de segurança Android (SPL)
Data que identifica o nível de atualização instalado. O Google diz que 2026-10-01 ou posterior corrige o boletim; a distribuição depende do fabricante.

Mapeamentos de frameworks

  • Referência CWE para a fraqueza descrita neste guia: CWE-787

Análise de Causa Raiz

Em wpas_handle_robust_av_scs_recv_action, scs_resp[0] e [1] são arrays int *. Antes da correção, os_zalloc(num_active_scs) reservava apenas esse número de bytes. O código grava IDs e estados inteiros por índice; portanto, precisa de num_active_scs * sizeof(int) bytes. As verificações de solicitação pendente, token correspondente, contagem e tamanho do quadro limitam a entrada, mas não corrigem a unidade da alocação. O patch AOSP troca ambas as chamadas por os_calloc(num_active_scs, sizeof(int)). Não se infere execução de código controlada pelo atacante a partir da escrita fora dos limites.

Fluxo de Ataque Passo a Paso

Passo 1

Um quadro de resposta chega ao handler

O caminho Wi-Fi direciona Robust AV SCS Response ao handler afetado. O caminho é de rede, mas as fontes não provam que qualquer transmissor sem autenticação satisfaça todas as condições.

Passo 2

Estado da solicitação e limites são verificados

O handler exige solicitação pendente e token correspondente, depois valida a contagem. O vetor CISA-ADP no NVD indica AV:N/AC:L/PR:H/UI:N; mantenha o requisito de privilégios altos.

Passo 3

Valores inteiros excedem a alocação em bytes

O código antigo reserva um byte por entrada e grava valores int. Limitar a quantidade não aumenta a memória alocada.

Passo 4

O patch de outubro corrige a alocação

A mudança do Google aloca num_active_scs elementos de sizeof(int) para os dois arrays. Não invente payload nem alegue que o diff demonstra execução arbitrária.

Código-Fonte: Vulnerável vs. Seguro

O diff é a alteração de código publicada pelo AOSP no commit d131540379d631d7dcb09b0169e4462bc65abcca, não pseudocódigo reconstruído. os_zalloc(n) usa n como quantidade de bytes; os_calloc(count, size) reserva e zera a quantidade de elementos solicitada. A correção ajusta os dois arrays paralelos e mantém a limpeza existente em caso de falha de alocação.

IMPLEMENTAÇÃO VULNERÁVEL
/* AOSP antes da correção: num_active_scs é uma contagem de elementos,
 * mas os_zalloc recebe esse valor como uma quantidade de bytes. */
scs_resp[0] = (int *) os_zalloc(num_active_scs);
if (!scs_resp[0])
    return;

scs_resp[1] = (int *) os_zalloc(num_active_scs);
if (!scs_resp[1]) {
    os_free(scs_resp[0]);
    return;
}
PATCH SEGURO E ROBUSTO
/* Correção do AOSP: aloque um int completo para cada entrada. */
scs_resp[0] = os_calloc(num_active_scs, sizeof(int));
if (!scs_resp[0])
    return;

scs_resp[1] = os_calloc(num_active_scs, sizeof(int));
if (!scs_resp[1]) {
    os_free(scs_resp[0]);
    return;
}

Lista de Verificação de Segurança para Engenharia

Fontes