Bug Description
The XOR-float vector codec at src/codec.rs:582-589 performs leading + trailing + width as an unchecked u64 add before validating that the sum is <= 64. In release builds (no overflow checks), the sum wraps around u64::MAX and bypasses the guard. Subsequently, payload << trailing can shift by 64 or more, which is undefined behavior in Rust for the shift operator (debug panic, release-mode UB).
Steps to Reproduce
- Encode a typed-vector with
f64 element type and codec=XorFloat.
- For one element, set
leading = u64::MAX - 32, trailing = 33, width = 0. The sum wraps to 1 and passes the <= 64 check.
- Decode →
payload << trailing shifts by 33 (currently safe in this exact example, but the bypassed guard lets the attacker pick trailing >= 64 freely with neighboring values that wrap).
Expected Behavior
Use leading.checked_add(trailing).and_then(|x| x.checked_add(width)), or compare each component against 64 individually, before any shift. Reject the value with InvalidData on any failure.
Actual Behavior
leading + trailing + width is computed without overflow checking; the guard is bypassed; the subsequent shift is undefined.
Environment
- Crate:
recurram, XOR-float codec, src/codec.rs:582-589
Additional Context
Severity: High. Same class of bug exists in recurram-zig (decodeXorFloat, tracked as twilic/twilic-zig#5).
Bug Description
The XOR-float vector codec at
src/codec.rs:582-589performsleading + trailing + widthas an uncheckedu64add before validating that the sum is<= 64. In release builds (no overflow checks), the sum wraps aroundu64::MAXand bypasses the guard. Subsequently,payload << trailingcan shift by 64 or more, which is undefined behavior in Rust for the shift operator (debug panic, release-mode UB).Steps to Reproduce
f64element type and codec=XorFloat.leading = u64::MAX - 32,trailing = 33,width = 0. The sum wraps to1and passes the<= 64check.payload << trailingshifts by 33 (currently safe in this exact example, but the bypassed guard lets the attacker picktrailing >= 64freely with neighboring values that wrap).Expected Behavior
Use
leading.checked_add(trailing).and_then(|x| x.checked_add(width)), or compare each component against 64 individually, before any shift. Reject the value withInvalidDataon any failure.Actual Behavior
leading + trailing + widthis computed without overflow checking; the guard is bypassed; the subsequent shift is undefined.Environment
recurram, XOR-float codec,src/codec.rs:582-589Additional Context
Severity: High. Same class of bug exists in
recurram-zig(decodeXorFloat, tracked as twilic/twilic-zig#5).