Description
The following lines are unsound when given a user defined reader who is allowed to read from the buffer local_buf
.
Lines 164 to 173 in 0ebb96c
I can't run a test case in miri, but the following fuzzing harness with --sanitizer=memory
given will find it.
#![no_main]
#[macro_use] extern crate libfuzzer_sys;
extern crate bson;
use bson::Document;
use std::io::Cursor;
fuzz_target!(|buf: &[u8]| {
struct HostileReader<R> {
reader: R,
}
impl<R: std::io::Read> std::io::Read for HostileReader<R> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
let v: usize = buf.iter().copied().map(|x| x as usize).sum();
self.reader.read(buf)
}
}
let mut r = HostileReader { reader: Cursor::new(&buf[..]) };
let _ = Document::from_reader(&mut r);
});
An implementation of std::io::Read
which reads from the buffer given instead of purely writing to it is discouraged, but Read
is a safe trait, so it's not unsafe to do this.
There's the https://doc.rust-lang.org/std/io/trait.Read.html#method.initializer method, but it's unstable, tracking issue: rust-lang/rust#42788
Failing that, I think the only reasonable thing to do is to just zero out the buffer (just like what's done above for the case where decimal128
is not enabled).
As a side note, does anyone know why decimal::d128::from_raw_bytes is unsafe? We're calling it with completely unchecked values from the user, so if there's any values for which it can cause UB, that doesn't sound safe. I might open an issue on their end asking for clarification as to why it's unsafe.
I had a look at the documentation there there's no indication as to what you need to do to be safe calling it. Looks like from_hex does basically the same thing as from_raw_bytes, so it shouldn't be unsafe?