Skip to content

SquashfsHandler: backport 7-Zip 23.00 LzoDecode UInt32 widening (CVE-2023-40481) - #257

Open
tonghuaroot wants to merge 1 commit into
p7zip-project:masterfrom
tonghuaroot:fix/squashfs-lzo-oob-cve-2023-40481
Open

tonghuaroot wants to merge 1 commit into
p7zip-project:masterfrom
tonghuaroot:fix/squashfs-lzo-oob-cve-2023-40481

Conversation

@tonghuaroot

@tonghuaroot tonghuaroot commented May 27, 2026

Copy link
Copy Markdown

Backports the one-line UInt32 widening landed in upstream 7-Zip 23.00 to address CVE-2023-40481 (ZDI-23-1164) in the SquashFS handler's LZO decoder.

What changed upstream

7-Zip 23.00 changed CPP/7zip/Archive/SquashfsHandler.cpp inside LzoDecode() from:

back = (b >> 2) + (*src++ << 2);

to:

back = (b >> 2) + ((UInt32)*src++ << 2);

Without the cast, *src++ is a Byte promoted to int, and << 2 on the resulting int is performed in signed arithmetic. Together with the subsequent additions, this can compute a back offset that overflows past the destination buffer, giving an out-of-bounds write while extracting a crafted SquashFS image.

p7zip's LzoDecode() carries the pre-fix expression at line 1047 and inherits the same flaw. The next branch in the same function (mode == 4 path) already uses ((UInt32)src[1] << 6) in p7zip, so the surrounding code style is consistent with the cast.

Patch

Single-line widening, byte-for-byte the same as upstream 23.00:

-      back = (b >> 2) + (*src++ << 2);
+      back = (b >> 2) + ((UInt32)*src++ << 2);

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).

…2023-40481)

Upstream 7-Zip 23.00 changed the `back` offset computation inside
LzoDecode() so that the source byte is widened to UInt32 before the
shift, preventing a signed-overflow which can cause an out-of-bounds
write while extracting a crafted SquashFS image. p7zip carries the
pre-fix line and is therefore reachable from the same crafted image.

The change is a single-line widening cast equal to upstream 23.00:

    -      back = (b >> 2) + (*src++ << 2);
    +      back = (b >> 2) + ((UInt32)*src++ << 2);

The next branch in the same function (mode == 4 path) was already
using `((UInt32)src[1] << 6)` in p7zip, so the surrounding code style
matches.

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