Skip to content

Fix data race possible from safe code on InlineArray type - #8

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

Fix data race possible from safe code on InlineArray type#8
Ollie-Pearce wants to merge 1 commit into
komora-io:mainfrom
Ollie-Pearce:fix-data-race

Conversation

@Ollie-Pearce

Copy link
Copy Markdown

The make_mut function for InlineArray selects the wrong From implementation as calling self.deref() matches the blanket impl<T> Deref for &mut T first before reaching InlineArray's own Deref impl.

impl From<&InlineArray> for InlineArray { //Incorrect From impl
    fn from(v: &Self) -> Self { v.clone() }
}
impl From<&[u8]> for InlineArray { //Correct From impl
    fn from(slice: &[u8]) -> Self { InlineArray::new(slice) }
}

Reproduction:

Test case:

#[test]
fn make_mut_races_a_shared_clone() {
    let bytes: InlineArray = InlineArray::from("foobar000".to_string());
    let bytes_clone = bytes.clone();

    std::thread::scope(|s| {
        s.spawn(move || {
            let bytes = bytes;
            bytes.as_ref();
        });

        let mut bytes = bytes_clone;
        bytes.make_mut();
    });
}

Verifying with Miri:

cargo +nightly-2025-08-20 miri test --test repro
test make_mut_races_a_shared_clone ... error: Undefined Behavior: Data race detected between (1) retag write on thread `make_mut_races_` and (2) retag read of type `[u8]` on thread `unnamed-2` at alloc40180
    |
276 |                 std::slice::from_raw_parts(data_ptr, len)
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (2) just happened here
    |
help: and (1) occurred earlier here
   --> tests/repro.rs:15:9
    |
 15 |         bytes.make_mut();
    |         ^^^^^^^^^^^^^^^^
    = help: retags occur on all (re)borrows and as well as when references are copied or moved
    = help: retags permit optimizations that insert speculative reads or writes
    = help: therefore from the perspective of data races, a retag has the same implications as a read or write
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
    = note: BACKTRACE (of the first span) on thread `unnamed-2`:

Fix:

  • Change self.deref() to &**self in order to invoke InlineArray's own Deref impl and the correct From impl

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