
Descobertas de segurança do EDK2 BrotliCustomDecompressLib — divulgação coordenada
Um heap-buffer-overflow na própria camada de descompressão Brotli do EDK2
(MdeModulePkg/Library/BrotliCustomDecompressLib), presente desde 2017, não corrigido
no HEAD em 2026-10-25. Confirmado por ASAN com uma prova de conceito e uma
demonstração de corrupção controlada de ponta a ponta.
O wrapper Brotli do EDK2 lê o tamanho da saída descomprimida de um
cabeçalho de seção GUIDed controlado pelo atacante, trunca-o de UINT64 → UINT32 sem
nenhuma proteção, e o passa ao núcleo DXE, que aloca um buffer desse tamanho.
BrotliDecompressInternal então descomprime nesse buffer sem limite — ele
executa até o fluxo Brotli terminar, escrevendo além da alocação.
Resultado: estouro de heap (primitiva de escrita) na fase DXE, antes da verificação do Secure Boot ser concluída. Um atacante que controla a imagem de firmware (flash, cápsula, ou ESP) pode sobrescrever objetos de pool adjacentes — ponteiros de função, flags de segurança, estruturas de protocolo — com bytes escolhidos.
Este é o irmão Brotli negligenciado do CVE-2021-28211 (o LZMA recebeu uma
proteção >MAX_UINT32 em 2021; o Brotli nunca recebeu). Uma varredura de variantes confirma que o Brotli
é o único descompressor do EDK2 que carece tanto da proteção de truncamento quanto de um
limite de saída.
| Arquivo | O que faz |
|---|---|
BrotliDecompress.c:238 | Converte o tamanho decodificado UINT64 para UINT32 — sem proteção MAX_UINT32 |
BrotliDecompress.c:118–157 | Descomprime no buffer de destino sem verificação de limite |
GuidedSectionExtraction.c | Chama GetInfo e depois Decompress — confia no tamanho declarado |
CoreSectionExtraction.c:1597 | Aloca o buffer de destino no tamanho declarado |
Tudo em tianocore/edk2, MdeModulePkg/Library/BrotliCustomDecompressLib.
| Artefato | Descrição |
|---|---|
harness/edk2_brotli_overflow_poc.c | Prova de conceito ASAN: fluxo de 4096 bytes em buffer de 64 bytes |
harness/asan_output.txt | Saída ASAN: heap-buffer-overflow em BrotliDecompressInternal → memcpy |
harness/edk2_brotli_overflow_demo.c | Demonstração de ponta a ponta: corrupção controlada de objetos de pool adjacentes |
harness/demo_output.txt | Saída da demonstração: ponteiros de função sequestrados, Secure Boot desativado |
harness/lvfs_brotli_scan.py | Scanner de firmware LVFS (medição do raio de impacto) |
harness/lvfs_scan_output.txt | Resultados da varredura: 0/200 imagens de firmware usam Brotli |
evidence/ | Cópias dos arquivos-fonte vulneráveis do EDK2 no HEAD |
FINDINGS.md | Relatório completo: referências de linha, busca de trabalhos anteriores, varredura de variantes, auditoria do LZMA |
Estreito. Duas pesquisas independentes encontraram zero plataformas que usam seções GUIDed Brotli na prática:
BrotliCustomDecompressLib. Toda ocorrência é o próprio MdeModulePkg.dsc.O código vulnerável é distribuído na árvore do EDK2, mas é código morto hoje — adicionado em 2017, nunca adotado por IBVs ou OEMs. O bug é real e explorável em princípio; se a adoção do Brotli aumentar, ele se torna imediatamente alcançável.
Duas mudanças, correspondendo ao que o LZMA e o Tiano já possuem:
MAX_UINT32 a BrotliUefiDecompressGetInfo
(BrotliDecompress.c:238): rejeitar tamanhos decodificados > MAX_UINT32, como
LzmaDecompress.c:149 faz desde o CVE-2021-28211.BrotliDecompressInternal: rastrear os bytes escritos e
parar em DestinationSize, como o descompressor Tiano faz com mOrigSize.Compile a PoC no Linux com libbrotli e GCC:
# ASAN proof (aborts at the overflow)
gcc -fsanitize=address -g -O1 -o poc harness/edk2_brotli_overflow_poc.c \
-lbrotlienc -lbrotlidec
./poc
# Controlled-corruption demo (completes the overflow, shows the damage)
gcc -g -O1 -o demo harness/edk2_brotli_overflow_demo.c \
-lbrotlienc -lbrotlidec
./demo
Divulgação pública completa, 2026-10-26. Nenhum período de divulgação coordenada foi concedido ao TianoCore. O raio de impacto restrito (nenhum firmware em produção afetado) e o fato de que o bug irmão do LZMA é público desde 2021 embasaram esta decisão.