rust: kernel: introduce `unsafe_precondition_assert!` macro
PATCH v2 1/1 rust: kernel: introduce `unsafe_precondition_assert!` macro
Introduce a new safety module containing unsafe_precondition_assert! macro. It is a wrapper around debug_assert!, intended for validating pre-conditions of unsafe function.
When CONFIG_RUST_DEBUG_ASSERTIONS flag is enabled, this macro performs runtime checks to ensure that the preconditions for unsafe function hold. Otherwise, the macro is a no-op.
---
Changes in v2:
- Wrap debug_assert! internally instead of using pr_err! with assert! + `cfg!(debug_assertions)
- Print “unsafe precondition(s) violated” only on assertion failure (no longer always printed)
- Use # Safety section instead of comment in the example
- Rename module-level doc
- Link to v1: https://lore.kernel.org/rust-for-linux/[email protected]/
--- rust/kernel/lib.rs | 1 + rust/kernel/safety.rs | 52 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 rust/kernel/safety.rs
rust/kernel/lib.rs +1 -0
@@ -104,6 +104,7 @@pub mod print;pub mod rbtree;pub mod revocable; +pub mod safety;pub mod security;pub mod seq_file;pub mod sizes;
rust/kernel/safety.rs new file +52 -0
52 lines not on this page · raw message
base-commit: dff64b072708ffef23c117fa1ee1ea59eb417807
Signature · 1 line
2.50.1
Gary Guo
reviewerQuoted 7 lines · On Wed, 30 Jul 2025 22:41:28 +0530 Ritvik Gupta <[email protected]> wrote:
Introduce a new
safetymodule containingunsafe_precondition_assert!macro. It is a wrapper arounddebug_assert!, intended for validating pre-conditions of unsafe function.When
CONFIG_RUST_DEBUG_ASSERTIONSflag is enabled, this macro performs runtime checks to ensure that the preconditions for unsafe function hold. Otherwise, the macro is a no-op.
This email should be include the Rust-for-Linux list.
Quoted 53 lines
Suggested-by Miguel Ojeda <[email protected]>Signed-off-by Ritvik Gupta <[email protected]>---
Changes in v2:
- Wrapdebug_assert!internally instead of usingpr_err!withassert!+ `cfg!(debug_assertions)
- Print “unsafe precondition(s) violated” only on assertion failure (no longer always printed)
- Use# Safetysection instead of comment in the example
- Rename module-level doc
- Link to v1: https://lore.kernel.org/rust-for-linux/[email protected]/--- rust/kernel/lib.rs | 1 + rust/kernel/safety.rs | 52 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 rust/kernel/safety.rsrust/kernel/lib.rs +1
-0@@ -104,6 +104,7 @@pub mod print;pub mod rbtree;pub mod revocable; +pub mod safety;pub mod security;pub mod seq_file;pub mod sizes;rust/kernel/safety.rs new file +15
-0@@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Safety related APIs. + +/// Checks that preconditions of an unsafe function are followed. +/// +/// The check is enabled at runtime if debug assertions (`CONFIG_RUST_DEBUG_ASSERTIONS`) +/// are enabled. Otherwise, this macro is no-op. +/// +/// # Examples +/// +/// ``` +/// /// # Safety +/// /// +/// /// The caller must ensure that interpreting the bytes of `[T; N]` as `[U; N]` is valid.
rust/kernel/safety.rs line 25
Quoted 10 lines
rust/kernel/safety.rs new file +10
-0+/// /// +/// /// This requires: +/// /// - `T` and `U` must have same size. +/// /// - The bit pattern of `T` must be valid for `U`. +/// /// - The alignment of `T` must be at least as strict as `U`. +/// unsafe fn transmute_array<const N: usize, T: Copy, U: Copy>(input: [T; N]) -> [U; N] { +/// unsafe_precondition_assert!( +/// core::mem::size_of::<T>() == core::mem::size_of::<U>(), +/// "src and dst must have the same size" +/// );
These can just be const { assert!() }? There's no reason for this to be runtime.
Best,
Gary
Quoted 29 lines
rust/kernel/safety.rs new file +27
-0+/// +/// unsafe_precondition_assert!( +/// core::mem::align_of::<T>() >= core::mem::align_of::<U>(), +/// "src alignment must be compatible with dst alignment" +/// ); +/// +/// unsafe { core::mem::transmute_copy(&input) } +/// } +/// ``` +/// +/// # Panics +/// +/// Panics if the expression is evaluated to `false` at runtime. +/// +#[macro_export] +macro_rules! unsafe_precondition_assert { + ($cond:expr $(,)?) => { + $crate::unsafe_precondition_assert!(@inner $cond, ::core::stringify!($cond)) + }; + + ($cond:expr, $($arg:tt)+) => { + $crate::unsafe_precondition_assert!(@inner $cond, ::core::format_args!($($arg)+)) + }; + + (@inner $cond:expr, $msg:expr) => { + ::core::debug_assert!($cond,"unsafe precondition(s) violated: {}" , $msg) }; +}base-commit:
dff64b072708ffef23c117fa1ee1ea59eb417807
Quoted 1 line
This email should be include the Rust-for-Linux list.
Apologies for oversight.
Automated it to prevent in future :)
Quoted 2 lines
These can just be
const { assert!() }? There's no reason for this to be runtime.
Yeah! static_assert! makes sense here.
I'll add more relevant example in v3.
Thanks for the feedback :)