Skip to content

Commit 6618d69

Browse files
committed
rust: print: avoid evaluating arguments in pr_* macros in unsafe blocks
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 <[email protected]> Reported-by: Domen Puncer Kugler <[email protected]> Link: #479 Signed-off-by: Miguel Ojeda <[email protected]> Reviewed-by: Boqun Feng <[email protected]> Reviewed-by: Gary Guo <[email protected]> Reviewed-by: Björn Roy Baron <[email protected]> Reviewed-by: Vincenzo Palazzo <[email protected]>
1 parent 5dc4c99 commit 6618d69

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

rust/kernel/print.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,24 @@ pub fn call_printk_cont(args: fmt::Arguments<'_>) {
142142
macro_rules! print_macro (
143143
// The non-continuation cases (most of them, e.g. `INFO`).
144144
($format_string:path, false, $($arg:tt)+) => (
145-
// SAFETY: This hidden macro should only be called by the documented
146-
// printing macros which ensure the format string is one of the fixed
147-
// ones. All `__LOG_PREFIX`s are null-terminated as they are generated
148-
// by the `module!` proc macro or fixed values defined in a kernel
149-
// crate.
150-
unsafe {
151-
$crate::print::call_printk(
152-
&$format_string,
153-
crate::__LOG_PREFIX,
154-
format_args!($($arg)+),
155-
);
145+
// To remain sound, `arg`s must be expanded outside the `unsafe` block.
146+
// Typically one would use a `let` binding for that; however, `format_args!`
147+
// takes borrows on the arguments, but does not extend the scope of temporaries.
148+
// Therefore, a `match` expression is used to keep them around, since
149+
// the scrutinee is kept until the end of the `match`.
150+
match format_args!($($arg)+) {
151+
// SAFETY: This hidden macro should only be called by the documented
152+
// printing macros which ensure the format string is one of the fixed
153+
// ones. All `__LOG_PREFIX`s are null-terminated as they are generated
154+
// by the `module!` proc macro or fixed values defined in a kernel
155+
// crate.
156+
args => unsafe {
157+
$crate::print::call_printk(
158+
&$format_string,
159+
crate::__LOG_PREFIX,
160+
args,
161+
);
162+
}
156163
}
157164
);
158165

0 commit comments

Comments
 (0)