Skip to content

Commit

Permalink
Fix memory exhaustion with malicious header size (flatgeobuf#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
pka committed Nov 28, 2020
1 parent 25a0456 commit 5d6b302
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 4 deletions.
6 changes: 6 additions & 0 deletions src/rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,9 @@ See [documentation](https://docs.rs/flatgeobuf/) and [tests](tests/) for more ex
cargo test

cargo bench

## Run fuzzer

cargo install cargo-fuzz

cargo +nightly fuzz run read
5 changes: 4 additions & 1 deletion src/rust/src/file_reader.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::header_generated::flat_geobuf::*;
use crate::packed_r_tree::{self, PackedRTree};
use crate::properties_reader::FgbFeature;
use crate::MAGIC_BYTES;
use crate::{HEADER_MAX_BUFFER_SIZE, MAGIC_BYTES};
use geozero::error::{GeozeroError, Result};
use geozero::{FeatureProcessor, ReadSeek};
use std::io::SeekFrom;
Expand Down Expand Up @@ -34,6 +34,9 @@ impl<'a> FgbReader<'a> {
let mut size_buf: [u8; 4] = [0; 4];
reader.read_exact(&mut size_buf)?;
let header_size = u32::from_le_bytes(size_buf) as usize;
if header_size > HEADER_MAX_BUFFER_SIZE {
return Err(GeozeroError::GeometryFormat);
}

let mut header_buf = Vec::with_capacity(header_size);
header_buf.resize(header_size, 0);
Expand Down
3 changes: 1 addition & 2 deletions src/rust/src/header_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,5 +809,4 @@ pub fn finish_header_buffer<'a, 'b>(
pub fn finish_size_prefixed_header_buffer<'a, 'b>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset<Header<'a>>) {
fbb.finish_size_prefixed(root, None);
}
} // pub mod FlatGeobuf

} // pub mod FlatGeobuf
5 changes: 4 additions & 1 deletion src/rust/src/http_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::header_generated::flat_geobuf::*;
use crate::http_client::BufferedHttpClient;
use crate::packed_r_tree::{self, PackedRTree};
use crate::properties_reader::FgbFeature;
use crate::MAGIC_BYTES;
use crate::{HEADER_MAX_BUFFER_SIZE, MAGIC_BYTES};
use byteorder::{ByteOrder, LittleEndian};
use geozero::error::{GeozeroError, Result};
use geozero::FeatureProcessor;
Expand Down Expand Up @@ -35,6 +35,9 @@ impl HttpFgbReader {
}
let bytes = client.get(8, 12, min_req_size).await?;
let header_size = LittleEndian::read_u32(bytes) as usize;
if header_size > HEADER_MAX_BUFFER_SIZE {
return Err(GeozeroError::GeometryFormat);
}
let bytes = client.get(12, header_size, min_req_size).await?;
let header_buf = bytes.to_vec();

Expand Down
2 changes: 2 additions & 0 deletions src/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,5 @@ pub use properties_reader::*;

pub const VERSION: u8 = 3;
pub const MAGIC_BYTES: [u8; 8] = [b'f', b'g', b'b', VERSION, b'f', b'g', b'b', 0];

pub const HEADER_MAX_BUFFER_SIZE: usize = 1048576 * 10;

0 comments on commit 5d6b302

Please sign in to comment.