-
Notifications
You must be signed in to change notification settings - Fork 392
Description
This program will crash Miri:
extern "Rust" {
pub fn miri_run_provenance_gc();
}
fn oof(mut b: Box<u8>) {
drop(b);
b = Box::new(0u8);
unsafe { miri_run_provenance_gc() };
}
fn main() {
oof(Box::new(0u8));
}
We create a Box
, and immediately pass it to a function which makes it weakly protected.
This function argument is the only memory with the relevant AllocId.
Then we deallocate the Box
, and at the same time overwrite the function argument.
One GC run later
We return from the function and execute this code to check if the allocation is still alive and 💥
miri/src/borrow_tracker/mod.rs
Lines 378 to 384 in e615426
// Just because the tag is protected doesn't guarantee that | |
// the allocation still exists (weak protectors allow deallocations) | |
// so we must check that the allocation exists. | |
// If it does exist, then we have the guarantee that the | |
// pointer is readable, and the implicit read access inserted | |
// will never cause UB on the pointer itself. | |
let (_, _, kind) = this.get_alloc_info(*alloc_id); |
I'm not entirely sure what the best way to fix this is. The obvious way would be to visit the AllocIds in borrow_tracker::FrameExtra
in the GC. But the comments we left around there seemed pretty confident that wouldn't be required, so I'm not totally sure there isn't another sort of design flaw here.