
Constats de sécurité d'EDK2 BrotliCustomDecompressLib — divulgation coordonnée
Un débordement de tampon de tas dans la glue de décompression Brotli propre à EDK2
(MdeModulePkg/Library/BrotliCustomDecompressLib), présent depuis 2017, non corrigé
à HEAD au 2026-10-25. Confirmé par ASAN avec une preuve de concept et une
démonstration de corruption contrôlée de bout en bout.
Le wrapper Brotli d'EDK2 lit la taille de sortie décompressée depuis un
en-tête de section GUIDée contrôlé par l'attaquant, la tronque de UINT64 → UINT32 sans
garde-fou, et la transmet au cœur DXE qui alloue un tampon de cette taille.
BrotliDecompressInternal décompresse ensuite dans ce tampon sans borne — il
s'exécute jusqu'à la fin du flux Brotli, écrivant au-delà de l'allocation.
Résultat : débordement de tas (primitive d'écriture) dans la phase DXE, avant que la vérification Secure Boot ne soit terminée. Un attaquant qui contrôle l'image du firmware (flash, capsule, ou ESP) peut écraser des objets de pool adjacents — pointeurs de fonction, drapeaux de sécurité, structures de protocole — avec des octets choisis.
C'est le frère Brotli négligé de CVE-2021-28211 (LZMA a reçu une
garde >MAX_UINT32 en 2021 ; Brotli ne l'a jamais eue). Un balayage des variantes confirme que Brotli
est le seul décompresseur EDK2 qui manque à la fois de la garde de troncature et d'une
borne de sortie.
| Fichier | Ce qu'il fait |
|---|---|
BrotliDecompress.c:238 | Convertit la taille décodée UINT64 en UINT32 — aucune garde MAX_UINT32 |
BrotliDecompress.c:118–157 | Décompresse dans le tampon de destination sans vérification de borne |
GuidedSectionExtraction.c | Appelle GetInfo puis Decompress — fait confiance à la taille déclarée |
CoreSectionExtraction.c:1597 | Alloue le tampon de destination à la taille déclarée |
Tous dans tianocore/edk2, MdeModulePkg/Library/BrotliCustomDecompressLib.
| Artefact | Description |
|---|---|
harness/edk2_brotli_overflow_poc.c | Preuve de concept ASAN : flux de 4096 octets dans un tampon de 64 octets |
harness/asan_output.txt | Sortie ASAN : heap-buffer-overflow à BrotliDecompressInternal → memcpy |
harness/edk2_brotli_overflow_demo.c | Démo de bout en bout : corruption contrôlée d'objets de pool adjacents |
harness/demo_output.txt | Sortie de la démo : pointeurs de fonction détournés, Secure Boot désactivé |
harness/lvfs_brotli_scan.py | Scanner de firmware LVFS (mesure du rayon d'impact) |
harness/lvfs_scan_output.txt | Résultats du scan : 0/200 images de firmware utilisent Brotli |
evidence/ | Copies des fichiers source EDK2 vulnérables à HEAD |
FINDINGS.md | Rapport complet : références de lignes, recherche d'antériorité, balayage des variantes, audit LZMA |
Étroit. Deux enquêtes indépendantes n'ont trouvé aucune plateforme qui utilise des sections GUIDées Brotli en pratique :
BrotliCustomDecompressLib. Chaque occurrence est MdeModulePkg.dsc lui-même.Le code vulnérable est livré dans l'arbre EDK2 mais est du code mort aujourd'hui — ajouté en 2017, jamais adopté par les IBV ni les OEM. Le bug est réel et exploitable en principe ; si l'adoption de Brotli augmente, il devient immédiatement atteignable.
Deux changements, correspondant à ce que LZMA et Tiano possèdent déjà :
MAX_UINT32 à BrotliUefiDecompressGetInfo
(BrotliDecompress.c:238) : rejeter les tailles décodées > MAX_UINT32, comme
le fait LzmaDecompress.c:149 depuis CVE-2021-28211.BrotliDecompressInternal : suivre les octets écrits et
s'arrêter à DestinationSize, comme le fait le décompresseur Tiano avec mOrigSize.Compiler la PoC sous Linux avec libbrotli et 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
Divulgation publique complète, 2026-10-26. Aucune période de divulgation coordonnée n'a été accordée à TianoCore. Le rayon d'impact restreint (aucun firmware livré affecté) et le fait que le bug frère LZMA soit public depuis 2021 ont motivé cette décision.