Skip to content

Fix data race in Arc and Weak types - #139

Open
Ollie-Pearce wants to merge 1 commit into
ZettaScaleLabs:mainfrom
Ollie-Pearce:fix-data-race
Open

Fix data race in Arc and Weak types#139
Ollie-Pearce wants to merge 1 commit into
ZettaScaleLabs:mainfrom
Ollie-Pearce:fix-data-race

Conversation

@Ollie-Pearce

Copy link
Copy Markdown

Refcount decrements for Arc use Relaxed. This can result in a data race when two threads drop an owned instance of a type duplicated via Clone.

Reproduction:

Test Case:

#[test]
fn racy_test() {
    let a: Arc<u64, RustAlloc> = Arc::new_in(7, RustAlloc::new());
    let b = a.clone();
    std::thread::scope(|s| {
        s.spawn(move || drop(b));
        drop(a);
    });
}

Running with Miri:

MIRIFLAGS="-Zmiri-many-seeds=0..16" cargo +nightly-2025-08-20 miri test -p stabby-abi --test repro

Miri output:

error: Undefined Behavior: Data race detected between (1) atomic store on thread `race_arc_drop_v` and (2) deallocation on thread `unnamed-3` at alloc688906+0x20
    |
 82 | /         alloc_rs::alloc::dealloc(
 83 | |             dealloc_start,
 84 | |             core::alloc::Layout::from_size_align_unchecked(prev_layout.size, prev_layout.align),
 85 | |         )
    | |_________^ (2) just happened here

Fix:

Synchronise drops of std::sync::Arc using a release ordering to decrement the reference counter and a fence before memory is freed. This mirrors the synchronisation used by std::sync::Arc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant