Bug Description
src/v2.rs:443-446 calls state.shapes.resize(shape_id + 1, …) with shape_id taken directly from the wire (a varuint). This produces three failure modes from a single malformed message:
- For moderate
shape_id values (e.g., 2^30), the resize requests (shape_id + 1) * sizeof(ShapeEntry) bytes and OOMs the process.
- For
shape_id == u64::MAX, shape_id + 1 wraps in release builds (with overflow-checks disabled) to 0, silently truncating the shape table — a session-state corruption primitive.
- In debug builds, the wrap is a checked panic and crashes the process.
Steps to Reproduce
- Construct a v2 message that registers a shape with
shape_id = 0x7FFF_FFFF_FFFF_FFFF (or any large value).
- Call
recurram::decode on it.
- Observe OOM (large but finite
shape_id) or shape-table corruption (u64::MAX).
Expected Behavior
shape_id should be validated against a small configurable cap (e.g., MAX_SHAPES = 65_536) before any resize, or the shape table should be a sparse HashMap keyed by shape_id rather than a dense Vec.
Actual Behavior
state.shapes.resize(shape_id + 1, …) is called with attacker-controlled shape_id.
Environment
- Crate:
recurram, v2 decoder
Additional Context
Severity: Critical — unauthenticated remote OOM / session-state corruption.
// state.shapes.resize(shape_id + 1, ...)
(Replace with exact lines after review.)
Bug Description
src/v2.rs:443-446callsstate.shapes.resize(shape_id + 1, …)withshape_idtaken directly from the wire (a varuint). This produces three failure modes from a single malformed message:shape_idvalues (e.g.,2^30), the resize requests(shape_id + 1) * sizeof(ShapeEntry)bytes and OOMs the process.shape_id == u64::MAX,shape_id + 1wraps in release builds (with overflow-checks disabled) to0, silently truncating the shape table — a session-state corruption primitive.Steps to Reproduce
shape_id = 0x7FFF_FFFF_FFFF_FFFF(or any large value).recurram::decodeon it.shape_id) or shape-table corruption (u64::MAX).Expected Behavior
shape_idshould be validated against a small configurable cap (e.g.,MAX_SHAPES = 65_536) before any resize, or the shape table should be a sparseHashMapkeyed byshape_idrather than a denseVec.Actual Behavior
state.shapes.resize(shape_id + 1, …)is called with attacker-controlledshape_id.Environment
recurram, v2 decoderAdditional Context
Severity: Critical — unauthenticated remote OOM / session-state corruption.
(Replace with exact lines after review.)