Potential Undefined Behavior in Buffer struct found
Hello,
We are currently developing a static analysis tool for Rust, and during our testing, we analyzed fcplug. We believe we have identified two instances of Undefined Behavior in the Buffer struct, which we were able to confirm using miri.
Double Free due to Buffer being Copy
The Buffer struct derives #[derive(Copy)]. However, Buffer::from_vec takes ownership of a Vec's memory. Because the Buffer is Copy, this unique ownership can be duplicated, leading to a double-free when the public free_buffer function is called on both copies.
https://github.com/andeya/fcplug/blob/04fd56ad2331af25627800aeebc8f00376f9ca3d/rust/fcplug/src/lib.rs#L25-L27
POC:
fn main() {
let v = vec![1, 2, 3, 4, 5];
let b1 = Buffer::from_vec(v);
let b2 = b1;
println!("b1 ptr: {:?}", b1.ptr);
println!("b2 ptr: {:?}", b2.ptr);
free_buffer(b1);
free_buffer(b2);
}
miri output:
b1 ptr: 0x20adf
b2 ptr: 0x20adf
error: Undefined Behavior: pointer not dereferenceable: alloc210 has been freed, so this pointer is dangling
--> /home/ccuu/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:804:1
|
804 | pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
Use-After-Free due to unsound from_vec_mut
The Buffer::from_vec_mut function takes a &mut Vec
https://github.com/andeya/fcplug/blob/04fd56ad2331af25627800aeebc8f00376f9ca3d/rust/fcplug/src/lib.rs#L153-L164
POC:
fn main() {
let b: Buffer;
{
let mut v = vec![1, 2, 3, 4, 5];
b = Buffer::from_vec_mut(&mut v);
}
let _data = b.read();
}
miri output:
error: Undefined Behavior: pointer not dereferenceable: alloc203 has been freed, so this pointer is dangling
--> /home/ccuu/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fcplug-0.4.5/src/lib.rs:108:27
|
108 | unsafe { Some(std::slice::from_raw_parts(self.ptr, self.len)) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior