
EDK2 BrotliCustomDecompressLib のセキュリティ上の発見 — 調整された開示
EDK2 自身の Brotli 展開グルーコード(MdeModulePkg/Library/BrotliCustomDecompressLib)に存在するヒープバッファオーバーフロー。2017年から存在し、2026-10-25 時点の HEAD でも未修正。概念実証(PoC)とエンドツーエンドの制御された破壊デモにより ASAN で確認済み。
EDK2 の Brotli ラッパーは、攻撃者が制御する GUIDed セクションヘッダーから展開後の出力サイズを読み取り、ガードなしで UINT64 → UINT32 に切り捨て、そのサイズのバッファを確保する DXE コアに渡す。その後 BrotliDecompressInternal がそのバッファへ無制限に展開する — Brotli ストリームが終わるまで実行し続け、確保領域を超えて書き込む。
結果: DXE フェーズにおいて、Secure Boot の検証が完了する前にヒープオーバーフロー(書き込みプリミティブ)が発生する。ファームウェアイメージ(フラッシュ、カプセル、または ESP)を制御する攻撃者は、隣接するプールオブジェクト — 関数ポインタ、セキュリティフラグ、プロトコル構造体 — を任意のバイト列で上書きできる。
これは CVE-2021-28211 の見落とされていた Brotli 版の兄弟である(LZMA は 2021 年に >MAX_UINT32 ガードを得たが、Brotli は得ていない)。バリアントの一括調査により、Brotli が切り捨てガードと出力境界の両方を欠く EDK2 の唯一の展開器であることが確認された。
| ファイル | 役割 |
|---|---|
BrotliDecompress.c:238 | UINT64 の展開後サイズを UINT32 にキャスト — MAX_UINT32 ガードなし |
BrotliDecompress.c:118–157 | 境界チェックなしで宛先バッファへ展開 |
GuidedSectionExtraction.c | GetInfo を呼んでから Decompress を呼ぶ — 宣言されたサイズを信頼 |
CoreSectionExtraction.c:1597 | 宣言されたサイズで宛先バッファを確保 |
すべて tianocore/edk2 の MdeModulePkg/Library/BrotliCustomDecompressLib 内。
| 成果物 | 説明 |
|---|---|
harness/edk2_brotli_overflow_poc.c | ASAN 概念実証: 4096 バイトのストリームを 64 バイトのバッファへ |
harness/asan_output.txt | ASAN 出力: BrotliDecompressInternal → memcpy で heap-buffer-overflow |
harness/edk2_brotli_overflow_demo.c | エンドツーエンドデモ: 隣接するプールオブジェクトの制御された破壊 |
harness/demo_output.txt | デモ出力: 関数ポインタの乗っ取り、Secure Boot の無効化 |
harness/lvfs_brotli_scan.py | LVFS ファームウェアスキャナ(影響範囲の測定) |
harness/lvfs_scan_output.txt | スキャン結果: 200 件中 0 件のファームウェアイメージが Brotli を使用 |
evidence/ | HEAD 時点の脆弱な EDK2 ソースファイルのコピー |
FINDINGS.md | 完全な報告書: 行参照、先行技術調査、バリアント一括調査、LZMA 監査 |
限定的。 2 つの独立した調査により、実際に Brotli GUIDed セクションを使用するプラットフォームはゼロであることが判明した:
BrotliCustomDecompressLib を参照するプラットフォーム DSC ファイルは 0 件。ヒットはすべて MdeModulePkg.dsc 自身。脆弱なコードは EDK2 ツリーに含まれているが、現時点ではデッドコードである — 2017 年に追加され、IBV や OEM には採用されていない。バグは実在し、原理的には悪用可能であり、Brotli の採用が増えれば直ちに到達可能となる。
LZMA と Tiano が既に備えているものに合わせた 2 つの変更:
MAX_UINT32 ガードを追加する(BrotliUefiDecompressGetInfo、BrotliDecompress.c:238): LzmaDecompress.c:149 が CVE-2021-28211 以降行っているように、展開後サイズが MAX_UINT32 を超える場合は拒否する。BrotliDecompressInternal): 書き込み済みバイト数を追跡し、Tiano 展開器が mOrigSize で行っているように DestinationSize で停止する。libbrotli と GCC を用いて Linux 上で PoC をビルドする:
# 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
2026-10-26 に完全な公開開示を行った。TianoCore には協調的開示期間は設けられなかった。 影響範囲が狭いこと(出荷済みファームウェアへの影響はゼロ)と、類似の LZMA バグが 2021 年から公開されているという事実が、この判断の根拠となった。