
Exploit de prova de conceito para escalonamento local de privilégios em uma condição de corrida na rate-table do qdisc do Linux, usando heap grooming com BPF e um vazamento via pipe para obter root.

Este repositório contém uma prova de conceito de exploração de escalonamento local de privilégios para a CVE-2026-68138, uma condição de corrida no código da tabela de taxas do controlador de tráfego do Linux. No ambiente QEMU testado, o PoC eleva um processo comum com UID externo 1000 a um shell com UID 0 no namespace de usuário inicial.
Aviso
Este código corrompe intencionalmente o estado da memória do kernel. Use-o somente em uma VM isolada e descartável que lhe pertença. Uma corrida perdida ou uma limpeza prematura pode causar pânico no convidado. Não o execute em uma estação de trabalho, servidor ou sistema de terceiros.
qdisc_get_rtab() e qdisc_put_rtab() gerenciam uma lista encadeada
singular global ao processo, qdisc_rtab_list, e um int refcnt simples e
não atômico. Historicamente, os chamadores mantinham o mutex RTNL, que
serializava o acesso à lista e à contagem de referências.
O classificador flower define TCF_PROTO_OPS_DOIT_UNLOCKED. Uma requisição
RTM_NEWTFILTER para uma regra flower pode, consequentemente, alcançar uma
ação de polícia e chamar os auxiliares da tabela de taxas do qdisc sem RTNL:
tc_new_tfilter()
-> fl_change()
-> tcf_exts_validate_ex()
-> tcf_action_init()
-> tcf_police_init()
-> qdisc_get_rtab()/qdisc_put_rtab()
Requisições concorrentes que usam a mesma tabela de taxas podem competir pela
lista global e por sua contagem de referências. O resultado é um
use-after-free ou double-free de struct qdisc_rate_table, um objeto de 1056
bytes alocado de kmalloc-2k no kernel x86-64 testado.
Como a lista é global em vez de por namespace de rede, requisições de namespaces de rede separados ainda competem pelo mesmo objeto.
O registro CNA do Linux identifica o commit de introdução
470502de5bdb,
lançado no Linux 5.1.
| Linha | Status | Commit/versão |
|---|---|---|
| Linux antes de 5.1 | Não afetado | A alteração introdutória está ausente |
| Linux 5.1 até 7.1.5 | Afetado, salvo se houver backport do fornecedor | 470502de5bdb até o commit anterior à correção estável |
| Linux 7.1.y | Corrigido | 7.1.6, fb29e1b41052 |
| Série de desenvolvimento do Linux 7.2 | Afetado antes do rc5 | rc1 até rc4 |
| Mainline | Corrigido | 7.2-rc5, f43ee0c0730d |
Kernels de distribuições frequentemente aplicam correções por backport sem alterar a versão upstream mostrada acima. Verifique se algum dos commits de correção — ou a alteração equivalente do spinlock da tabela de taxas do qdisc — está presente no código-fonte exato do kernel usado pelo sistema.
A exploração foi desenvolvida e validada contra o commit vulnerável
92d3817649df2b0b6a008a686c8275c88d7ef594, o pai direto da correção do
mainline. O controle com kernel corrigido usou
f43ee0c0730d6191629b5ee1ceae27b1ebfdc047.
Em 2026-08-12, a
pesquisa do rastreador de CVEs do Ubuntu
não retornou uma entrada para esta CVE. A tabela abaixo é, portanto, uma
inspeção direta do código-fonte, não uma determinação de status de segurança
da Canonical. Cada tag Ubuntu vinculada ainda possui a qdisc_rtab_list sem
bloqueio e não contém a correção qdisc_rtab_lock.
| Linha do Ubuntu | Pacote/tag inspecionado | Resultado do código-fonte |
|---|---|---|
| Ubuntu 22.04 GA | 5.15.0-187.197 | Código vulnerável presente; exploração completa reproduzida no QEMU |
| Ubuntu 22.04 HWE | 6.8.0-136.136~22.04.1 | Código vulnerável presente; cadeia de exploração não testada |
| Ubuntu 24.04 HWE | 7.0.0-28.28~24.04.1 | Código vulnerável presente; esta cadeia de exploração não é compatível com o endurecimento do alocador dela |
| Ubuntu 26.04 | 7.0.0-28.28 | Código vulnerável presente; esta cadeia de exploração não é compatível com o endurecimento do alocador dela |
Nenhum pacote Ubuntu corrigido foi identificado na data dessa inspeção. Pacotes Ubuntu futuros devem ser verificados quanto a um backport equivalente às correções upstream vinculadas, e não avaliados apenas pelo número de versão.
A exploração específica para a build do Ubuntu 22.04, o laboratório QEMU, a
soma de verificação exata da imagem e as condições estão documentados em
ubuntu/README.md. Ela foi validada contra o kernel
oficial 5.15.0-187-generic #197-Ubuntu com contabilização de cgroup de
memória ativada.
O bug subjacente e esta cadeia de exploração específica têm requisitos diferentes. O PoC foi validado com:
CONFIG_USER_NS=y e CONFIG_NET_NS=y;CONFIG_NET_CLS=y, CONFIG_NET_CLS_FLOWER=y,
CONFIG_NET_CLS_ACT=y e CONFIG_NET_ACT_POLICE=y;CONFIG_TMPFS_XATTR=y para o heap spray com simple_xattr;CONFIG_MODULES=y e um /sbin/modprobe utilizável para o auxiliar final de root;CONFIG_MEMCG=n, para que as alocações qdisc/BPF/pipe/xattr usadas por esta
cadeia compartilhem o cache kmalloc-2k esperado;CONFIG_SLAB_BUCKETS=y, randomização de freelist e endurecimento de freelist
estavam ativados no kernel de teste bem-sucedido. O KASLR não é contornado
inerentemente com um endereço fixo: o PoC obtém o ponteiro de página e os
ponteiros de operações necessários por meio do vazamento de pipe. O laboratório
fornecido usou nokaslr para simplificar a depuração.
Kernels com contabilização de cgroup de memória ativada ou com layouts de alocador/cache diferentes exigem uma estratégia de reaproveitamento diferente. O PoC deliberadamente se recusa a afirmar portabilidade entre configurações arbitrárias de distribuições.
A variante separada do Ubuntu implementa essa estratégia de reaproveitamento
diferente; seus requisitos são intencionalmente mais restritos e estão
listados em ubuntu/README.md.
Quatro threads de trabalho entram em namespaces de rede distintos e criam filtros flower com ações de polícia. Três workers seguem o caminho de ação bem- sucedida; um fornece um estimador deliberadamente inválido após adquirir ambas as referências da tabela de taxas, forçando o caminho de limpeza. Essa combinação torna a manipulação concorrente da contagem de referências e da lista reproduzível sem compartilhar o estado do classificador flower entre os workers.
qdisc_rate_table com BPF clássico