-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Description
Hi there, we (Rust group @sslab-gatech) are scanning crates on crates.io for potential soundness bugs. We noticed that Slock
implements Send
and Sync
for all types:
Lines 268 to 269 in 301f598
unsafe impl<T> Send for Slock<T> {} | |
unsafe impl<T> Sync for Slock<T> {} |
This should probably be bounded by T: Send
just like the standard library's Mutex, otherwise this allows sending non-Send types across thread boundaries which may invoke undefined behavior.
Here's an example of this in action with an Rc
segfaulting safe Rust code. Built with futures 0.3.8
with thread-pool
feature enabled:
#![forbid(unsafe_code)]
use slock::Slock;
use std::rc::Rc;
use futures::executor::ThreadPool;
fn main() {
let rc = Rc::new(());
let lock = Slock::new(rc);
let another_lock = lock.split();
let fut1 = async move {
let rc = lock.get_clone().await;
println!("Future 1 - {:p}", rc);
// Race the un-synchronized refcount in the RCs.
for _ in 0..100_000_000 {
rc.clone();
}
};
let fut2 = async move {
let rc = another_lock.get_clone().await;
println!("Future 2 - {:p}", rc);
for _ in 0..100_000_000 {
rc.clone();
}
};
let mut pool = ThreadPool::new().unwrap();
pool.spawn_ok(fut1);
pool.spawn_ok(fut2);
// Give the pool time to complete its tasks.
loop {}
}
This outputs:
Future 1 - 0x561c3cd6ba50
Future 2 - 0x561c3cd6ba50
Return Code: -4 (SIGILL)
Metadata
Metadata
Assignees
Labels
No labels