Skip to content

Commit

Permalink
Merge #1010
Browse files Browse the repository at this point in the history
1010: Fix ownership invalidation of saved scope panics r=cuviper a=cuviper

Miri complained when we tried to reconstruct a panic `Box` from an
`AtomicPtr`, because a later call to `mem::forget` invalidated that
pointer, even though we just meant not to drop it. `ManuallyDrop` is a
way to accomplish that *before* we take the pointer.

```
test scope::test::panic_propagate_nested_scope_spawn - should panic ... error: Undefined Behavior: trying to retag from <547680> for Unique permission at alloc207942[0x0], but that tag does not exist in the borrow stack for this location
    --> ~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1014:9
     |
1014 |         Box(unsafe { Unique::new_unchecked(raw) }, alloc)
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |         |
     |         trying to retag from <547680> for Unique permission at alloc207942[0x0], but that tag does not exist in the borrow stack for this location
     |         this error occurs as part of retag at alloc207942[0x0..0x10]
     |
     = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
     = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <547680> was created by a SharedReadWrite retag at offsets [0x0..0x10]
    --> rayon-core/src/scope/mod.rs:732:36
     |
732  |             .compare_exchange(nil, &mut *err, Ordering::Release, Ordering::Relaxed)
     |                                    ^^^^^^^^^
help: <547680> was later invalidated at offsets [0x0..0x10] by a Unique retag
    --> rayon-core/src/scope/mod.rs:735:25
     |
735  |             mem::forget(err); // ownership now transferred into self.panic
     |                         ^^^
```


Co-authored-by: Josh Stone <[email protected]>
  • Loading branch information
bors[bot] and cuviper authored Jan 19, 2023
2 parents 0cc5912 + 063b406 commit ed98853
Showing 1 changed file with 15 additions and 9 deletions.
24 changes: 15 additions & 9 deletions rayon-core/src/scope/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::unwind;
use std::any::Any;
use std::fmt;
use std::marker::PhantomData;
use std::mem;
use std::mem::ManuallyDrop;
use std::ptr;
use std::sync::atomic::{AtomicPtr, Ordering};
use std::sync::Arc;
Expand Down Expand Up @@ -725,14 +725,20 @@ impl<'scope> ScopeBase<'scope> {

fn job_panicked(&self, err: Box<dyn Any + Send + 'static>) {
// capture the first error we see, free the rest
let nil = ptr::null_mut();
let mut err = Box::new(err); // box up the fat ptr
if self
.panic
.compare_exchange(nil, &mut *err, Ordering::Release, Ordering::Relaxed)
.is_ok()
{
mem::forget(err); // ownership now transferred into self.panic
if self.panic.load(Ordering::Relaxed).is_null() {
let nil = ptr::null_mut();
let mut err = ManuallyDrop::new(Box::new(err)); // box up the fat ptr
let err_ptr: *mut Box<dyn Any + Send + 'static> = &mut **err;
if self
.panic
.compare_exchange(nil, err_ptr, Ordering::Release, Ordering::Relaxed)
.is_ok()
{
// ownership now transferred into self.panic
} else {
// another panic raced in ahead of us, so drop ours
let _: Box<Box<_>> = ManuallyDrop::into_inner(err);
}
}
}

Expand Down

0 comments on commit ed98853

Please sign in to comment.