rust/kernel/alloc/kbox.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
Extend the safety requirements of `Box::from_raw()` to mention that the
layout of the allocation must match exactly. Even though the underlying
allocators maintain allocation layout information to some degree, the
Rust abstraction strictly requires the layout to match exactly.
Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: David Rheinsberg <david@readahead.eu>
---
rust/kernel/alloc/kbox.rs | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
index 622b3529edfc..1b30c51f87ab 100644
--- a/rust/kernel/alloc/kbox.rs
+++ b/rust/kernel/alloc/kbox.rs
@@ -170,15 +170,16 @@ impl<T, A> Box<T, A>
///
/// # Safety
///
- /// For non-ZSTs, `raw` must point at an allocation allocated with `A` that is sufficiently
- /// aligned for and holds a valid `T`. The caller passes ownership of the allocation to the
- /// `Box`.
+ /// For non-ZSTs, `raw` must point at an allocation allocated with `A` with a layout
+ /// of `Layout::for_value::<T>()`. The caller passes ownership of the allocation
+ /// to the `Box`.
///
/// For ZSTs, `raw` must be a dangling, well aligned pointer.
#[inline]
pub const unsafe fn from_raw(raw: *mut T) -> Self {
// INVARIANT: Validity of `raw` is guaranteed by the safety preconditions of this function.
- // SAFETY: By the safety preconditions of this function, `raw` is not a NULL pointer.
+ // SAFETY: By the safety preconditions of this function, `raw` is not a NULL pointer and
+ // was allocated via `A` for `Layout::for_value::<T>()`.
Self(unsafe { NonNull::new_unchecked(raw) }, PhantomData)
}
--
2.53.0
On Wed Apr 1, 2026 at 12:58 PM CEST, David Rheinsberg wrote:
> Extend the safety requirements of `Box::from_raw()` to mention that the
> layout of the allocation must match exactly. Even though the underlying
> allocators maintain allocation layout information to some degree, the
> Rust abstraction strictly requires the layout to match exactly.
One additional general note on this. I've always been more against this
additional requirement of Allocator::free() compared to our existing kernel
allocators, but eventually agreed as there may also be advantages.
This is the first time it gets a little bit in our way, since technically
Vec::into_boxed_slice() only needs to call realloc() to fulfill the safety
requirement that comes from Allocator::free().
I will keep monitoring this, and if it turns out to have more disadvantages we
might want to change it.
> Suggested-by: Danilo Krummrich <dakr@kernel.org>
This should be:
Reported-by: Danilo Krummrich <dakr@kernel.org>
Closes: https://lore.kernel.org/all/DHCNOY4GFV7B.3VGGZNT3382L0@kernel.org/
Please also add a corresponding Fixes: tag.
> Signed-off-by: David Rheinsberg <david@readahead.eu>
> ---
> rust/kernel/alloc/kbox.rs | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
> index 622b3529edfc..1b30c51f87ab 100644
> --- a/rust/kernel/alloc/kbox.rs
> +++ b/rust/kernel/alloc/kbox.rs
> @@ -170,15 +170,16 @@ impl<T, A> Box<T, A>
> ///
> /// # Safety
> ///
> - /// For non-ZSTs, `raw` must point at an allocation allocated with `A` that is sufficiently
> - /// aligned for and holds a valid `T`. The caller passes ownership of the allocation to the
> - /// `Box`.
> + /// For non-ZSTs, `raw` must point at an allocation allocated with `A` with a layout
> + /// of `Layout::for_value::<T>()`. The caller passes ownership of the allocation
> + /// to the `Box`.
> ///
> /// For ZSTs, `raw` must be a dangling, well aligned pointer.
> #[inline]
> pub const unsafe fn from_raw(raw: *mut T) -> Self {
> // INVARIANT: Validity of `raw` is guaranteed by the safety preconditions of this function.
> - // SAFETY: By the safety preconditions of this function, `raw` is not a NULL pointer.
> + // SAFETY: By the safety preconditions of this function, `raw` is not a NULL pointer and
> + // was allocated via `A` for `Layout::for_value::<T>()`.
> Self(unsafe { NonNull::new_unchecked(raw) }, PhantomData)
> }
This looks good, but I think we also need this as a type invariant, can you
please add one?
© 2016 - 2026 Red Hat, Inc.