-
Notifications
You must be signed in to change notification settings - Fork 643
Closed
Description
This code in scratch_arena causes undefined behavior if it's called while there's an existing ScratchArena object pointing to the same slot. That's because taking a new mutable borrow invalidates all existing borrows.
let arena = &mut S_SCRATCH[index];
ScratchArena::new(arena)I'm not sure whether the application itself actually triggers the UB, but the documentation indicates that it's intended for "the same Arena to be borrowed multiple times at once".
This is trivial to fix, though, because ScratchArena::new doesn't need a mutable borrow. Just change &mut to & here.
For completeness, I verified the UB by adding the following test and running cargo miri test arena:
#[test]
fn test_arena() {
fn recur(n: u32, other: Option<&Arena>) {
let scratch = scratch_arena(other);
if n != 0 {
recur(n - 1, Some(&scratch));
}
}
recur(5, None);
}test arena::scratch::test_arena ... error: Undefined Behavior: trying to retag from <214510> for SharedReadOnly permission at alloc25[0x28], but that tag does not exist in the borrow stack for this location
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels