Skip to content

Commit be6ff29

Browse files
bors[bot]saethlin
andauthored
Merge #779
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>
2 parents 85d0bdc + b911157 commit be6ff29

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

crossbeam-epoch/src/deferred.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ type Data = [usize; DATA_WORDS];
1818
/// This is a handy way of keeping an unsized `FnOnce()` within a sized structure.
1919
pub(crate) struct Deferred {
2020
call: unsafe fn(*mut u8),
21-
data: Data,
21+
data: MaybeUninit<Data>,
2222
_marker: PhantomData<*mut ()>, // !Send + !Sync
2323
}
2424

@@ -46,7 +46,7 @@ impl Deferred {
4646

4747
Deferred {
4848
call: call::<F>,
49-
data: data.assume_init(),
49+
data,
5050
_marker: PhantomData,
5151
}
5252
} else {
@@ -64,7 +64,7 @@ impl Deferred {
6464

6565
Deferred {
6666
call: call::<F>,
67-
data: data.assume_init(),
67+
data,
6868
_marker: PhantomData,
6969
}
7070
}
@@ -75,7 +75,7 @@ impl Deferred {
7575
#[inline]
7676
pub(crate) fn call(mut self) {
7777
let call = self.call;
78-
unsafe { call(&mut self.data as *mut Data as *mut u8) };
78+
unsafe { call(self.data.as_mut_ptr() as *mut u8) };
7979
}
8080
}
8181

0 commit comments

Comments
 (0)