aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Barnard2017-03-06 21:08:58 +0000
committerEdward Barnard2017-03-06 21:08:58 +0000
commit1df5db005ea9959c4e19107997f446dc17095be4 (patch)
tree703c0f8b482ed563b72a2b76fc412f59ed3c6540
parente322e26b7e8c3dbfcba5c6142ca7559b63fc1652 (diff)
downloadrust-plist-1df5db005ea9959c4e19107997f446dc17095be4.tar.bz2
Limit the number of objects that can be created by the binary parser. Binary plists can contain circular references.
-rw-r--r--src/binary/reader.rs15
-rw-r--r--tests/fuzzer.rs6
2 files changed, 20 insertions, 1 deletions
diff --git a/src/binary/reader.rs b/src/binary/reader.rs
index e8a2bf8..770b12f 100644
--- a/src/binary/reader.rs
+++ b/src/binary/reader.rs
@@ -40,6 +40,11 @@ pub struct EventReader<R> {
// The largest single allocation allowed for this Plist.
// Equal to the number of bytes in the Plist minus the magic and trailer.
max_allocation: usize,
+ // The maximum number of objects that can be created. Default 10 * object_offsets.len().
+ // Binary plists can contain circular references.
+ max_objects: usize,
+ // The number of objects created so far.
+ current_objects: usize,
}
impl<R: Read + Seek> EventReader<R> {
@@ -50,7 +55,9 @@ impl<R: Read + Seek> EventReader<R> {
reader: reader,
ref_size: 0,
finished: false,
- max_allocation: 0
+ max_allocation: 0,
+ max_objects: 0,
+ current_objects: 0,
}
}
@@ -92,6 +99,8 @@ impl<R: Read + Seek> EventReader<R> {
try!(self.reader.seek(SeekFrom::Start(offset_table_offset)));
self.object_offsets = try!(self.read_ints(num_objects, offset_size));
+ self.max_objects = self.object_offsets.len() * 10;
+
// Seek to top object
self.stack.push(StackItem {
object_refs: vec![top_object],
@@ -164,6 +173,10 @@ impl<R: Read + Seek> EventReader<R> {
match object_ref {
Some(object_ref) => {
+ if self.current_objects > self.max_objects {
+ return Err(Error::InvalidData);
+ }
+ self.current_objects += 1;
try!(self.seek_to_object(object_ref));
}
None => {
diff --git a/tests/fuzzer.rs b/tests/fuzzer.rs
index 4d7b151..65ce8eb 100644
--- a/tests/fuzzer.rs
+++ b/tests/fuzzer.rs
@@ -21,6 +21,12 @@ fn empty_offset_table() {
test_fuzzer_data_err(data);
}
+#[test]
+fn binary_circular_reference() {
+ let data = b"bplist00\xd6\x01\x02\x03\x04\x05\x06\x07\x0a\x0b\x0c\x0d\x0eULinesUDeathVHeightYBirthdateVAutbplist00\xd6\x01\x02\x03\x04\x05\x06\x07\x0a\x0b\x0c\x0d\x0eULinesUDeathVHeightYBirthdateVAuthorTData\xa2\x08\x09_\x10\x1eIt is nifying nothing.\x11\x06\x1c#?\xf9\x99\x99\x99\x99\x99\x9a3\xc1\xc2v\x00e\x00\x00\x00_\x10\x13William ShakespeareO\x10\x0f\x00\x00\x00\xbe\x00\x00\x00\x03\x00\x00\x00\x1e\x00\x00\x00\x08\x15\x1b!(58>Ab\x90\x93\x9c\xa5\xbb\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd";
+ test_fuzzer_data_err(data);
+}
+
fn test_fuzzer_data_err(data: &[u8]) {
let cursor = Cursor::new(data);
let res = Plist::read(cursor);