-
Notifications
You must be signed in to change notification settings - Fork 214
Description
Right now, the ByteReader::read_many
function looks like this:
winterfell/utils/core/src/serde/byte_reader.rs
Lines 189 to 199 in 5a57503
fn read_many<D>(&mut self, num_elements: usize) -> Result<Vec<D>, DeserializationError> | |
where | |
Self: Sized, | |
D: Deserializable, | |
{ | |
let mut result = Vec::with_capacity(num_elements); | |
for _ in 0..num_elements { | |
let element = D::read_from(self)?; | |
result.push(element) | |
} | |
Ok(result) |
If num_elements
exceeds the system's available memory capacity, Vec::with_capacity
panics. Deserialization input can generally not be trusted, and in theory it would be the responsibility of the caller of read_many
to validate num_elements
or impose limits. However, that is generally not done and is likely to be forgotten, at least in some places. So if a malicious input sets the value of num_elements
that is passed to a number that exceeds the available capacity, the attacker can provoke a panic. It would probably be best if we removed the potential for a panic and errored instead if the capacity is too large, e.g.:
let mut result = Vec::new();
result
.try_reserve(num_elements)
.map_err(|err| DeserializationError::InvalidValue(err.to_string()))?;
(Note that Vec::try_with_capacity
exists, but is not stable at this time).
Alternatively, I'd prefer adding a new error variant to DeserializationError
directly for this case.