Message ID | 20230109204912.539790-1-ojeda@kernel.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp2373423wrt; Mon, 9 Jan 2023 12:51:26 -0800 (PST) X-Google-Smtp-Source: AMrXdXvpOeHvf+4dPTvgspV66foIJ3c1u32lks6xRBKc5F+Sht4cTFE7sMSeV4qTE4yUv55StXYJ X-Received: by 2002:a05:6a20:1029:b0:b5:d50a:4aad with SMTP id a41-20020a056a20102900b000b5d50a4aadmr6659907pzd.39.1673297485997; Mon, 09 Jan 2023 12:51:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673297485; cv=none; d=google.com; s=arc-20160816; b=rmDeV+FLnEltzwlh3tnS0WiWXCxdl+8ahbQ8Ke3a+1zEr5jeLXuHp9wPwkUFk2tYS0 sGo48dAd+R8f5QwgZtr0WS6SqSL4kiId4wuccGfFVnCHdHxJdwMKMN5GMtwwCIXuDI2R aFz2J+glScyEku3xLZHZxabVtdyEgNhEEgFDH8mjGoGuV6PinTalIMDXWUWjSgRvq1C0 R00JurhTlzb+sOTvB7T7lm4aBd2Og5pYGIakYJx/wyHeOrFlVzpF6bw9nzN4gCiRszmu d2rJx0uYHd6TLaVOVc7XcDlV7iY7imoRwkBLiBi0eXxOcsJmx9jg5nJ2rt8mHcoPK3HU eMsg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=NUcehdDxpEo+pQkTYlOZslYx2489zhpCv1HcOF64Zlw=; b=kdiUnrPvsjIf0eV02AE4PIOuom4PWeMsz/VeAIdv+fi0ZpgrwjsBfQ0hyAyH420RrQ CQn9jyfA8wRJkBi/il+acYEhUyGaf8lHAna2ZT0Lmkw9zCoMd6KyGBzH129u68ip5oac +q5iRPtrko29UDd3OhGvf4Jv4V7m2xLpiRy4jIsbAvAXmHvDJqmrvAe62WA2fZbj/JP2 r6XDEOo4pc/S4jl2kEd9B8ZdBElFo/PYIlY1xRUgH5ffWzT0hRUkM46qyP++tSqc1+6P sWw0ix/Dp4ECAZrVlTt17BNnF2sj/j2Osq72P7oScH7j4RIQDsIDLC4ncT+/aFtD+nXz BgxQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=tcY6SHNY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id v8-20020a63bf08000000b00477bf7b0c43si107430pgf.458.2023.01.09.12.51.13; Mon, 09 Jan 2023 12:51:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=tcY6SHNY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235188AbjAIUtn (ORCPT <rfc822;syz17693488234@gmail.com> + 99 others); Mon, 9 Jan 2023 15:49:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58410 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237453AbjAIUta (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Mon, 9 Jan 2023 15:49:30 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2008071FD4; Mon, 9 Jan 2023 12:49:28 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id AF5C861378; Mon, 9 Jan 2023 20:49:27 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C6196C433EF; Mon, 9 Jan 2023 20:49:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673297367; bh=ZCpIfx/6UP52Vxj4R4wUhX+SXLNpHxh2VEnEZXQEJdM=; h=From:To:Cc:Subject:Date:From; b=tcY6SHNYWtmLB7FfBUj4VIUl8tjXhVpGGlMeqPQf0JkAo0Kz4SNiRNCFi1xgl8muN EC9vmwUiEY2A5JYQEJfBeVvfVpePlc7bSmmSqMsMYNDbTfMwZAhO8oL5saDewrCc40 jdIwxVYtEA2W+7RSdmMVl5xfL92AWlbBhVgV7tdaFdt/qcwlJsqLimQCyhh4vnOqga DiE3NfjcmTDjajypQXosYv9zXvkrou0I5DG1DB/ubeYXRTZg4m6fC0io6ompOMzdMe KjymdCJ2KpPz/bolKYNvvTobcxp3L6tUK1JD4rGiGK3EVAeuGfNdg1RMHKTcrBqjkH KCniDREGSE6FQ== From: Miguel Ojeda <ojeda@kernel.org> To: Wedson Almeida Filho <wedsonaf@gmail.com>, Alex Gaynor <alex.gaynor@gmail.com>, Boqun Feng <boqun.feng@gmail.com>, Gary Guo <gary@garyguo.net>, =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= <bjorn3_gh@protonmail.com> Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>, Domen Puncer Kugler <domen.puncerkugler@nccgroup.com> Subject: [PATCH] rust: print: avoid evaluating arguments in `pr_*` macros in `unsafe` blocks Date: Mon, 9 Jan 2023 21:49:12 +0100 Message-Id: <20230109204912.539790-1-ojeda@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1754579584515659710?= X-GMAIL-MSGID: =?utf-8?q?1754579584515659710?= |
Series |
rust: print: avoid evaluating arguments in `pr_*` macros in `unsafe` blocks
|
|
Commit Message
Miguel Ojeda
Jan. 9, 2023, 8:49 p.m. UTC
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>
---
rust/kernel/print.rs | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
base-commit: b7bfaa761d760e72a969d116517eaa12e404c262
Comments
On Mon, Jan 09, 2023 at 09:49:12PM +0100, Miguel Ojeda wrote: > 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> > --- > rust/kernel/print.rs | 29 ++++++++++++++++++----------- > 1 file changed, 18 insertions(+), 11 deletions(-) > > diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs > index 29bf9c2e8aee..30103325696d 100644 > --- a/rust/kernel/print.rs > +++ b/rust/kernel/print.rs > @@ -142,17 +142,24 @@ pub fn call_printk_cont(args: fmt::Arguments<'_>) { > macro_rules! print_macro ( > // The non-continuation cases (most of them, e.g. `INFO`). > ($format_string:path, false, $($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, > + ); > + } > } > ); > > > base-commit: b7bfaa761d760e72a969d116517eaa12e404c262 > -- > 2.39.0 >
On Mon, 9 Jan 2023 21:49:12 +0100 Miguel Ojeda <ojeda@kernel.org> wrote: > 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: Gary Guo <gary@garyguo.net> > --- > rust/kernel/print.rs | 29 ++++++++++++++++++----------- > 1 file changed, 18 insertions(+), 11 deletions(-) > > diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs > index 29bf9c2e8aee..30103325696d 100644 > --- a/rust/kernel/print.rs > +++ b/rust/kernel/print.rs > @@ -142,17 +142,24 @@ pub fn call_printk_cont(args: fmt::Arguments<'_>) { > macro_rules! print_macro ( > // The non-continuation cases (most of them, e.g. `INFO`). > ($format_string:path, false, $($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, > + ); > + } > } > ); > > > base-commit: b7bfaa761d760e72a969d116517eaa12e404c262
On Monday, January 9th, 2023 at 21:49, Miguel Ojeda <ojeda@kernel.org> wrote: > 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: Björn Roy Baron <bjorn3_gh@protonmail.com> > --- > rust/kernel/print.rs | 29 ++++++++++++++++++----------- > 1 file changed, 18 insertions(+), 11 deletions(-) > > diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs > index 29bf9c2e8aee..30103325696d 100644 > --- a/rust/kernel/print.rs > +++ b/rust/kernel/print.rs > @@ -142,17 +142,24 @@ pub fn call_printk_cont(args: fmt::Arguments<'_>) { > macro_rules! print_macro ( > // The non-continuation cases (most of them, e.g. `INFO`). > ($format_string:path, false, $($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, > + ); > + } > } > ); > > > base-commit: b7bfaa761d760e72a969d116517eaa12e404c262 > -- > 2.39.0
On Mon Jan 9, 2023 at 9:49 PM CET, Miguel Ojeda wrote: > 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: Vincenzo Palazzo <vincenzopalazzodev@gmail.com> > --- > rust/kernel/print.rs | 29 ++++++++++++++++++----------- > 1 file changed, 18 insertions(+), 11 deletions(-) > > diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs > index 29bf9c2e8aee..30103325696d 100644 > --- a/rust/kernel/print.rs > +++ b/rust/kernel/print.rs > @@ -142,17 +142,24 @@ pub fn call_printk_cont(args: fmt::Arguments<'_>) { > macro_rules! print_macro ( > // The non-continuation cases (most of them, e.g. `INFO`). > ($format_string:path, false, $($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, > + ); > + } > } > ); > > > base-commit: b7bfaa761d760e72a969d116517eaa12e404c262 > -- > 2.39.0
On Mon, Jan 9, 2023 at 9:49 PM Miguel Ojeda <ojeda@kernel.org> wrote: > > 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> Applied to rust-fixes, thanks all! Cheers, Miguel
diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs index 29bf9c2e8aee..30103325696d 100644 --- a/rust/kernel/print.rs +++ b/rust/kernel/print.rs @@ -142,17 +142,24 @@ pub fn call_printk_cont(args: fmt::Arguments<'_>) { macro_rules! print_macro ( // The non-continuation cases (most of them, e.g. `INFO`). ($format_string:path, false, $($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, + ); + } } );