Skip to content

codec: scale a decoded element count in 64-bit so 32-bit targets agree - #384

Closed
EnRaiha wants to merge 1 commit into
NodeDB-Lab:mainfrom
EnRaiha:fix/codec-32bit-element-count
Closed

EnRaiha wants to merge 1 commit into
NodeDB-Lab:mainfrom
EnRaiha:fix/codec-32bit-element-count

Conversation

@EnRaiha

@EnRaiha EnRaiha commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

codec: scale a decoded element count in 64-bit so 32-bit targets agree

Why

An element count read from a frame is multiplied by its element size before the
64 MiB ceiling is compared. On a 32-bit target that multiplication overflows
usize for counts the 64-bit path rejects cleanly, so the same hostile frame
came back as Corrupt there and ResourceLimit here — and the delta decoder's
own test asserts ResourceLimit, so the suite aborted on a 32-bit target
instead of reporting a test failure.

What changed

checked_capacity does the scaling in 64-bit arithmetic and reports the
resource limit whenever the product exceeds the ceiling, on every target.
validate_value_count in delta and double-delta and the FastLanes header parse
route through it rather than repeating the multiplication.

The requested field stays a byte count: the rejecting branch is only reachable
above the 64 MiB ceiling and below the type's maximum, so the value is always
representable. On a 64-bit target no reachable input changes — wire counts cap
at u32::MAX, whose byte size both the old and the new code reject as
ResourceLimit.

The classification change is deliberate and was already asserted by the tests:
checked_capacity_rejects_usize_overflow was replaced by two stricter cases
covering usize::MAX and u32::MAX at element size 8.

Steps to test

cargo test -p nodedb-codec                      # 264 passed
# the target that has the bug:
CARGO_TARGET_WASM32_WASIP1_RUNNER="wasmtime -W max-wasm-stack=33554432 --dir=." \
  cargo test --profile ci --target wasm32-wasip1 -p nodedb-codec \
  rejects_overflowed_noncanonical_and_huge_input_before_allocation \
  hostile_counts_and_block_shapes_fail_before_allocation_or_looping

Exclusions, stated

The eight zstd encoder tests in this crate also fail on wasm32-wasip1,
because that target has no zstd encoder by design (compress_native returns
CompressFailed; it decodes with ruzstd and encodes with LZ4). That is a
different defect in a different test group and is not part of this change.

An element count read from a frame is multiplied by its element size before the
64 MiB ceiling is compared. On a 32-bit target that multiplication overflows
`usize` for counts the 64-bit path rejects cleanly, so the same hostile frame
came back as `Corrupt` there and `ResourceLimit` here — and the delta decoder's
own test asserts `ResourceLimit`, so the suite aborted on a 32-bit target.

`checked_capacity` now does the scaling in 64-bit arithmetic and reports the
resource limit whenever the product exceeds the ceiling, on every target. The
`requested` field stays a byte count: the branch is only reachable above 64 MiB
and below the type's maximum, so the value is always representable.

`validate_value_count` in delta and double-delta and the FastLanes header parse
route through it rather than repeating the multiplication. On a 64-bit target no
reachable input changes: wire counts cap at `u32::MAX`, whose byte size is
rejected as `ResourceLimit` by both the old and the new code.
Copilot AI lite review requested due to automatic review settings September 27, 2026 11:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@EnRaiha

EnRaiha commented Sep 28, 2026

Copy link
Copy Markdown
Contributor Author

Reframing: hostile-input hardening on 32-bit usize, not wasm work. NodeDB does not support wasm; this stands or falls on supported targets. Leaving open for the maintainer's call.

@EnRaiha EnRaiha closed this Sep 28, 2026
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.

2 participants