Skip to content

Commit

Permalink
Merge #779
Browse files Browse the repository at this point in the history
779: Don't call assume_init on Deferred's Data r=taiki-e a=saethlin

This situation can be observed by running `MIRIFLAGS="-Zmiri-check-number-validity" cargo miri test` in `crossbeam/crossbeam-deque`:
```
test is_empty ... error: Undefined Behavior: type validation failed at .value[0]: encountered uninitialized bytes
  --> /home/ben/crossbeam/crossbeam-epoch/src/deferred.rs:49:27a
   |
49 |                     data: data.assume_init(),
   |                           ^^^^^^^^^^^^^^^^^^ type validation failed at .value[0]: encountered uninitialized bytes
   |
```

In the crossbeam-deque test suite, a `Deferred` was created from a `FnOnce` which is smaller than the `Data`. This makes the call to `MaybeUninit::assume_init()` immediate UB (the reference to it created upon call is probably UB too). [The docs for `MaybeUninit::assume_init()`](https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#safety) say this:
> It is up to the caller to guarantee that the MaybeUninit<T> really is in an initialized state. Calling this when the content is not yet fully initialized causes immediate undefined behavior. The [type-level documentation](https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#initialization-invariant) contains more information about this initialization invariant.

 Since `Data` doesn't have a `Drop` impl, we can just leave it in the `MaybeUninit` wrapper. This removes all issues about type validity.

Co-authored-by: Ben Kimock <kimockb@gmail.com>
  • Loading branch information
bors[bot] and saethlin committed Feb 5, 2022
2 parents 85d0bdc + b911157 commit be6ff29
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions crossbeam-epoch/src/deferred.rs
Expand Up @@ -18,7 +18,7 @@ type Data = [usize; DATA_WORDS];
/// This is a handy way of keeping an unsized `FnOnce()` within a sized structure.
pub(crate) struct Deferred {
call: unsafe fn(*mut u8),
data: Data,
data: MaybeUninit<Data>,
_marker: PhantomData<*mut ()>, // !Send + !Sync
}

Expand Down Expand Up @@ -46,7 +46,7 @@ impl Deferred {

Deferred {
call: call::<F>,
data: data.assume_init(),
data,
_marker: PhantomData,
}
} else {
Expand All @@ -64,7 +64,7 @@ impl Deferred {

Deferred {
call: call::<F>,
data: data.assume_init(),
data,
_marker: PhantomData,
}
}
Expand All @@ -75,7 +75,7 @@ impl Deferred {
#[inline]
pub(crate) fn call(mut self) {
let call = self.call;
unsafe { call(&mut self.data as *mut Data as *mut u8) };
unsafe { call(self.data.as_mut_ptr() as *mut u8) };
}
}

Expand Down

0 comments on commit be6ff29

Please sign in to comment.