You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello fellow Rustacean,
we (Rust group @sslab-gatech) found a memory-safety/soundness issue in this crate while scanning Rust code on crates.io for potential vulnerabilities.
SyncRef's Sync implementation doesn't impose Sync bound on T. This definition allows data races if &T is accessible through &SyncRef.
SyncRef derives Clone and Debug, and the default implementations of those traits access &T in such a way.
Reproduction
Below is an example program that exhibits undefined behavior using safe APIs of v9.
Show Detail
#![forbid(unsafe_code)]use std::cell::Cell;use std::fmt::Debug;use std::thread;use v9::util::SyncRef;staticSTATIC_INT:u64 = 123;// A simple tagged union for demonstrating the data race#[derive(Clone,Copy)]enumRefOrInt{Ref(&'static u64),Int(u128),}#[derive(Clone)]structRefOrIntCell(Cell<RefOrInt>);implRefOrIntCell{pubfnnew() -> Self{RefOrIntCell(Cell::new(RefOrInt::Ref(&STATIC_INT)))}}implDebugforRefOrIntCell{fnfmt(&self,_f:&mut std::fmt::Formatter<'_>) -> std::fmt::Result{loop{ifletRefOrInt::Ref(addr) = self.0.get(){// Hope that between the time we pattern match the object as a// `Ref`, it gets written to by the other thread.if addr as*constu64 == &STATIC_INTas*constu64{continue;}// We got an invalid reference with safe Rust codeprintln!("Reference is pointing: {:p}", addr);println!("Dereferencing addr will segfault: {}",*addr);}}}}fnmain(){// Creating &'static RefOrIntCelllet ref_or_int = &*Box::leak(Box::new(RefOrIntCell::new()));// Creating &'static SyncRef<&'static RefOrIntCell>let sync_ref = &*Box::leak(Box::new(SyncRef::new(ref_or_int)));
thread::spawn(move || {// Cell<_> is non-Sync, but `SyncRef` allows this type to be accessed concurrently by multiple threadsformat!("{:?}", sync_ref);});loop{// Repeatedly write Ref(&addr) and Int(0xdeadbeef) into the cell.
ref_or_int.0.set(RefOrInt::Ref(&STATIC_INT));
ref_or_int.0.set(RefOrInt::Int(0xdeadbeef));}}
Output:
Reference is pointing: 0xdeadbeef
Terminated with signal 11 (SIGSEGV)
Once a fix is released to crates.io, please open a pull request to update the advisory with the patched version, or file an issue on the advisory database repository.
Crates with soundness holes are fine as long as they're explicitly labeled as such. If you put something like this in the README, it should clear up any confusion:
This crate is experimental and likely unsound. Don't use it in production just yet!
Hello fellow Rustacean,
we (Rust group @sslab-gatech) found a memory-safety/soundness issue in this crate while scanning Rust code on crates.io for potential vulnerabilities.
Issue Description
v9/src/util.rs
Line 27 in 37756c6
SyncRef
'sSync
implementation doesn't imposeSync
bound onT
. This definition allows data races if&T
is accessible through&SyncRef
.SyncRef
derivesClone
andDebug
, and the default implementations of those traits access&T
in such a way.Reproduction
Below is an example program that exhibits undefined behavior using safe APIs of
v9
.Show Detail
Output:
Tested Environment
The text was updated successfully, but these errors were encountered: