flatgeobuf/flatgeobuf

Index out of bounds panic occurs when reading header

frewsxcv opened this issue · 1 comments

Reading this slice of bytes into the Rust FgbReader will cause an index out of bounds panic:

let input: &[u8] = &[102, 103, 98, 3, 102, 103, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
thread '<unnamed>' panicked at 'range end index 4 out of range for slice of length 0', /Users/coreyf/.cargo/registry/src/github.com-1ecc6299db9ec823/flatbuffers-0.6.1/src/primitives.rs:180:22
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a0d664bae6ca79c54cc054aa2403198e105190a2/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/a0d664bae6ca79c54cc054aa2403198e105190a2/library/core/src/panicking.rs:92:14
   2: core::slice::index::slice_end_index_len_fail
             at /rustc/a0d664bae6ca79c54cc054aa2403198e105190a2/library/core/src/slice/index.rs:41:5
   3: flatgeobuf::file_reader::FgbReader::header
   4: _rust_fuzzer_test_input
   5: ___rust_try
   6: _LLVMFuzzerTestOneInput
   7: __ZN6fuzzer6Fuzzer15ExecuteCallbackEPKhm
   8: __ZN6fuzzer6Fuzzer6RunOneEPKhmbPNS_9InputInfoEbPb
   9: __ZN6fuzzer6Fuzzer16MutateAndTestOneEv
  10: __ZN6fuzzer6Fuzzer4LoopERNSt3__16vectorINS_9SizedFileENS_16fuzzer_allocatorIS3_EEEE
  11: __ZN6fuzzer12FuzzerDriverEPiPPPcPFiPKhmE
  12: _main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
==84348== ERROR: libFuzzer: deadly signal
    #0 0x10e418895 in __sanitizer_print_stack_trace+0x35 (librustc-nightly_rt.asan.dylib:x86_64+0x4e895)
    #1 0x10c4e6f5a in fuzzer::PrintStackTrace()+0x2a (read:x86_64+0x100024f5a)
    #2 0x10c4d94e3 in fuzzer::Fuzzer::CrashCallback()+0x43 (read:x86_64+0x1000174e3)
    #3 0x7fff2036fd7c in _sigtramp+0x1c (libsystem_platform.dylib:x86_64+0x3d7c)

NOTE: libFuzzer has rudimentary signal handlers.
      Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal
MS: 1 CMP- DE: "\x00\x00\x00\x00\x00\x00\x00\x00"-; base unit: f4bda5aa4bd1aba187f23ffa02189e44de7d95f8
0x66,0x67,0x62,0x3,0x66,0x67,0x62,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
fgb\x03fgb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
artifact_prefix='/Users/coreyf/tmp/flatgeobuf/src/rust/fuzz/artifacts/read/'; Test unit written to /Users/coreyf/tmp/flatgeobuf/src/rust/fuzz/artifacts/read/crash-a973003ed587bc77ccce1de26ccca5b8e06be32b
Base64: ZmdiA2ZnYgAAAAAAAAAAAAAA

Note that I applied this patch to work around the OOM issue brought up in #85:

diff --git a/src/rust/src/file_reader.rs b/src/rust/src/file_reader.rs
index 0dd4092..670cf47 100644
--- a/src/rust/src/file_reader.rs
+++ b/src/rust/src/file_reader.rs
@@ -35,6 +35,10 @@ impl<'a> FgbReader<'a> {
         reader.read_exact(&mut size_buf)?;
         let header_size = u32::from_le_bytes(size_buf) as usize;

+        if header_size > 20_000_000 {
+            return Err(GeozeroError::GeometryFormat);
+        }
+
         let mut header_buf = Vec::with_capacity(header_size);
         header_buf.resize(header_size, 0);
         reader.read_exact(&mut header_buf)?;

Discovered while fuzzing via #84

pka commented

This panic occurs in FlatBuffers decoding. Buffer verification is not supported for Rust (see https://google.github.io/flatbuffers/flatbuffers_support.html), so there are more panics to expect. A check for minimal buffer size seems to prevent many of them.