Skip to content

ComHandler: backport 7-Zip 25.00/26.00 item.Size sanity check (CVE-2025-53817)#258

Open
tonghuaroot wants to merge 1 commit into
p7zip-project:masterfrom
tonghuaroot:fix/com-handler-itemsize-cve-2025-53817
Open

ComHandler: backport 7-Zip 25.00/26.00 item.Size sanity check (CVE-2025-53817)#258
tonghuaroot wants to merge 1 commit into
p7zip-project:masterfrom
tonghuaroot:fix/com-handler-itemsize-cve-2025-53817

Conversation

@tonghuaroot

@tonghuaroot tonghuaroot commented May 27, 2026

Copy link
Copy Markdown

Backports the directory-entry size guard landed in upstream 7-Zip 25.00 (further tightened in 26.00) to address CVE-2025-53817 (GHSL-2025-059) in the Compound Document (CFB / MSI / DOC / XLS / PPT) handler.

What changed upstream

7-Zip 25.00 added a single guard right after item.Parse() in the directory-entry loop of CDatabase::Open(), rejecting Compound archive entries whose declared stream size cannot fit the sector table. 26.00 tightened the check to:

if ((UInt32)(item.Size >> 32) >= sectSize) // FAT size is limited by (1 << 32) items.
  return S_FALSE;

That is the form NanaZip and git-for-windows' 7-Zip carry today.

Without this check, the Compound handler can later be steered into a null-pointer dereference during extraction by a crafted Compound Document, causing a denial of service in any tool that calls into the CFB handler.

p7zip's CDatabase::Open() at CPP/7zip/Archive/ComHandler.cpp:515 runs the same parse without any size validation and is reachable from the same crafted document. The surrounding identifiers (sectSize, item, Items.Add(item)) match upstream exactly, so the backport is mechanical.

Patch

       for (UInt32 i = 0; i < sectSize; i += 128)
       {
         CItem item;
         item.Parse(sect + i, mode64bit);
+        // we use (item.Size) check here.
+        // so we don't need additional overflow checks for (item.Size +) in another code
+        if ((UInt32)(item.Size >> 32) >= sectSize) // it's because FAT size is limited by (1 << 32) items.
+          return S_FALSE;
         Items.Add(item);
       }

p7zip has a precedent of backporting CVE fixes one at a time (e.g. #239 for CVE-2021-3520, #254 for the NTFS ClusterSizeLog bound).

…25-53817)

Upstream 7-Zip 25.00 added a single guard right after Parse() in the
directory-entry loop of CDatabase::Open() to reject Compound (CFB)
archive entries whose declared stream size cannot possibly fit the
sector table. 26.00 tightened the check to `(UInt32)(item.Size >> 32)
>= sectSize`, which is byte-for-byte what NanaZip and git-for-windows'
7-Zip carry. Without this check, the Compound handler can be driven
into a null-pointer dereference during extraction by a crafted
Compound Document.

p7zip's CDatabase::Open() loop at CPP/7zip/Archive/ComHandler.cpp:515
runs the same parse without any size validation and is therefore
reachable from the same crafted document.

The backport drops the upstream 26.00 line in unchanged:

    if ((UInt32)(item.Size >> 32) >= sectSize) // FAT size is limited by (1 << 32) items.
      return S_FALSE;

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