From 2a90d874c3acc834a08fb3407c653de2f08d069a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lanteri=20Thauvin?= Date: Sat, 31 Jul 2021 22:23:38 +0200 Subject: [PATCH] Fix soundness issue with `container_of!` macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously it was possible to trigger UB from safe code using the `container_of!` macro. For example: ```rust struct Foo { a: (), } fn main() { container_of!(core::ptr::null(), Foo, a); // UB } ``` Using `wrapping_offset` instead of `offset` makes the macro safe to call for any input. Signed-off-by: Léo Lanteri Thauvin --- rust/kernel/lib.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 0733f325cc7184..226af02dc825a8 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -197,7 +197,8 @@ macro_rules! offset_of { /// # Safety /// /// Callers must ensure that the pointer to the field is in fact a pointer to the specified field, -/// as opposed to a pointer to another object of the same type. +/// as opposed to a pointer to another object of the same type. If this condition is not met, +/// any dereference of the resulting pointer is UB. /// /// # Example /// @@ -212,7 +213,7 @@ macro_rules! offset_of { /// fn test() { /// let test = Test { a: 10, b: 20 }; /// let b_ptr = &test.b; -/// let test_alias = unsafe { container_of!(b_ptr, Test, b) }; +/// let test_alias = container_of!(b_ptr, Test, b); /// // This prints `true`. /// pr_info!("{}\n", core::ptr::eq(&test, test_alias)); /// } @@ -222,6 +223,6 @@ macro_rules! container_of { ($ptr:expr, $type:ty, $($f:tt)*) => {{ let ptr = $ptr as *const _ as *const u8; let offset = $crate::offset_of!($type, $($f)*); - unsafe { ptr.offset(-offset) as *const $type } + ptr.wrapping_offset(-offset) as *const $type }} }