-
Notifications
You must be signed in to change notification settings - Fork 223
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.