TL;DR
- GHSL-2026-140 documents CVE-2026-48095: a heap buffer overflow in 7-Zip’s NTFS archive path, reachable on x86 and x64, with a documented path to vtable hijack after a 256 MB write into a 1-byte allocation when the crafted image trips undefined behavior in
GetCuSize(). - 7-Zip 26.01 shipped with a fix on 2026-04-27 per the advisory timeline; anything through 26.00 is in the affected range the write-up calls out.
- The same analysis explains why file extension is a weak control: the NTFS handler can still win signature-based probing even when the filename ends in
.7z,.zip,.rar, or no extension, because the"NTFS "marker sits early in the file.
What broke, in one pass
The failure is not “big cluster numbers look scary” as a headline. The advisory pins a C++ shift UB in CInStream::GetCuSize() inside NtfsHandler.cpp (the write-up cites line 687): the code sizes a compression-unit buffer with (UInt32)1 << (BlockSizeLog + CompressionUnit). For attacker-chosen field combinations called out in the report, the exponent hits 32, which is undefined behavior for a 32-bit shift. On common hardware the expression collapses in a way that under-allocates _inBuf, and the next read tries to land up to 256 MB of attacker-controlled compressed data into that tiny buffer.
From there the text is explicit about how LZNT1 plumbing uses _inBuf and _outBuf, why x64 can still reach the overflow when an enormous _outBuf allocation succeeds on well-equipped machines, and how debugger layout on a release build put the CInStream vtable within overwrite range early in the loop. That is the kind of compile-path detail security teams actually need when they are deciding whether “archive malware” is a desktop hygiene problem or an RCE class incident for managed endpoints.
Why “we do not mount .ntfs images” is the wrong mental model
Operations teams sometimes bucket risk by extension and MIME policy. The GHSL note argues against that comfort: 7-Zip probes formats by signature, and the NTFS handler matches the "NTFS " signature at a fixed early offset. If the extension-matched format fails to parse, other handlers still get a turn. A deliberately malformed image can therefore ride in under a boring name while still reaching the vulnerable NTFS path during open or extract.
Pair that with CI caches, artifact unzip steps, and helpdesk “double-click the attachment” workflows, and the trust boundary stops being “disk images the OS would mount” and becomes “anything a parser touches.”
What to do
Upgrade to 26.01 or newer on every fleet line where 7-Zip is installed, including bundled copies inside third-party installers and golden images. The coordinated timeline in the advisory says the fix landed in 26.01 on 2026-04-27; treat older builds as carrying the flawed GetCuSize() logic back to when NTFS compressed stream support first shipped.
If you cannot move versions immediately, shrink exposure the way you would for any archive parser bug: stop letting automation open untrusted archives, isolate extraction jobs, and assume extension allowlists do not keep this class of defect out.
For verification-oriented teams, the advisory ships a Python PoC generator (gen_ntfs_sparse.py) that materializes a sparse NTFS image hitting the bad combination, plus UBSan traces that show the shift failure and the subsequent bad vptr call. That is enough to turn “vendor scored it high” into “we reproduced the sanitizer trip on our toolchain.”
Sources
- GHSL-2026-140: Heap Buffer Write Overflow in 7-Zip (GitHub Security Lab coordinated disclosure, technical analysis, PoC generator, UBSan traces, CVSS vector, CWE references, credit to Jaroslav Lobačevski)
- CVE-2026-48095 record (MITRE CVE Program dictionary entry for the assigned identifier)