lockbud
lockbud copied to clipboard
An FP about Use After Free Detection in LockBud
I encounter a false positive UseAfterFree warning in LockBud. The reported UAF warning should not occur in practice because Rust's Arc mechanism already provides guaranteed memory safety. Below is a minimized reproduction of this case.
I run the cargo lockbud -k all command and Lockbud should not report a UseAfterFree warning because the code in lines 27 and 32 uses Arc, which guarantees the referenced data remains valid (no use-after-free occurs).
fn func() {
use std::ptr;
use std::sync::{Arc, atomic::{AtomicPtr, Ordering}};
struct Owned<T> {
data: T,
}
impl<T> Owned<T> {
fn as_raw(&self) -> *mut T {
&self.data as *const _ as *mut _
}
}
fn opt_owned_as_raw<T>(val: &Option<Arc<Owned<T>>>) -> *mut T {
val.as_ref().map(|o| o.as_raw()).unwrap_or(ptr::null_mut())
}
struct Obj<T> {
ptr: AtomicPtr<T>,
}
impl<T> Obj<T> {
fn null() -> Self {
Obj {
ptr: AtomicPtr::new(ptr::null_mut()),
}
}
fn load(&self, ord: Ordering) -> *mut T {
self.ptr.load(ord)
}
fn store(&self, owned: Option<Arc<Owned<T>>>, ord: Ordering) {
self.ptr.store(opt_owned_as_raw(&owned), ord); // report a false UseAfterFree warning
}
}
let o = Obj::<Vec<i32>>::null();
let owned = Some(Arc::new(Owned { data: Vec::new() }));
o.store(owned.clone(), Ordering::Relaxed);
let p = o.load(Ordering::Relaxed);
unsafe {
println!("{:?}", *p);
}
}
fn main() {
func();
}
However, Lockbud reports the following UseAfterFree warning:
"UseAfterFree": {
"bug_kind": "UseAfterFree",
"possibility": "Possibly",
"diagnosis": "Escape to Param/Return: Raw ptr _5 at src/main.rs:28:13: 28:21 (#0) escapes to [(_1.0: std::sync::atomic::AtomicPtr<T>)] but pointee is dropped at src/main.rs:29:9: 29:10 (#0)",
"explanation": "Raw ptr is used or escapes the current function after the pointed value is dropped"
}