Skip to content

Commit aae8277

Browse files
committed
UB-check for alignment of ptr to Box::from_raw{,_in}
1 parent 28b83ee commit aae8277

File tree

3 files changed

+38
-5
lines changed

3 files changed

+38
-5
lines changed

library/alloc/src/boxed.rs

+24-5
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,7 @@ impl<T: ?Sized> Box<T> {
10171017
/// resulting `Box`. Specifically, the `Box` destructor will call
10181018
/// the destructor of `T` and free the allocated memory. For this
10191019
/// to be safe, the memory must have been allocated in accordance
1020-
/// with the [memory layout] used by `Box` .
1020+
/// with the [memory layout] used by `Box`.
10211021
///
10221022
/// # Safety
10231023
///
@@ -1056,8 +1056,15 @@ impl<T: ?Sized> Box<T> {
10561056
#[stable(feature = "box_raw", since = "1.4.0")]
10571057
#[inline]
10581058
#[must_use = "call `drop(Box::from_raw(ptr))` if you intend to drop the `Box`"]
1059-
pub unsafe fn from_raw(raw: *mut T) -> Self {
1060-
unsafe { Self::from_raw_in(raw, Global) }
1059+
pub unsafe fn from_raw(ptr: *mut T) -> Self {
1060+
core::assert_unsafe_precondition!(
1061+
check_language_ub,
1062+
"Box::from_raw requires that its pointer argument is properly aligned and not null",
1063+
() => maybe_is_aligned_and_not_null(ptr as *const (), align_of::<T>(), T::IS_ZST)
1064+
);
1065+
1066+
assert_pointer_is_aligned_and_not_null!("Box::from_raw", ptr, align_of::<T>(), T::IS_ZST);
1067+
unsafe { Self::from_raw_in(ptr, Global) }
10611068
}
10621069

10631070
/// Constructs a box from a `NonNull` pointer.
@@ -1111,6 +1118,12 @@ impl<T: ?Sized> Box<T> {
11111118
#[inline]
11121119
#[must_use = "call `drop(Box::from_non_null(ptr))` if you intend to drop the `Box`"]
11131120
pub unsafe fn from_non_null(ptr: NonNull<T>) -> Self {
1121+
/*assert_pointer_is_aligned_and_not_null!(
1122+
"Box::from_non_null",
1123+
ptr,
1124+
align_of::<T>(),
1125+
T::IS_ZST
1126+
);*/
11141127
unsafe { Self::from_raw(ptr.as_ptr()) }
11151128
}
11161129
}
@@ -1166,8 +1179,14 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
11661179
#[unstable(feature = "allocator_api", issue = "32838")]
11671180
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
11681181
#[inline]
1169-
pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
1170-
Box(unsafe { Unique::new_unchecked(raw) }, alloc)
1182+
pub const unsafe fn from_raw_in(ptr: *mut T, alloc: A) -> Self {
1183+
/*assert_pointer_is_aligned_and_not_null!(
1184+
"Box::from_raw_in",
1185+
ptr,
1186+
align_of::<T>(),
1187+
T::IS_ZST
1188+
);*/
1189+
Box(unsafe { Unique::new_unchecked(ptr) }, alloc)
11711190
}
11721191

11731192
/// Constructs a box from a `NonNull` pointer in the given allocator.

library/alloc/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154
#![feature(try_trait_v2)]
155155
#![feature(try_with_capacity)]
156156
#![feature(tuple_trait)]
157+
#![feature(ub_checks)]
157158
#![feature(unicode_internals)]
158159
#![feature(unsize)]
159160
#![feature(unwrap_infallible)]

library/core/src/ub_checks.rs

+13
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,19 @@ pub(crate) const fn maybe_is_aligned_and_not_null(
129129
)
130130
}
131131

132+
/// Specialized version of `assert_unsafe_precondition` for checking that a pointer is properly aligned and not null
133+
#[macro_export]
134+
#[unstable(feature = "ub_checks", issue = "none")]
135+
macro_rules! assert_pointer_is_aligned_and_not_null {
136+
($function_name: literal, $ptr: expr, $align: expr, $is_zst: expr) => {
137+
::core::assert_unsafe_precondition!(
138+
check_language_ub,
139+
concat!($function_name, " requires that its pointer argument is properly aligned and not null"),
140+
() => ::core::ub_checks::maybe_is_aligned_and_not_null(ptr as *const (), $align, $is_zst)
141+
);
142+
}
143+
}
144+
132145
#[inline]
133146
pub(crate) const fn is_valid_allocation_size(size: usize, len: usize) -> bool {
134147
let max_len = if size == 0 { usize::MAX } else { isize::MAX as usize / size };

0 commit comments

Comments
 (0)