FlawOpen

flawopen.com/Teardowns/cve-2024-1086-linux-netfilter-nftables-uaf

● CVE-2024-1086 · CVSS 7.8 · Alta
Pesquisa · FlawOpen

CVE-2024-1086: use-after-free no Linux nf_tables

CVE-2024-1086 é um use-after-free no nf_tables do Linux por parâmetros DROP inválidos. Instale o kernel corrigido da sua distribuição.

💡 Explicação em Linguagem Simples (ELI5)

Imagine um formulário em que o atendente só pode escolher “aceitar” ou “descartar”. Há também um campo para o código de erro do descarte, que só aceita zero ou um erro negativo válido. O validador vulnerável deixou o valor positivo “aceitar” entrar nesse campo. Mais tarde, o código de rede interpretava o veredicto de forma inconsistente. A correção aceita apenas os valores de veredicto previstos.

Conceitos Centrais e Termos

nf_tables
Subsistema do kernel Linux usado pelo nftables para configurar filtragem de pacotes e regras de rede relacionadas.
Veredicto Netfilter
Resultado da avaliação de uma regra de pacote no kernel, como NF_ACCEPT ou NF_DROP. Um DROP pode carregar um valor de erro que o hook espera ser zero ou um errno negativo válido.
Use-after-free (CWE-416)
Falha de segurança em que o código acessa um objeto depois do fim de sua vida útil. Neste caso, o NVD registra uma vulnerabilidade local de elevação de privilégios no kernel.
User namespace
Namespace Linux que mapeia identidades e capacidades de processos. A criação por usuários sem privilégios depende da política do kernel e da distribuição; não implica, por si só, acesso ao host.

Mapeamentos de frameworks

Análise de Causa Raiz

Em net/netfilter/nf_tables_api.c, nft_verdict_init() antes aplicava uma máscara ao veredicto e aceitava parâmetros de NF_DROP ou NF_QUEUE. O hook do Netfilter espera que os bits superiores de NF_DROP representem zero ou um errno negativo válido. A correção upstream registra que um valor positivo como NF_ACCEPT podia causar use-after-free. O patch elimina a validação permissiva e aceita apenas os veredictos exatos; valores inválidos retornam -EINVAL. NVD classifica o impacto como elevação local de privilégios. A possibilidade de exploração depende do kernel, das capacidades disponíveis e da política da distribuição; não presuma que todo contêiner tenha o mesmo risco.

Fluxo de Ataque Passo a Paso

Passo 1

Capacidade local de gerenciar regras

O ataque documentado é local. O processo precisa alcançar a validação de veredictos do nf_tables; capacidades necessárias e disponibilidade de user namespaces não privilegiados dependem da configuração do host.

Passo 2

Parâmetro de veredicto inválido chega à validação

Antes da correção, nft_verdict_init() aceitava certos valores parametrizados após aplicar NF_VERDICT_MASK, incluindo um valor positivo como NF_ACCEPT nos bits do parâmetro.

Passo 3

O hook chega ao use-after-free

O hook do Netfilter interpreta parâmetros de NF_DROP como zero ou errno negativo válido. O relato upstream informa que o valor positivo aceito pode causar use-after-free no processamento de pacotes; o patch não documenta uma primitiva universal nem uma fuga de contêiner garantida.

Passo 4

Instale o kernel corrigido da distribuição

A alteração upstream rejeita parâmetros de veredicto não suportados. Instale e inicialize o kernel corrigido fornecido pela distribuição, pois as versões e os backports variam.

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

O código vulnerável mascarava o veredicto e seguia para outros casos, permitindo valores parametrizados como NF_ACCEPT positivo no campo de erro de NF_DROP. A correção aceita apenas constantes exatas e retorna -EINVAL para qualquer outro valor. São trechos focados do patch upstream, não funções independentes compiláveis.

Trecho de origem: net/netfilter/nf_tables_api.c

IMPLEMENTAÇÃO VULNERÁVEL
/* Trecho de nft_verdict_init() em net/netfilter/nf_tables_api.c, antes de f342de4e2f33.
 * O caminho com valor mascarado aceitava vereditos parametrizados. */
switch (data->verdict.code) {
default:
    switch (data->verdict.code & NF_VERDICT_MASK) {
    case NF_ACCEPT:
    case NF_DROP:
    case NF_QUEUE:
        break;
    default:
        return -EINVAL;
    }
    fallthrough;
case NFT_CONTINUE:
case NFT_BREAK:
case NFT_RETURN:
    /* O tratamento dos outros vereditos existentes continua. */
    break;
}
PATCH SEGURO E ROBUSTO
/* Trecho de nft_verdict_init() em net/netfilter/nf_tables_api.c,
 * conforme alterado por f342de4e2f33. */
switch (data->verdict.code) {
case NF_ACCEPT:
case NF_DROP:
case NF_QUEUE:
    break;
case NFT_CONTINUE:
case NFT_BREAK:
case NFT_RETURN:
    /* O tratamento dos outros vereditos existentes continua. */
    break;
default:
    return -EINVAL;
}

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

Fontes