Skip to content

Commit

Permalink
epoch: Fix UB in Pointable impl of [MaybeUninit<T>]
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed May 4, 2021
1 parent c093db3 commit bc1f08e
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions crossbeam-epoch/src/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ impl<T> Pointable for T {
// [`alloc::alloc::Layout::extend`] instead.
#[repr(C)]
struct Array<T> {
/// The number of elements (not the number of bytes).
size: usize,
elements: [MaybeUninit<T>; 0],
}
Expand All @@ -247,15 +248,15 @@ impl<T> Pointable for [MaybeUninit<T>] {

type Init = usize;

unsafe fn init(size: Self::Init) -> usize {
let size = mem::size_of::<Array<T>>() + mem::size_of::<MaybeUninit<T>>() * size;
unsafe fn init(len: Self::Init) -> usize {
let size = mem::size_of::<Array<T>>() + mem::size_of::<MaybeUninit<T>>() * len;
let align = mem::align_of::<Array<T>>();
let layout = alloc::Layout::from_size_align(size, align).unwrap();
let ptr = alloc::alloc(layout) as *mut Array<T>;
if ptr.is_null() {
alloc::handle_alloc_error(layout);
}
(*ptr).size = size;
(*ptr).size = len;
ptr as usize
}

Expand Down Expand Up @@ -1529,7 +1530,8 @@ impl<T: ?Sized + Pointable> Default for Shared<'_, T> {

#[cfg(all(test, not(crossbeam_loom)))]
mod tests {
use super::Shared;
use super::{Owned, Shared};
use std::mem::MaybeUninit;

#[test]
fn valid_tag_i8() {
Expand All @@ -1547,4 +1549,11 @@ mod tests {
use super::Atomic;
const _: Atomic<u8> = Atomic::<u8>::null();
}

#[test]
fn array_init() {
let owned = Owned::<[MaybeUninit<usize>]>::init(10);
let arr: &[MaybeUninit<usize>] = &*owned;
assert_eq!(arr.len(), 10);
}
}

0 comments on commit bc1f08e

Please sign in to comment.