lockbud icon indicating copy to clipboard operation
lockbud copied to clipboard

An FP about Use After Free Detection in LockBud

Open soyo114 opened this issue 8 months ago • 2 comments

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"
}

soyo114 avatar Apr 15 '25 02:04 soyo114