rust-fuzz/libfuzzer

Soundness issue in rust_fuzzer_custom_mutator

gigaroby opened this issue · 0 comments

While conducting an internal unsafe review @cramertj found issues in rust_fuzzer_custom_mutator:

This function should also be unsafe since it makes assumptions about $data, $size, and $max_size when calling from_raw_parts_mut. Additionally, as far as I can tell, there is no guarantee here that data has been initialized up to max_size, so it's not safe to use with from_raw_parts_mut, as this would allow the user to read from uninitialized memory. Misoptimizations seem unlikely to be an issue in practice due to the FFI boundary, however.

libfuzzer/src/lib.rs

Lines 464 to 485 in c9c43f3

pub fn rust_fuzzer_custom_mutator(
$data: *mut u8,
$size: usize,
$max_size: usize,
$seed: std::os::raw::c_uint,
) -> usize {
// Depending on if we are growing or shrinking the test case, `size`
// might be larger or smaller than `max_size`. The `data`'s capacity
// is the maximum of the two.
let len = std::cmp::max($max_size, $size);
let $data: &mut [u8] = unsafe { std::slice::from_raw_parts_mut($data, len) };
// `unsigned int` is generally a `u32`, but not on all targets. Do
// an infallible (and potentially lossy, but that's okay because it
// preserves determinism) conversion.
let $seed = $seed as u32;
// Truncate the new size if it is larger than the max.
let new_size = { $body };
std::cmp::min(new_size, $max_size)
}
};