summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorMiguel Ojeda <ojeda@kernel.org>2022-12-13 21:03:55 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-02-06 10:06:34 +0300
commit60cd03ffe93839925d8d6b6c329e1f6550c69b07 (patch)
treefe0ed9053b732970e1dac9b211abe6616c1d6ea2 /rust
parent888dad6f3e85e3b2f8389bd6478f181efc72534d (diff)
downloadlinux-60cd03ffe93839925d8d6b6c329e1f6550c69b07.tar.xz
rust: print: avoid evaluating arguments in `pr_*` macros in `unsafe` blocks
commit 6618d69aa129a8fc613e64775d5019524c6f231b upstream. At the moment it is possible to perform unsafe operations in the arguments of `pr_*` macros since they are evaluated inside an `unsafe` block: let x = &10u32 as *const u32; pr_info!("{}", *x); In other words, this is a soundness issue. Fix it so that it requires an explicit `unsafe` block. Reported-by: Wedson Almeida Filho <wedsonaf@gmail.com> Reported-by: Domen Puncer Kugler <domen.puncerkugler@nccgroup.com> Link: https://github.com/Rust-for-Linux/linux/issues/479 Signed-off-by: Miguel Ojeda <ojeda@kernel.org> Reviewed-by: Boqun Feng <boqun.feng@gmail.com> Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Björn Roy Baron <bjorn3_gh@protonmail.com> Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'rust')
-rw-r--r--rust/kernel/print.rs29
1 files changed, 18 insertions, 11 deletions
diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs
index 55db5a1ba752..97ff086ba22e 100644
--- a/rust/kernel/print.rs
+++ b/rust/kernel/print.rs
@@ -115,17 +115,24 @@ pub unsafe fn call_printk(
macro_rules! print_macro (
// The non-continuation cases (most of them, e.g. `INFO`).
($format_string:path, $($arg:tt)+) => (
- // SAFETY: This hidden macro should only be called by the documented
- // printing macros which ensure the format string is one of the fixed
- // ones. All `__LOG_PREFIX`s are null-terminated as they are generated
- // by the `module!` proc macro or fixed values defined in a kernel
- // crate.
- unsafe {
- $crate::print::call_printk(
- &$format_string,
- crate::__LOG_PREFIX,
- format_args!($($arg)+),
- );
+ // To remain sound, `arg`s must be expanded outside the `unsafe` block.
+ // Typically one would use a `let` binding for that; however, `format_args!`
+ // takes borrows on the arguments, but does not extend the scope of temporaries.
+ // Therefore, a `match` expression is used to keep them around, since
+ // the scrutinee is kept until the end of the `match`.
+ match format_args!($($arg)+) {
+ // SAFETY: This hidden macro should only be called by the documented
+ // printing macros which ensure the format string is one of the fixed
+ // ones. All `__LOG_PREFIX`s are null-terminated as they are generated
+ // by the `module!` proc macro or fixed values defined in a kernel
+ // crate.
+ args => unsafe {
+ $crate::print::call_printk(
+ &$format_string,
+ crate::__LOG_PREFIX,
+ args,
+ );
+ }
}
);
);