From f696f8cacd0f81ccd13048e5cc582a569f24ae99 Mon Sep 17 00:00:00 2001 From: gperinazzo Date: Wed, 24 Mar 2021 13:53:37 -0300 Subject: [PATCH] RUST-713 Fix underflow on BSON array and binary deserialization (#244) --- src/de/mod.rs | 19 +++++++++++++++++ src/tests/modules/serializer_deserializer.rs | 22 ++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/de/mod.rs b/src/de/mod.rs index 0fe3a9aa..401dc432 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -176,6 +176,17 @@ fn deserialize_array(reader: &mut R, utf8_lossy: bool) -> Resu let mut arr = Array::new(); let length = read_i32(reader)?; + if !(MIN_BSON_DOCUMENT_SIZE..=MAX_BSON_SIZE).contains(&length) { + return Err(Error::invalid_length( + length as usize, + &format!( + "array length must be between {} and {}", + MIN_BSON_DOCUMENT_SIZE, MAX_BSON_SIZE + ) + .as_str(), + )); + } + ensure_read_exactly( reader, (length as usize) - 4, @@ -224,6 +235,14 @@ pub(crate) fn deserialize_bson_kvp( if let BinarySubtype::BinaryOld = subtype { let data_len = read_i32(reader)?; + if !(0..=(MAX_BSON_SIZE - 4)).contains(&data_len) { + return Err(Error::invalid_length( + data_len as usize, + &format!("0x02 length must be between 0 and {}", MAX_BSON_SIZE - 4) + .as_str(), + )); + } + if data_len + 4 != len { return Err(Error::invalid_length( data_len as usize, diff --git a/src/tests/modules/serializer_deserializer.rs b/src/tests/modules/serializer_deserializer.rs index cbc87fcd..33e6f9c8 100644 --- a/src/tests/modules/serializer_deserializer.rs +++ b/src/tests/modules/serializer_deserializer.rs @@ -540,3 +540,25 @@ fn test_serialize_deserialize_document() { let bad_point: Result = from_document(bad_point); assert!(bad_point.is_err()); } + +/// [RUST-713](https://jira.mongodb.org/browse/RUST-713) +#[test] +fn test_deserialize_invalid_array_length() { + let _guard = LOCK.run_concurrently(); + let buffer = b"\n\x00\x00\x00\x04\x00\x00\x00\x00\x00"; + Document::from_reader(&mut std::io::Cursor::new(buffer)) + .expect_err("expected deserialization to fail"); +} + +/// [RUST-713](https://jira.mongodb.org/browse/RUST-713) +#[test] +fn test_deserialize_invalid_old_binary_length() { + let _guard = LOCK.run_concurrently(); + let buffer = b"\x0F\x00\x00\x00\x05\x00\x00\x00\x00\x00\x02\xFC\xFF\xFF\xFF"; + Document::from_reader(&mut std::io::Cursor::new(buffer)) + .expect_err("expected deserialization to fail"); + + 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++"; + Document::from_reader(&mut std::io::Cursor::new(buffer)) + .expect_err("expected deserialization to fail"); +}