
Risultati di sicurezza di EDK2 BrotliCustomDecompressLib — divulgazione coordinata
Un heap-buffer-overflow nel glue di decompressione Brotli di EDK2
(MdeModulePkg/Library/BrotliCustomDecompressLib), presente dal 2017, non corretto
a HEAD al 2026-10-25. Confermato con ASAN tramite un proof-of-concept e una
demo end-to-end di corruzione controllata.
Il wrapper Brotli di EDK2 legge la dimensione dell'output decompresso da un
header di sezione GUIDed controllato dall'attaccante, la tronca da UINT64 a UINT32 senza
alcuna protezione, e la passa al core DXE che alloca un buffer di quella dimensione.
BrotliDecompressInternal decomprime poi in quel buffer senza limiti — continua
finché il flusso Brotli non termina, scrivendo oltre l'allocazione.
Risultato: heap overflow (primitiva di scrittura) nella fase DXE, prima che la verifica di Secure Boot sia completata. Un attaccante che controlla l'immagine del firmware (flash, capsule, o ESP) può sovrascrivere oggetti pool adiacenti — puntatori a funzione, flag di sicurezza, strutture di protocollo — con byte scelti.
Questo è il fratello Brotli trascurato di CVE-2021-28211 (LZMA ha ricevuto una
protezione >MAX_UINT32 nel 2021; Brotli mai). Una scansione delle varianti conferma che Brotli
è l'unico decompressore EDK2 privo sia della protezione sulla troncatura sia di un
limite sull'output.
| File | Cosa fa |
|---|---|
BrotliDecompress.c:238 | Converte la dimensione decodificata da UINT64 a UINT32 — nessuna protezione MAX_UINT32 |
BrotliDecompress.c:118–157 | Decomprime nel buffer di destinazione senza controllo dei limiti |
GuidedSectionExtraction.c | Chiama GetInfo poi Decompress — si fida della dimensione dichiarata |
CoreSectionExtraction.c:1597 | Alloca il buffer di destinazione alla dimensione dichiarata |
Tutti in tianocore/edk2, MdeModulePkg/Library/BrotliCustomDecompressLib.
| Artefatto | Descrizione |
|---|---|
harness/edk2_brotli_overflow_poc.c | Proof-of-concept ASAN: flusso da 4096 byte in un buffer da 64 byte |
harness/asan_output.txt | Output ASAN: heap-buffer-overflow in BrotliDecompressInternal → memcpy |
harness/edk2_brotli_overflow_demo.c | Demo end-to-end: corruzione controllata di oggetti pool adiacenti |
harness/demo_output.txt | Output della demo: puntatori a funzione dirottati, Secure Boot disabilitato |
harness/lvfs_brotli_scan.py | Scanner firmware LVFS (misurazione del raggio d'impatto) |
harness/lvfs_scan_output.txt | Risultati della scansione: 0/200 immagini firmware usano Brotli |
evidence/ | Copie dei file sorgente EDK2 vulnerabili a HEAD |
FINDINGS.md | Resoconto completo: riferimenti di riga, ricerca di prior art, scansione delle varianti, audit LZMA |
Ristretto. Due indagini indipendenti non hanno trovato alcuna piattaforma che usi sezioni GUIDed Brotli in pratica:
BrotliCustomDecompressLib. Ogni occorrenza è MdeModulePkg.dsc stesso.Il codice vulnerabile è presente nell'albero EDK2 ma oggi è codice morto — aggiunto nel 2017, mai adottato da IBV o OEM. Il bug è reale e sfruttabile in linea di principio; se l'adozione di Brotli aumenterà, diventerà immediatamente raggiungibile.
Due modifiche, in linea con quanto già presente in LZMA e Tiano:
MAX_UINT32 a BrotliUefiDecompressGetInfo
(BrotliDecompress.c:238): rifiutare dimensioni decodificate > MAX_UINT32, come
fa LzmaDecompress.c:149 dal CVE-2021-28211.BrotliDecompressInternal: tenere traccia dei byte scritti e
fermarsi a DestinationSize, come fa il decompressore Tiano con mOrigSize.Compilare il PoC su Linux con 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
Divulgazione pubblica completa, 2026-10-26. Non è stato concesso alcun periodo di divulgazione coordinata a TianoCore. Il raggio d'impatto ristretto (nessun firmware in distribuzione interessato) e il fatto che il bug gemello relativo a LZMA sia pubblico dal 2021 hanno motivato questa decisione.