Skip to content

NtfsHandler: backport 7-Zip 26.01 ClusterSizeLog bound (CVE-2026-48095) - #254

Open
tonghuaroot wants to merge 1 commit into
p7zip-project:masterfrom
tonghuaroot:fix/ntfs-cluster-size-bounds-backport-26.01
Open

tonghuaroot wants to merge 1 commit into
p7zip-project:masterfrom
tonghuaroot:fix/ntfs-cluster-size-bounds-backport-26.01

Conversation

@tonghuaroot

@tonghuaroot tonghuaroot commented May 27, 2026

Copy link
Copy Markdown

Backports the one-line bounds tightening landed in upstream 7-Zip 26.01 (released 2026-04-27) to address CVE-2026-48095 (GHSL-2026-140).

What changed upstream

7-Zip 26.01 changed CPP/7zip/Archive/NtfsHandler.cpp from:

    if (ClusterSizeLog > 30)
      return false;

to:

    if (ClusterSizeLog > 21)
      return false;

The reason is that GetCuSize() further down in the same file computes:

  UInt32 GetCuSize() const { return (UInt32)1 << (BlockSizeLog + CompressionUnit); }

With the old cap of 30, an NTFS image specifying ClusterSizeLog = 28..30 plus CompressionUnit = 4 makes the shift exponent reach 32, which is undefined behaviour for a 32-bit shift in C/C++. On x86/x64 the count is masked to the low 5 bits, so GetCuSize() returns 1 and the compression-unit buffer is allocated as 1 byte before the subsequent read writes up to 256 MiB into it. The new cap of 21 leaves room for the maximum CompressionUnit of 4 so the exponent stays under 32.

p7zip's NtfsHandler.cpp at line 123 still has the original > 30 cap, so the same heap overflow is reachable from a crafted NTFS image when p7zip extracts it.

Patch

Single line, byte-for-byte the same as upstream 26.01:

-    if (ClusterSizeLog > 30)
+    if (ClusterSizeLog > 21)

p7zip has a precedent of backporting CVE fixes one at a time (e.g. #239 for CVE-2021-3520).

Upstream 7-Zip 26.01 tightened the ClusterSizeLog cap in the NTFS
boot-sector parser from > 30 to > 21 so the shift exponent in
GetCuSize() (BlockSizeLog + CompressionUnit, max +4) cannot reach
32 on a malicious image. With the prior > 30 bound the 32-bit
shift was undefined behaviour and reduced the compression-unit
buffer to 1 byte before a 256 MiB write followed. Disclosed as
CVE-2026-48095.

Signed-off-by: tonghuaroot <tonghuaroot@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant