Skip to content

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

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

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

Conversation

@kevinjzhang

@kevinjzhang kevinjzhang commented Nov 12, 2026 •

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.

@meta-cla meta-cla Bot added the CLA Signed label Nov 12, 2026
@kevinjzhang
kevinjzhang force-pushed the fix/4675-zstdmt-32bit-overflow branch 2 times, most recently from 9e9e526 to b0da217 Compare November 12, 2026 22:36
@kevinjzhang kevinjzhang changed the title Fix 32-bit zstdmt round buffer size overflow Fix 32-bit zstdmt round buffer size overflow (memory OOB) Nov 12, 2026
@kevinjzhang
kevinjzhang force-pushed the fix/4675-zstdmt-32bit-overflow branch from b0da217 to 8e25309 Compare November 12, 2026 23:27
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.
@kevinjzhang
kevinjzhang force-pushed the fix/4675-zstdmt-32bit-overflow branch from 8e25309 to 759a042 Compare November 12, 2026 23:52
@kevinjzhang
kevinjzhang deleted the fix/4675-zstdmt-32bit-overflow branch November 12, 2026 23:55
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