-
Notifications
You must be signed in to change notification settings - Fork 127
Description
Currently the VcpuFd structure implements both Send and Sync so it's safe to share across threads, but this method enables mutation of shared memory. The signature for this method takes &self which means it can be invoked concurrently on multiple threads. Its current implementation:
pub fn set_kvm_immediate_exit(&self, val: u8) {
let kvm_run = self.kvm_run_ptr.as_mut_ref();
kvm_run.immediate_exit = val;
}currently can expose two issues in Rust's memory model. The first is that the as_mut_ref function cannot be sound because it's promoting a safe shared reference to a safe mutable reference. Mutable references guarantee exclusivitity but that's not the case here with multiple threads. The second issue is that the write here is a non-atomic write as opposed to an atomic write, which means that multiple threads can do non-atomic writes causing a data race.
I found this when poking around this crate (thanks for providing it!). I'm still very new to this space and am trying to get my bearings. I was planning on using this to set this flag from another thread to assist with interrupting a VM, which is why I was curious how it worked internally given its signature.
I think that the fix here is relatively simple, just restructuring things internally. In theory as_mut_ref() should be removed entirely (that method signature can't ever be sound in Rust) and instead code can use ptr::addr_of to convert from *mut kvm_run to *mut u8 for the flag here. That could then be casted to AtomicU8 and the store done through that.