lockbud icon indicating copy to clipboard operation
lockbud copied to clipboard

FN Bug in CondvarDeadlock Detection

Open soyo114 opened this issue 2 months ago • 3 comments

Description

Hi, I found a false negative about the CondvarDeadlock vulnerability detection when using lockbud. The minmized code example is provided below. Lockbud should report a CondvarDeadlock warning. The lock in the line let _i = self.other.lock().unwrap(); //wait_lock and the lock in the line 33 let _i = self.other.lock().unwrap(); //notify_lock are the same lock, and the program hangs due to a deadlock. I used the command cargo lockbud -k all to run the tool.

Case

use std::sync::Arc;
use std::thread;
use std::time::Duration;
fn foo() {
    use std::sync::{Condvar, Mutex};
    struct CondPair {
        lock: Mutex<bool>,
        cvar: Condvar,
        other: Mutex<i32>,
    }
    impl CondPair {
        fn new() -> Self {
            Self {
                lock: Mutex::new(false),
                cvar: Condvar::new(),
                other: Mutex::new(1),
            }
        }
        fn wait(&self) {
            let _i = self.other.lock().unwrap();  //wait_lock
            let wait_for_condition = || {
                let mut started = self.lock.lock().unwrap();
                while !*started {
                    started = self.cvar.wait(started).unwrap();  //condvar_wait
                }
            };
            wait_for_condition();
        }
        fn notify(&self) {
            thread::sleep(Duration::from_millis(1000));
            let _i = self.other.lock().unwrap();  //notify_lock
            let mut started = self.lock.lock().unwrap();
            *started = true;
            self.cvar.notify_one();  //condvar_notify
        }
    }
    let condvar1 = Arc::new(CondPair::new());
    let condvar2 = condvar1.clone();
    let th1 = thread::spawn(move || {
        condvar1.wait();
    });
    condvar2.notify();
    th1.join().unwrap();
}
fn main() {
    foo();
}

soyo114 avatar Oct 15 '25 06:10 soyo114