lzma: unbounded dictionary-size allocation is a memory DoS (zipfile, tarfile, lzma.decompress)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 35.9k
- PR merge metrics
- PR metrics pending
Description
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with parse_filter_spec_lzma() and LZMADecompressor, then review the zipfile and tarfile paths described in the issue. Use the linked OSS-Fuzz reproducers to verify that oversized dictionaries no longer cause unbounded allocation, while normal LZMA streams and explicit memlimit behavior remain intact.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100