Skip to content

Fix 32-bit zstdmt round buffer size overflow (memory OOB) - #4948

Open
kevinjzhang wants to merge 1 commit into
meta:devfrom
kevinjzhang:fix-zstdmt-32bit-overflow
Open

kevinjzhang wants to merge 1 commit into
meta:devfrom
kevinjzhang:fix-zstdmt-32bit-overflow

Conversation

@kevinjzhang

Copy link
Copy Markdown
Contributor

On 32-bit builds, ZSTDMT_initCStream_internal() computed the round buffer size in size_t. The total can reach or exceed 4 GiB and wrap.

Instead, compute the slack/section totals in 64 bits and reject the configuration with memory_allocation when the total exceeds SIZE_MAX, before allocating.

Add a 32-bit-only fuzzer regression test that expects both cases to fail cleanly with memory_allocation, which prior to the fix crashes.

Test plan: the new fuzzer test (oversized round buffer must fail cleanly on 32-bit) is a no-op on 64-bit builds; fuzzer passes there.

On 32-bit builds, ZSTDMT_initCStream_internal() computed the round
buffer size in size_t. The total can reach or exceed 4 GiB and wrap:

- windowLog 30 with btultra2 and LDM disabled makes the overlap
  1 GiB, which raises the job size to 1 GiB after the job size cap is
  applied. The 4 GiB total wraps to 0, the allocation is skipped, and
  the first streaming copy writes through a NULL buffer.
- Many workers with large jobs wrap to a smaller non-zero size, so
  the buffer is allocated but is too small for the configuration.

Compute the slack/section totals in 64 bits and reject the
configuration with memory_allocation when the total exceeds SIZE_MAX,
before allocating.

Add a 32-bit-only fuzzer regression test that expects both cases to
fail cleanly with memory_allocation.
@meta-cla meta-cla Bot added the CLA Signed label Nov 12, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant