lzma: unbounded dictionary-size allocation is a memory DoS (zipfile, tarfile, lzma.decompress)
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 77.2k
- Fork
- 35.9k
- Metriche di merge delle PR
- Metriche PR in attesa
Descrizione
Bug: LZMA decompression accepts an attacker-controlled dictionary size with no bound, and liblzma allocates the full dictionary up front when a decompressor is created. A few bytes of input can therefore force a multi-gigabyte allocation (memory denial of service).
Attack surfaces (both reported by OSS-Fuzz, both public):
zipfilewith an LZMA-compressed member: the 5-byte LZMA properties header in the member data declares the dictionary. A 1088-byte zip whose member declares a ~2 GiB dictionary OOMs the process. https://issues.oss-fuzz.com/issues/495472861tarfile's compression-detection loop: a 13-byte input whose first byte is a valid LZMA-alone properties byte (0x66) and whose remaining bytes encode a ~4 GiB dictionary is tried as LZMA; liblzma allocates 4 GiB before failing. https://issues.oss-fuzz.com/issues/482161128
Also reachable directly: lzma.decompress() / LZMADecompressor(format=FORMAT_AUTO) on untrusted bytes, and LZMADecompressor(FORMAT_RAW, filters=[{"dict_size": ...}]).
Root cause: two gaps:
parse_filter_spec_lzma()accepts anydict_size(up to UINT32_MAX) for raw LZMA1/LZMA2 filter chains; liblzma allocates that dictionary at decompressor creation.LZMADecompressordefaultsmemlimittoUINT64_MAX, so the FORMAT_ALONE/FORMAT_AUTO paths (where the header is parsed inside liblzma) are also unbounded.
Proposed fix (PR to follow):
- Reject
dict_size > LZMA_DICT_SIZE_MAX(1.5 GiB, liblzma's own maximum) inparse_filter_spec_lzma()withLZMAError. - Default the decompressor
memlimittoLZMA_DICT_SIZE_MAXinstead ofUINT64_MAX(callers may still pass an explicitmemlimit).
No legitimate streams are affected: liblzma presets cap at 64 MiB dictionaries, and 1.5 GiB is liblzma's own maximum supported dictionary size.
Reported by OSS-Fuzz (ClusterFuzz). Reproducers attached to the issues above.
Linked PRs
- gh-155650
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia con parse_filter_spec_lzma() e LZMADecompressor, quindi esamina i percorsi zipfile e tarfile descritti nell’issue. Usa i riproduttori OSS-Fuzz collegati per verificare che i dizionari sovradimensionati non causino più un’allocazione non vincolata, mentre i normali stream LZMA e il comportamento esplicito di memlimit rimangono invariati.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- security
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 35/100