Right now, the ByteReader::read_many function looks like this:
|
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.
Right now, the
ByteReader::read_manyfunction looks like this:winterfell/utils/core/src/serde/byte_reader.rs
Lines 189 to 199 in 5a57503
If
num_elementsexceeds the system's available memory capacity,Vec::with_capacitypanics. Deserialization input can generally not be trusted, and in theory it would be the responsibility of the caller ofread_manyto validatenum_elementsor 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 ofnum_elementsthat 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.:(Note that
Vec::try_with_capacityexists, but is not stable at this time).Alternatively, I'd prefer adding a new error variant to
DeserializationErrordirectly for this case.