Skip to content

Commit a73741b

Browse files
authored
RUST-713 Fix underflow on BSON array and binary deserialization (#244)
1 parent 404d404 commit a73741b

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

src/de/mod.rs

+19
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,17 @@ fn deserialize_array<R: Read + ?Sized>(reader: &mut R, utf8_lossy: bool) -> Resu
176176
let mut arr = Array::new();
177177
let length = read_i32(reader)?;
178178

179+
if !(MIN_BSON_DOCUMENT_SIZE..=MAX_BSON_SIZE).contains(&length) {
180+
return Err(Error::invalid_length(
181+
length as usize,
182+
&format!(
183+
"array length must be between {} and {}",
184+
MIN_BSON_DOCUMENT_SIZE, MAX_BSON_SIZE
185+
)
186+
.as_str(),
187+
));
188+
}
189+
179190
ensure_read_exactly(
180191
reader,
181192
(length as usize) - 4,
@@ -224,6 +235,14 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
224235
if let BinarySubtype::BinaryOld = subtype {
225236
let data_len = read_i32(reader)?;
226237

238+
if !(0..=(MAX_BSON_SIZE - 4)).contains(&data_len) {
239+
return Err(Error::invalid_length(
240+
data_len as usize,
241+
&format!("0x02 length must be between 0 and {}", MAX_BSON_SIZE - 4)
242+
.as_str(),
243+
));
244+
}
245+
227246
if data_len + 4 != len {
228247
return Err(Error::invalid_length(
229248
data_len as usize,

src/tests/modules/serializer_deserializer.rs

+22
Original file line numberDiff line numberDiff line change
@@ -540,3 +540,25 @@ fn test_serialize_deserialize_document() {
540540
let bad_point: Result<Point, crate::de::Error> = from_document(bad_point);
541541
assert!(bad_point.is_err());
542542
}
543+
544+
/// [RUST-713](https://jira.mongodb.org/browse/RUST-713)
545+
#[test]
546+
fn test_deserialize_invalid_array_length() {
547+
let _guard = LOCK.run_concurrently();
548+
let buffer = b"\n\x00\x00\x00\x04\x00\x00\x00\x00\x00";
549+
Document::from_reader(&mut std::io::Cursor::new(buffer))
550+
.expect_err("expected deserialization to fail");
551+
}
552+
553+
/// [RUST-713](https://jira.mongodb.org/browse/RUST-713)
554+
#[test]
555+
fn test_deserialize_invalid_old_binary_length() {
556+
let _guard = LOCK.run_concurrently();
557+
let buffer = b"\x0F\x00\x00\x00\x05\x00\x00\x00\x00\x00\x02\xFC\xFF\xFF\xFF";
558+
Document::from_reader(&mut std::io::Cursor::new(buffer))
559+
.expect_err("expected deserialization to fail");
560+
561+
let buffer = b".\x00\x00\x00\x05\x01\x00\x00\x00\x00\x00\x02\xfc\xff\xff\xff\xff\xff\xff\xff\x00\x00*\x00h\x0e\x10++\x00h\x0e++\x00\x00\t\x00\x00\x00\x00\x00*\x0e\x10++";
562+
Document::from_reader(&mut std::io::Cursor::new(buffer))
563+
.expect_err("expected deserialization to fail");
564+
}

0 commit comments

Comments
 (0)