Skip to content

Commit 2a90d87

Browse files
Fix soundness issue with container_of! macro
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 <[email protected]>
1 parent 38512f6 commit 2a90d87

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

rust/kernel/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ macro_rules! offset_of {
197197
/// # Safety
198198
///
199199
/// Callers must ensure that the pointer to the field is in fact a pointer to the specified field,
200-
/// as opposed to a pointer to another object of the same type.
200+
/// as opposed to a pointer to another object of the same type. If this condition is not met,
201+
/// any dereference of the resulting pointer is UB.
201202
///
202203
/// # Example
203204
///
@@ -212,7 +213,7 @@ macro_rules! offset_of {
212213
/// fn test() {
213214
/// let test = Test { a: 10, b: 20 };
214215
/// let b_ptr = &test.b;
215-
/// let test_alias = unsafe { container_of!(b_ptr, Test, b) };
216+
/// let test_alias = container_of!(b_ptr, Test, b);
216217
/// // This prints `true`.
217218
/// pr_info!("{}\n", core::ptr::eq(&test, test_alias));
218219
/// }
@@ -222,6 +223,6 @@ macro_rules! container_of {
222223
($ptr:expr, $type:ty, $($f:tt)*) => {{
223224
let ptr = $ptr as *const _ as *const u8;
224225
let offset = $crate::offset_of!($type, $($f)*);
225-
unsafe { ptr.offset(-offset) as *const $type }
226+
ptr.wrapping_offset(-offset) as *const $type
226227
}}
227228
}

0 commit comments

Comments
 (0)