Skip to content

fix(zstd): return decode error instead of panicking on corrupt view lengths#8843

Open
mvanhorn wants to merge 1 commit into
vortex-data:developfrom
mvanhorn:fix/zstd-decode-oob-panic
Open

fix(zstd): return decode error instead of panicking on corrupt view lengths#8843
mvanhorn wants to merge 1 commit into
vortex-data:developfrom
mvanhorn:fix/zstd-decode-oob-panic

Conversation

@mvanhorn

Copy link
Copy Markdown

Summary

reconstruct_views decodes a [u32-LE length][value bytes] stream from ZSTD-decompressed (untrusted) data and used the length prefix as a slice bound without validation, so a corrupt or fuzzed length triggered an out-of-bounds slice panic (range end index ... out of range for slice of length ...). This makes reconstruct_views return VortexResult and bounds-checks the untrusted reads, returning a decode error instead of panicking.

Rationale for this change

This is a fuzzer-reported crash (#8822): decoding attacker-controllable ZSTD array data could panic a worker thread instead of surfacing a recoverable decode error. Decoding untrusted input should never panic; it should return an error the caller can handle. The panic reproduces on develop with a length prefix that exceeds the remaining buffer.

What changes are included in this PR?

  • encodings/zstd/src/array.rs: reconstruct_views now returns VortexResult<(Vec<ByteBuffer>, Buffer<BinaryView>)>. Both untrusted reads (the view-length prefix and the value slice) are bounds-checked (with checked_add to avoid usize overflow) and return a decode error instead of panicking. The two in-crate callers propagate the error with ?.
  • vortex-cuda/src/kernel/encodings/zstd.rs: the CUDA decode caller propagates the new error with ?.
  • Added regression tests covering an oversized length prefix and a truncated length prefix; both now return Err rather than panicking. The existing reconstruct_views tests are unchanged in behavior.

What APIs are changed? Are there any user-facing changes?

The pub fn reconstruct_views in vortex-zstd changes its return type from (Vec<ByteBuffer>, Buffer<BinaryView>) to VortexResult<(Vec<ByteBuffer>, Buffer<BinaryView>)>. Decoding a corrupt ZSTD array now yields a VortexError instead of panicking. There is no behavior change for well-formed input.

AI was used for assistance.

…engths

reconstruct_views read a u32 view-length prefix from ZSTD-decompressed
(untrusted) data and used it as a slice bound without validation. A corrupt
or fuzzed length produced an out-of-bounds slice panic ("range end index
... out of range for slice of length ...") in reconstruct_views.

Make reconstruct_views return VortexResult: bounds-check both the length
prefix read and the value slice (with a checked_add to avoid usize
overflow), returning a decode error instead of panicking. Both zstd
callers and the vortex-cuda caller propagate the error.

Closes vortex-data#8822
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.

ZSTD decode OOB slice panic

1 participant