* [PATCH v2 1/6] rust: module: add static pointer to `{init,cleanup}_module()`
2024-07-24 16:14 [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool` Miguel Ojeda
@ 2024-07-24 16:14 ` Miguel Ojeda
2024-07-24 19:46 ` Gary Guo
2024-07-24 16:14 ` [PATCH v2 2/6] x86/rust: support MITIGATION_RETPOLINE Miguel Ojeda
` (7 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: Miguel Ojeda @ 2024-07-24 16:14 UTC (permalink / raw)
To: Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada
Cc: x86, H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Miguel Ojeda, Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, rust-for-linux, linux-kernel, patches
Add the equivalent of the `___ADDRESSABLE()` annotation in the
`module_{init,exit}` macros to the Rust `module!` macro.
Without this, `objtool` would complain if enabled for Rust, e.g.:
samples/rust/rust_print.o: warning: objtool: cleanup_module(): not an indirect call target
samples/rust/rust_print.o: warning: objtool: init_module(): not an indirect call target
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
rust/macros/module.rs | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/rust/macros/module.rs b/rust/macros/module.rs
index 411dc103d82e..571ffa2e189c 100644
--- a/rust/macros/module.rs
+++ b/rust/macros/module.rs
@@ -256,6 +256,12 @@ mod __module_init {{
unsafe {{ __init() }}
}}
+ #[cfg(MODULE)]
+ #[doc(hidden)]
+ #[used]
+ #[link_section = \".init.data\"]
+ static __UNIQUE_ID___addressable_init_module: unsafe extern \"C\" fn() -> i32 = init_module;
+
#[cfg(MODULE)]
#[doc(hidden)]
#[no_mangle]
@@ -269,6 +275,12 @@ mod __module_init {{
unsafe {{ __exit() }}
}}
+ #[cfg(MODULE)]
+ #[doc(hidden)]
+ #[used]
+ #[link_section = \".exit.data\"]
+ static __UNIQUE_ID___addressable_cleanup_module: extern \"C\" fn() = cleanup_module;
+
// Built-in modules are initialized through an initcall pointer
// and the identifiers need to be unique.
#[cfg(not(MODULE))]
--
2.45.2
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH v2 1/6] rust: module: add static pointer to `{init,cleanup}_module()`
2024-07-24 16:14 ` [PATCH v2 1/6] rust: module: add static pointer to `{init,cleanup}_module()` Miguel Ojeda
@ 2024-07-24 19:46 ` Gary Guo
2024-07-25 17:44 ` Miguel Ojeda
2024-07-25 17:47 ` Miguel Ojeda
0 siblings, 2 replies; 22+ messages in thread
From: Gary Guo @ 2024-07-24 19:46 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada, x86,
H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
rust-for-linux, linux-kernel, patches
On Wed, 24 Jul 2024 18:14:54 +0200
Miguel Ojeda <ojeda@kernel.org> wrote:
> Add the equivalent of the `___ADDRESSABLE()` annotation in the
> `module_{init,exit}` macros to the Rust `module!` macro.
>
> Without this, `objtool` would complain if enabled for Rust, e.g.:
>
> samples/rust/rust_print.o: warning: objtool: cleanup_module(): not an indirect call target
> samples/rust/rust_print.o: warning: objtool: init_module(): not an indirect call target
>
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> ---
> rust/macros/module.rs | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/rust/macros/module.rs b/rust/macros/module.rs
> index 411dc103d82e..571ffa2e189c 100644
> --- a/rust/macros/module.rs
> +++ b/rust/macros/module.rs
> @@ -256,6 +256,12 @@ mod __module_init {{
> unsafe {{ __init() }}
> }}
>
> + #[cfg(MODULE)]
> + #[doc(hidden)]
> + #[used]
> + #[link_section = \".init.data\"]
Should this be in section `.discard.addressable` instead?
> + static __UNIQUE_ID___addressable_init_module: unsafe extern \"C\" fn() -> i32 = init_module;
> +
> #[cfg(MODULE)]
> #[doc(hidden)]
> #[no_mangle]
> @@ -269,6 +275,12 @@ mod __module_init {{
> unsafe {{ __exit() }}
> }}
>
> + #[cfg(MODULE)]
> + #[doc(hidden)]
> + #[used]
> + #[link_section = \".exit.data\"]
> + static __UNIQUE_ID___addressable_cleanup_module: extern \"C\" fn() = cleanup_module;
> +
> // Built-in modules are initialized through an initcall pointer
> // and the identifiers need to be unique.
> #[cfg(not(MODULE))]
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: Re: [PATCH v2 1/6] rust: module: add static pointer to `{init,cleanup}_module()`
2024-07-24 19:46 ` Gary Guo
@ 2024-07-25 17:44 ` Miguel Ojeda
2024-07-25 17:46 ` Miguel Ojeda
2024-07-25 17:47 ` Miguel Ojeda
1 sibling, 1 reply; 22+ messages in thread
From: Miguel Ojeda @ 2024-07-25 17:44 UTC (permalink / raw)
To: gary
Cc: a.hindborg, alex.gaynor, aliceryhl, benno.lossin, bjorn3_gh,
boqun.feng, bp, dave.hansen, hpa, jpoimboe, linux-kernel,
masahiroy, mingo, nathan, nicolas, ojeda, patches, peterz,
rust-for-linux, tglx, wedsonaf, x86
On Wed, 24 Jul 2024 20:46:49 +0100 Gary Guo <gary@garyguo.net> wrote:
>
> On Wed, 24 Jul 2024 18:14:54 +0200
> Miguel Ojeda <ojeda@kernel.org> wrote:
>
> > Add the equivalent of the `___ADDRESSABLE()` annotation in the
> > `module_{init,exit}` macros to the Rust `module!` macro.
> >
> > Without this, `objtool` would complain if enabled for Rust, e.g.:
> >
> > samples/rust/rust_print.o: warning: objtool: cleanup_module(): not an indirect call target
> > samples/rust/rust_print.o: warning: objtool: init_module(): not an indirect call target
> >
> > Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> > ---
> > rust/macros/module.rs | 12 ++++++++++++
> > 1 file changed, 12 insertions(+)
> >
> > diff --git a/rust/macros/module.rs b/rust/macros/module.rs
> > index 411dc103d82e..571ffa2e189c 100644
> > --- a/rust/macros/module.rs
> > +++ b/rust/macros/module.rs
> > @@ -256,6 +256,12 @@ mod __module_init {{
> > unsafe {{ __init() }}
> > }}
> >
> > + #[cfg(MODULE)]
> > + #[doc(hidden)]
> > + #[used]
> > + #[link_section = \".init.data\"]
>
> Should this be in section `.discard.addressable` instead?
>
> > + static __UNIQUE_ID___addressable_init_module: unsafe extern \"C\" fn() -> i32 = init_module;
> > +
> > #[cfg(MODULE)]
> > #[doc(hidden)]
> > #[no_mangle]
> > @@ -269,6 +275,12 @@ mod __module_init {{
> > unsafe {{ __exit() }}
> > }}
> >
> > + #[cfg(MODULE)]
> > + #[doc(hidden)]
> > + #[used]
> > + #[link_section = \".exit.data\"]
> > + static __UNIQUE_ID___addressable_cleanup_module: extern \"C\" fn() = cleanup_module;
> > +
> > // Built-in modules are initialized through an initcall pointer
> > // and the identifiers need to be unique.
> > #[cfg(not(MODULE))]
Boot-tested under QEMU for Rust:
Tested-by: Miguel Ojeda <ojeda@kernel.org>
Thanks!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: Re: [PATCH v2 1/6] rust: module: add static pointer to `{init,cleanup}_module()`
2024-07-25 17:44 ` Miguel Ojeda
@ 2024-07-25 17:46 ` Miguel Ojeda
0 siblings, 0 replies; 22+ messages in thread
From: Miguel Ojeda @ 2024-07-25 17:46 UTC (permalink / raw)
To: Miguel Ojeda
Cc: gary, a.hindborg, alex.gaynor, aliceryhl, benno.lossin, bjorn3_gh,
boqun.feng, bp, dave.hansen, hpa, jpoimboe, linux-kernel,
masahiroy, mingo, nathan, nicolas, patches, peterz,
rust-for-linux, tglx, wedsonaf, x86
On Thu, Jul 25, 2024 at 7:45 PM Miguel Ojeda <ojeda@kernel.org> wrote:
>
> Boot-tested under QEMU for Rust:
Sorry, please ignore this message. I run a script of mine badly... :)
Cheers,
Miguel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: Re: [PATCH v2 1/6] rust: module: add static pointer to `{init,cleanup}_module()`
2024-07-24 19:46 ` Gary Guo
2024-07-25 17:44 ` Miguel Ojeda
@ 2024-07-25 17:47 ` Miguel Ojeda
2024-07-30 11:18 ` Gary Guo
1 sibling, 1 reply; 22+ messages in thread
From: Miguel Ojeda @ 2024-07-25 17:47 UTC (permalink / raw)
To: gary
Cc: a.hindborg, alex.gaynor, aliceryhl, benno.lossin, bjorn3_gh,
boqun.feng, bp, dave.hansen, hpa, jpoimboe, linux-kernel,
masahiroy, mingo, nathan, nicolas, ojeda, patches, peterz,
rust-for-linux, tglx, wedsonaf, x86
On Wed, 24 Jul 2024 20:46:49 +0100 Gary Guo <gary@garyguo.net> wrote:
>
> Should this be in section `.discard.addressable` instead?
No, we need to mimic the call to `___ADDRESSABLE()` (i.e. the one with
3 underscores, not 2), which passes `__{init,exit}data`.
By the way, thanks for the reviews Gary!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH v2 1/6] rust: module: add static pointer to `{init,cleanup}_module()`
2024-07-25 17:47 ` Miguel Ojeda
@ 2024-07-30 11:18 ` Gary Guo
0 siblings, 0 replies; 22+ messages in thread
From: Gary Guo @ 2024-07-30 11:18 UTC (permalink / raw)
To: Miguel Ojeda
Cc: a.hindborg, alex.gaynor, aliceryhl, benno.lossin, bjorn3_gh,
boqun.feng, bp, dave.hansen, hpa, jpoimboe, linux-kernel,
masahiroy, mingo, nathan, nicolas, patches, peterz,
rust-for-linux, tglx, wedsonaf, x86
On Thu, 25 Jul 2024 19:47:13 +0200
Miguel Ojeda <ojeda@kernel.org> wrote:
> On Wed, 24 Jul 2024 20:46:49 +0100 Gary Guo <gary@garyguo.net> wrote:
> >
> > Should this be in section `.discard.addressable` instead?
>
> No, we need to mimic the call to `___ADDRESSABLE()` (i.e. the one with
> 3 underscores, not 2), which passes `__{init,exit}data`.
>
> By the way, thanks for the reviews Gary!
>
> Cheers,
> Miguel
You're right. It's a bit difficult to navigate macros :)
In this case I think this indeed matches the C implementation.
Reviewed-by: Gary Guo <gary@garyguo.net>
Thanks,
Gary
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 2/6] x86/rust: support MITIGATION_RETPOLINE
2024-07-24 16:14 [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool` Miguel Ojeda
2024-07-24 16:14 ` [PATCH v2 1/6] rust: module: add static pointer to `{init,cleanup}_module()` Miguel Ojeda
@ 2024-07-24 16:14 ` Miguel Ojeda
2024-07-24 19:38 ` Gary Guo
2024-07-24 16:14 ` [PATCH v2 3/6] x86/rust: support MITIGATION_RETHUNK Miguel Ojeda
` (6 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: Miguel Ojeda @ 2024-07-24 16:14 UTC (permalink / raw)
To: Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada
Cc: x86, H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Miguel Ojeda, Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, rust-for-linux, linux-kernel, patches,
Daniel Borkmann
Support `MITIGATION_RETPOLINE` by enabling the target features that
Clang does.
The existing target feature being enabled was a leftover from
our old `rust` branch, and it is not enough: the target feature
`retpoline-external-thunk` only implies `retpoline-indirect-calls`, but
not `retpoline-indirect-branches` (see LLVM's `X86.td`), unlike Clang's
flag of the same name `-mretpoline-external-thunk` which does imply both
(see Clang's `lib/Driver/ToolChains/Arch/X86.cpp`).
Without this, `objtool` would complain if enabled for Rust, e.g.:
rust/core.o: warning: objtool:
_R...escape_default+0x13: indirect jump found in RETPOLINE build
In addition, change the comment to note that LLVM is the one disabling
jump tables when retpoline is enabled, thus we do not need to use
`-Zno-jump-tables` for Rust here -- see commit c58f2166ab39 ("Introduce
the "retpoline" x86 mitigation technique ...") [1]:
The goal is simple: avoid generating code which contains an indirect
branch that could have its prediction poisoned by an attacker. In
many cases, the compiler can simply use directed conditional
branches and a small search tree. LLVM already has support for
lowering switches in this way and the first step of this patch is
to disable jump-table lowering of switches and introduce a pass to
rewrite explicit indirectbr sequences into a switch over integers.
As well as a live example at [2].
These should be eventually enabled via `-Ctarget-feature` when `rustc`
starts recognizing them (or via a new dedicated flag) [3].
Cc: Daniel Borkmann <daniel@iogearbox.net>
Link: https://github.com/llvm/llvm-project/commit/c58f2166ab3987f37cb0d7815b561bff5a20a69a [1]
Link: https://godbolt.org/z/G4YPr58qG [2]
Link: https://github.com/rust-lang/rust/issues/116852 [3]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
arch/x86/Makefile | 2 +-
scripts/generate_rust_target.rs | 7 +++++++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 801fd85c3ef6..e8214bff1aeb 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -220,7 +220,7 @@ ifdef CONFIG_MITIGATION_RETPOLINE
KBUILD_CFLAGS += $(RETPOLINE_CFLAGS)
# Additionally, avoid generating expensive indirect jumps which
# are subject to retpolines for small number of switch cases.
- # clang turns off jump table generation by default when under
+ # LLVM turns off jump table generation by default when under
# retpoline builds, however, gcc does not for x86. This has
# only been fixed starting from gcc stable version 8.4.0 and
# onwards, but not for older ones. See gcc bug #86952.
diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
index 641b713a033a..44952f0a3aac 100644
--- a/scripts/generate_rust_target.rs
+++ b/scripts/generate_rust_target.rs
@@ -164,7 +164,14 @@ fn main() {
);
let mut features = "-3dnow,-3dnowa,-mmx,+soft-float".to_string();
if cfg.has("MITIGATION_RETPOLINE") {
+ // The kernel uses `-mretpoline-external-thunk` (for Clang), which Clang maps to the
+ // target feature of the same name plus the other two target features in
+ // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via
+ // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated
+ // flag); see https://github.com/rust-lang/rust/issues/116852.
features += ",+retpoline-external-thunk";
+ features += ",+retpoline-indirect-branches";
+ features += ",+retpoline-indirect-calls";
}
ts.push("features", features);
ts.push("llvm-target", "x86_64-linux-gnu");
--
2.45.2
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH v2 2/6] x86/rust: support MITIGATION_RETPOLINE
2024-07-24 16:14 ` [PATCH v2 2/6] x86/rust: support MITIGATION_RETPOLINE Miguel Ojeda
@ 2024-07-24 19:38 ` Gary Guo
0 siblings, 0 replies; 22+ messages in thread
From: Gary Guo @ 2024-07-24 19:38 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada, x86,
H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
rust-for-linux, linux-kernel, patches, Daniel Borkmann
On Wed, 24 Jul 2024 18:14:55 +0200
Miguel Ojeda <ojeda@kernel.org> wrote:
> Support `MITIGATION_RETPOLINE` by enabling the target features that
> Clang does.
>
> The existing target feature being enabled was a leftover from
> our old `rust` branch, and it is not enough: the target feature
> `retpoline-external-thunk` only implies `retpoline-indirect-calls`, but
> not `retpoline-indirect-branches` (see LLVM's `X86.td`), unlike Clang's
> flag of the same name `-mretpoline-external-thunk` which does imply both
> (see Clang's `lib/Driver/ToolChains/Arch/X86.cpp`).
>
> Without this, `objtool` would complain if enabled for Rust, e.g.:
>
> rust/core.o: warning: objtool:
> _R...escape_default+0x13: indirect jump found in RETPOLINE build
>
> In addition, change the comment to note that LLVM is the one disabling
> jump tables when retpoline is enabled, thus we do not need to use
> `-Zno-jump-tables` for Rust here -- see commit c58f2166ab39 ("Introduce
> the "retpoline" x86 mitigation technique ...") [1]:
>
> The goal is simple: avoid generating code which contains an indirect
> branch that could have its prediction poisoned by an attacker. In
> many cases, the compiler can simply use directed conditional
> branches and a small search tree. LLVM already has support for
> lowering switches in this way and the first step of this patch is
> to disable jump-table lowering of switches and introduce a pass to
> rewrite explicit indirectbr sequences into a switch over integers.
>
> As well as a live example at [2].
>
> These should be eventually enabled via `-Ctarget-feature` when `rustc`
> starts recognizing them (or via a new dedicated flag) [3].
>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Link: https://github.com/llvm/llvm-project/commit/c58f2166ab3987f37cb0d7815b561bff5a20a69a [1]
> Link: https://godbolt.org/z/G4YPr58qG [2]
> Link: https://github.com/rust-lang/rust/issues/116852 [3]
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
> ---
> arch/x86/Makefile | 2 +-
> scripts/generate_rust_target.rs | 7 +++++++
> 2 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/Makefile b/arch/x86/Makefile
> index 801fd85c3ef6..e8214bff1aeb 100644
> --- a/arch/x86/Makefile
> +++ b/arch/x86/Makefile
> @@ -220,7 +220,7 @@ ifdef CONFIG_MITIGATION_RETPOLINE
> KBUILD_CFLAGS += $(RETPOLINE_CFLAGS)
> # Additionally, avoid generating expensive indirect jumps which
> # are subject to retpolines for small number of switch cases.
> - # clang turns off jump table generation by default when under
> + # LLVM turns off jump table generation by default when under
> # retpoline builds, however, gcc does not for x86. This has
> # only been fixed starting from gcc stable version 8.4.0 and
> # onwards, but not for older ones. See gcc bug #86952.
> diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
> index 641b713a033a..44952f0a3aac 100644
> --- a/scripts/generate_rust_target.rs
> +++ b/scripts/generate_rust_target.rs
> @@ -164,7 +164,14 @@ fn main() {
> );
> let mut features = "-3dnow,-3dnowa,-mmx,+soft-float".to_string();
> if cfg.has("MITIGATION_RETPOLINE") {
> + // The kernel uses `-mretpoline-external-thunk` (for Clang), which Clang maps to the
> + // target feature of the same name plus the other two target features in
> + // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via
> + // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated
> + // flag); see https://github.com/rust-lang/rust/issues/116852.
> features += ",+retpoline-external-thunk";
> + features += ",+retpoline-indirect-branches";
> + features += ",+retpoline-indirect-calls";
> }
> ts.push("features", features);
> ts.push("llvm-target", "x86_64-linux-gnu");
> --
> 2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 3/6] x86/rust: support MITIGATION_RETHUNK
2024-07-24 16:14 [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool` Miguel Ojeda
2024-07-24 16:14 ` [PATCH v2 1/6] rust: module: add static pointer to `{init,cleanup}_module()` Miguel Ojeda
2024-07-24 16:14 ` [PATCH v2 2/6] x86/rust: support MITIGATION_RETPOLINE Miguel Ojeda
@ 2024-07-24 16:14 ` Miguel Ojeda
2024-07-24 19:40 ` Gary Guo
2024-07-24 16:14 ` [PATCH v2 4/6] x86/rust: support MITIGATION_SLS Miguel Ojeda
` (5 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: Miguel Ojeda @ 2024-07-24 16:14 UTC (permalink / raw)
To: Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada
Cc: x86, H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Miguel Ojeda, Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, rust-for-linux, linux-kernel, patches
The Rust compiler added support for `-Zfunction-return=thunk-extern` [1]
in 1.76.0 [2], i.e. the equivalent of `-mfunction-return=thunk-extern`.
Thus add support for `MITIGATION_RETHUNK`.
Without this, `objtool` would warn if enabled for Rust and already warns
under IBT builds, e.g.:
samples/rust/rust_print.o: warning: objtool:
_R...init+0xa5c: 'naked' return found in RETHUNK build
Link: https://github.com/rust-lang/rust/issues/116853 [1]
Link: https://github.com/rust-lang/rust/pull/116892 [2]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
arch/x86/Makefile | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index e8214bff1aeb..a1883a30a5d8 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -24,11 +24,15 @@ RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix)
ifdef CONFIG_MITIGATION_RETHUNK
RETHUNK_CFLAGS := -mfunction-return=thunk-extern
+RETHUNK_RUSTFLAGS := -Zfunction-return=thunk-extern
RETPOLINE_CFLAGS += $(RETHUNK_CFLAGS)
+RETPOLINE_RUSTFLAGS += $(RETHUNK_RUSTFLAGS)
endif
export RETHUNK_CFLAGS
+export RETHUNK_RUSTFLAGS
export RETPOLINE_CFLAGS
+export RETPOLINE_RUSTFLAGS
export RETPOLINE_VDSO_CFLAGS
# For gcc stack alignment is specified with -mpreferred-stack-boundary,
@@ -218,6 +222,7 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
# Avoid indirect branches in kernel to deal with Spectre
ifdef CONFIG_MITIGATION_RETPOLINE
KBUILD_CFLAGS += $(RETPOLINE_CFLAGS)
+ KBUILD_RUSTFLAGS += $(RETPOLINE_RUSTFLAGS)
# Additionally, avoid generating expensive indirect jumps which
# are subject to retpolines for small number of switch cases.
# LLVM turns off jump table generation by default when under
--
2.45.2
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH v2 3/6] x86/rust: support MITIGATION_RETHUNK
2024-07-24 16:14 ` [PATCH v2 3/6] x86/rust: support MITIGATION_RETHUNK Miguel Ojeda
@ 2024-07-24 19:40 ` Gary Guo
0 siblings, 0 replies; 22+ messages in thread
From: Gary Guo @ 2024-07-24 19:40 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada, x86,
H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
rust-for-linux, linux-kernel, patches
On Wed, 24 Jul 2024 18:14:56 +0200
Miguel Ojeda <ojeda@kernel.org> wrote:
> The Rust compiler added support for `-Zfunction-return=thunk-extern` [1]
> in 1.76.0 [2], i.e. the equivalent of `-mfunction-return=thunk-extern`.
> Thus add support for `MITIGATION_RETHUNK`.
>
> Without this, `objtool` would warn if enabled for Rust and already warns
> under IBT builds, e.g.:
>
> samples/rust/rust_print.o: warning: objtool:
> _R...init+0xa5c: 'naked' return found in RETHUNK build
>
> Link: https://github.com/rust-lang/rust/issues/116853 [1]
> Link: https://github.com/rust-lang/rust/pull/116892 [2]
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
> ---
> arch/x86/Makefile | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/arch/x86/Makefile b/arch/x86/Makefile
> index e8214bff1aeb..a1883a30a5d8 100644
> --- a/arch/x86/Makefile
> +++ b/arch/x86/Makefile
> @@ -24,11 +24,15 @@ RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix)
>
> ifdef CONFIG_MITIGATION_RETHUNK
> RETHUNK_CFLAGS := -mfunction-return=thunk-extern
> +RETHUNK_RUSTFLAGS := -Zfunction-return=thunk-extern
> RETPOLINE_CFLAGS += $(RETHUNK_CFLAGS)
> +RETPOLINE_RUSTFLAGS += $(RETHUNK_RUSTFLAGS)
> endif
>
> export RETHUNK_CFLAGS
> +export RETHUNK_RUSTFLAGS
> export RETPOLINE_CFLAGS
> +export RETPOLINE_RUSTFLAGS
> export RETPOLINE_VDSO_CFLAGS
>
> # For gcc stack alignment is specified with -mpreferred-stack-boundary,
> @@ -218,6 +222,7 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
> # Avoid indirect branches in kernel to deal with Spectre
> ifdef CONFIG_MITIGATION_RETPOLINE
> KBUILD_CFLAGS += $(RETPOLINE_CFLAGS)
> + KBUILD_RUSTFLAGS += $(RETPOLINE_RUSTFLAGS)
> # Additionally, avoid generating expensive indirect jumps which
> # are subject to retpolines for small number of switch cases.
> # LLVM turns off jump table generation by default when under
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 4/6] x86/rust: support MITIGATION_SLS
2024-07-24 16:14 [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool` Miguel Ojeda
` (2 preceding siblings ...)
2024-07-24 16:14 ` [PATCH v2 3/6] x86/rust: support MITIGATION_RETHUNK Miguel Ojeda
@ 2024-07-24 16:14 ` Miguel Ojeda
2024-07-24 19:42 ` Gary Guo
2024-07-24 16:14 ` [PATCH v2 5/6] objtool: list `noreturn` Rust functions Miguel Ojeda
` (4 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: Miguel Ojeda @ 2024-07-24 16:14 UTC (permalink / raw)
To: Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada
Cc: x86, H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Miguel Ojeda, Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, rust-for-linux, linux-kernel, patches
Support `MITIGATION_SLS` by enabling the target features that Clang does.
Without this, `objtool` would complain if enabled for Rust, e.g.:
rust/core.o: warning: objtool:
_R...next_up+0x44: missing int3 after ret
These should be eventually enabled via `-Ctarget-feature` when `rustc`
starts recognizing them (or via a new dedicated flag) [1].
Link: https://github.com/rust-lang/rust/issues/116851 [1]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
scripts/generate_rust_target.rs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
index 44952f0a3aac..ba1bd455e160 100644
--- a/scripts/generate_rust_target.rs
+++ b/scripts/generate_rust_target.rs
@@ -173,6 +173,14 @@ fn main() {
features += ",+retpoline-indirect-branches";
features += ",+retpoline-indirect-calls";
}
+ if cfg.has("MITIGATION_SLS") {
+ // The kernel uses `-mharden-sls=all`, which Clang maps to both these target features in
+ // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via
+ // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated
+ // flag); see https://github.com/rust-lang/rust/issues/116851.
+ features += ",+harden-sls-ijmp";
+ features += ",+harden-sls-ret";
+ }
ts.push("features", features);
ts.push("llvm-target", "x86_64-linux-gnu");
ts.push("target-pointer-width", "64");
--
2.45.2
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH v2 4/6] x86/rust: support MITIGATION_SLS
2024-07-24 16:14 ` [PATCH v2 4/6] x86/rust: support MITIGATION_SLS Miguel Ojeda
@ 2024-07-24 19:42 ` Gary Guo
0 siblings, 0 replies; 22+ messages in thread
From: Gary Guo @ 2024-07-24 19:42 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada, x86,
H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
rust-for-linux, linux-kernel, patches
On Wed, 24 Jul 2024 18:14:57 +0200
Miguel Ojeda <ojeda@kernel.org> wrote:
> Support `MITIGATION_SLS` by enabling the target features that Clang does.
>
> Without this, `objtool` would complain if enabled for Rust, e.g.:
>
> rust/core.o: warning: objtool:
> _R...next_up+0x44: missing int3 after ret
>
> These should be eventually enabled via `-Ctarget-feature` when `rustc`
> starts recognizing them (or via a new dedicated flag) [1].
>
> Link: https://github.com/rust-lang/rust/issues/116851 [1]
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
> ---
> scripts/generate_rust_target.rs | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
> index 44952f0a3aac..ba1bd455e160 100644
> --- a/scripts/generate_rust_target.rs
> +++ b/scripts/generate_rust_target.rs
> @@ -173,6 +173,14 @@ fn main() {
> features += ",+retpoline-indirect-branches";
> features += ",+retpoline-indirect-calls";
> }
> + if cfg.has("MITIGATION_SLS") {
> + // The kernel uses `-mharden-sls=all`, which Clang maps to both these target features in
> + // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via
> + // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated
> + // flag); see https://github.com/rust-lang/rust/issues/116851.
> + features += ",+harden-sls-ijmp";
> + features += ",+harden-sls-ret";
> + }
> ts.push("features", features);
> ts.push("llvm-target", "x86_64-linux-gnu");
> ts.push("target-pointer-width", "64");
> --
> 2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 5/6] objtool: list `noreturn` Rust functions
2024-07-24 16:14 [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool` Miguel Ojeda
` (3 preceding siblings ...)
2024-07-24 16:14 ` [PATCH v2 4/6] x86/rust: support MITIGATION_SLS Miguel Ojeda
@ 2024-07-24 16:14 ` Miguel Ojeda
2024-07-24 19:35 ` Gary Guo
2024-07-24 16:14 ` [PATCH v2 6/6] objtool/kbuild/rust: enable objtool for Rust Miguel Ojeda
` (3 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: Miguel Ojeda @ 2024-07-24 16:14 UTC (permalink / raw)
To: Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada
Cc: x86, H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Miguel Ojeda, Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, rust-for-linux, linux-kernel, patches
Rust functions may be `noreturn` (i.e. diverging) by returning the
"never" type, `!`, e.g.
fn f() -> ! {
loop {}
}
Thus list the known `noreturn` functions to avoid such warnings.
Without this, `objtool` would complain if enabled for Rust, e.g.:
rust/core.o: warning: objtool:
_R...9panic_fmt() falls through to next function _R...18panic_nounwind_fmt()
rust/alloc.o: warning: objtool:
.text: unexpected end of section
In order to do so, we cannot match symbols' names exactly, for two
reasons:
- Rust mangling scheme [1] contains disambiguators [2] which we
cannot predict (e.g. they may vary depending on the compiler version).
One possibility to solve this would be to parse v0 and ignore/zero
those before comparison.
- Some of the diverging functions come from `core` and `alloc`, i.e.
the Rust standard library, which may change with each compiler version
since they are implementation details (e.g. `panic_internals`).
Thus, to workaround both issues, only part of the symbols are matched,
instead of using the `NORETURN` macro in `noreturns.h`.
Ideally, just like for the C side, we should have a better solution. For
instance, the compiler could give us the list via something like:
$ rustc --print noreturns ...
Link: https://rust-lang.github.io/rfcs/2603-rust-symbol-name-mangling-v0.html [1]
Link: https://doc.rust-lang.org/rustc/symbol-mangling/v0.html#disambiguator [2]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
Please let me know if there is a better solution -- what kind of solution was
being thought about for C as mentioned in `noreturns.h`? Would it help for Rust?
tools/objtool/check.c | 36 +++++++++++++++++++++++++++++++++++-
tools/objtool/noreturns.h | 2 ++
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 0a33d9195b7a..0afdcee038fd 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -177,6 +177,20 @@ static bool is_sibling_call(struct instruction *insn)
return (is_static_jump(insn) && insn_call_dest(insn));
}
+/*
+ * Checks if a string ends with another.
+ */
+static bool str_ends_with(const char *s, const char *sub)
+{
+ const int slen = strlen(s);
+ const int sublen = strlen(sub);
+
+ if (sublen > slen)
+ return 0;
+
+ return !memcmp(s + slen - sublen, sub, sublen);
+}
+
/*
* This checks to see if the given function is a "noreturn" function.
*
@@ -202,10 +216,30 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
if (!func)
return false;
- if (func->bind == STB_GLOBAL || func->bind == STB_WEAK)
+ if (func->bind == STB_GLOBAL || func->bind == STB_WEAK) {
+ /*
+ * Rust standard library functions.
+ *
+ * These are just heuristics -- we do not control the precise symbol
+ * name, due to the crate disambiguators (which depend on the compiler)
+ * as well as changes to the source code itself between versions.
+ */
+ if (!strncmp(func->name, "_R", 2) &&
+ (str_ends_with(func->name, "_4core6option13unwrap_failed") ||
+ str_ends_with(func->name, "_4core6result13unwrap_failed") ||
+ str_ends_with(func->name, "_4core9panicking5panic") ||
+ str_ends_with(func->name, "_4core9panicking9panic_fmt") ||
+ str_ends_with(func->name, "_4core9panicking14panic_explicit") ||
+ str_ends_with(func->name, "_4core9panicking18panic_bounds_check") ||
+ strstr(func->name, "_4core9panicking11panic_const24panic_const_") ||
+ (strstr(func->name, "_4core5slice5index24slice_") &&
+ str_ends_with(func->name, "_fail"))))
+ return true;
+
for (i = 0; i < ARRAY_SIZE(global_noreturns); i++)
if (!strcmp(func->name, global_noreturns[i]))
return true;
+ }
if (func->bind == STB_WEAK)
return false;
diff --git a/tools/objtool/noreturns.h b/tools/objtool/noreturns.h
index 7ebf29c91184..82a001ac433b 100644
--- a/tools/objtool/noreturns.h
+++ b/tools/objtool/noreturns.h
@@ -35,6 +35,8 @@ NORETURN(panic)
NORETURN(panic_smp_self_stop)
NORETURN(rest_init)
NORETURN(rewind_stack_and_make_dead)
+NORETURN(rust_begin_unwind)
+NORETURN(rust_helper_BUG)
NORETURN(sev_es_terminate)
NORETURN(snp_abort)
NORETURN(start_kernel)
--
2.45.2
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH v2 5/6] objtool: list `noreturn` Rust functions
2024-07-24 16:14 ` [PATCH v2 5/6] objtool: list `noreturn` Rust functions Miguel Ojeda
@ 2024-07-24 19:35 ` Gary Guo
2024-07-25 8:33 ` Peter Zijlstra
0 siblings, 1 reply; 22+ messages in thread
From: Gary Guo @ 2024-07-24 19:35 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada, x86,
H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
rust-for-linux, linux-kernel, patches
On Wed, 24 Jul 2024 18:14:58 +0200
Miguel Ojeda <ojeda@kernel.org> wrote:
> Rust functions may be `noreturn` (i.e. diverging) by returning the
> "never" type, `!`, e.g.
>
> fn f() -> ! {
> loop {}
> }
>
> Thus list the known `noreturn` functions to avoid such warnings.
>
> Without this, `objtool` would complain if enabled for Rust, e.g.:
>
> rust/core.o: warning: objtool:
> _R...9panic_fmt() falls through to next function _R...18panic_nounwind_fmt()
>
> rust/alloc.o: warning: objtool:
> .text: unexpected end of section
>
> In order to do so, we cannot match symbols' names exactly, for two
> reasons:
>
> - Rust mangling scheme [1] contains disambiguators [2] which we
> cannot predict (e.g. they may vary depending on the compiler version).
>
> One possibility to solve this would be to parse v0 and ignore/zero
> those before comparison.
>
> - Some of the diverging functions come from `core` and `alloc`, i.e.
> the Rust standard library, which may change with each compiler version
> since they are implementation details (e.g. `panic_internals`).
>
> Thus, to workaround both issues, only part of the symbols are matched,
> instead of using the `NORETURN` macro in `noreturns.h`.
>
> Ideally, just like for the C side, we should have a better solution. For
> instance, the compiler could give us the list via something like:
>
> $ rustc --print noreturns ...
>
> Link: https://rust-lang.github.io/rfcs/2603-rust-symbol-name-mangling-v0.html [1]
> Link: https://doc.rust-lang.org/rustc/symbol-mangling/v0.html#disambiguator [2]
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> ---
> Please let me know if there is a better solution -- what kind of solution was
> being thought about for C as mentioned in `noreturns.h`? Would it help for Rust?
>
> tools/objtool/check.c | 36 +++++++++++++++++++++++++++++++++++-
> tools/objtool/noreturns.h | 2 ++
> 2 files changed, 37 insertions(+), 1 deletion(-)
>
> diff --git a/tools/objtool/check.c b/tools/objtool/check.c
> index 0a33d9195b7a..0afdcee038fd 100644
> --- a/tools/objtool/check.c
> +++ b/tools/objtool/check.c
> @@ -177,6 +177,20 @@ static bool is_sibling_call(struct instruction *insn)
> return (is_static_jump(insn) && insn_call_dest(insn));
> }
>
> +/*
> + * Checks if a string ends with another.
> + */
> +static bool str_ends_with(const char *s, const char *sub)
> +{
> + const int slen = strlen(s);
> + const int sublen = strlen(sub);
> +
> + if (sublen > slen)
> + return 0;
> +
> + return !memcmp(s + slen - sublen, sub, sublen);
> +}
> +
> /*
> * This checks to see if the given function is a "noreturn" function.
> *
> @@ -202,10 +216,30 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
> if (!func)
> return false;
>
> - if (func->bind == STB_GLOBAL || func->bind == STB_WEAK)
> + if (func->bind == STB_GLOBAL || func->bind == STB_WEAK) {
> + /*
> + * Rust standard library functions.
> + *
> + * These are just heuristics -- we do not control the precise symbol
> + * name, due to the crate disambiguators (which depend on the compiler)
> + * as well as changes to the source code itself between versions.
> + */
> + if (!strncmp(func->name, "_R", 2) &&
> + (str_ends_with(func->name, "_4core6option13unwrap_failed") ||
> + str_ends_with(func->name, "_4core6result13unwrap_failed") ||
> + str_ends_with(func->name, "_4core9panicking5panic") ||
> + str_ends_with(func->name, "_4core9panicking9panic_fmt") ||
> + str_ends_with(func->name, "_4core9panicking14panic_explicit") ||
> + str_ends_with(func->name, "_4core9panicking18panic_bounds_check") ||
> + strstr(func->name, "_4core9panicking11panic_const24panic_const_") ||
> + (strstr(func->name, "_4core5slice5index24slice_") &&
> + str_ends_with(func->name, "_fail"))))
> + return true;
> +
I wonder if we should use dwarf for this. There's DW_AT_noreturn which
tells us exactly what we want. This would also remove the need for the
hardcoded C symbol list. I do recognise that debug info is not required
for objtool though...
> for (i = 0; i < ARRAY_SIZE(global_noreturns); i++)
> if (!strcmp(func->name, global_noreturns[i]))
> return true;
> + }
>
> if (func->bind == STB_WEAK)
> return false;
> diff --git a/tools/objtool/noreturns.h b/tools/objtool/noreturns.h
> index 7ebf29c91184..82a001ac433b 100644
> --- a/tools/objtool/noreturns.h
> +++ b/tools/objtool/noreturns.h
> @@ -35,6 +35,8 @@ NORETURN(panic)
> NORETURN(panic_smp_self_stop)
> NORETURN(rest_init)
> NORETURN(rewind_stack_and_make_dead)
> +NORETURN(rust_begin_unwind)
> +NORETURN(rust_helper_BUG)
> NORETURN(sev_es_terminate)
> NORETURN(snp_abort)
> NORETURN(start_kernel)
> --
> 2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH v2 5/6] objtool: list `noreturn` Rust functions
2024-07-24 19:35 ` Gary Guo
@ 2024-07-25 8:33 ` Peter Zijlstra
2024-08-21 15:28 ` Gary Guo
0 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2024-07-25 8:33 UTC (permalink / raw)
To: Gary Guo
Cc: Miguel Ojeda, Josh Poimboeuf, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada, x86,
H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
rust-for-linux, linux-kernel, patches
On Wed, Jul 24, 2024 at 08:35:49PM +0100, Gary Guo wrote:
> > @@ -202,10 +216,30 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
> > if (!func)
> > return false;
> >
> > - if (func->bind == STB_GLOBAL || func->bind == STB_WEAK)
> > + if (func->bind == STB_GLOBAL || func->bind == STB_WEAK) {
> > + /*
> > + * Rust standard library functions.
> > + *
> > + * These are just heuristics -- we do not control the precise symbol
> > + * name, due to the crate disambiguators (which depend on the compiler)
> > + * as well as changes to the source code itself between versions.
> > + */
> > + if (!strncmp(func->name, "_R", 2) &&
> > + (str_ends_with(func->name, "_4core6option13unwrap_failed") ||
> > + str_ends_with(func->name, "_4core6result13unwrap_failed") ||
> > + str_ends_with(func->name, "_4core9panicking5panic") ||
> > + str_ends_with(func->name, "_4core9panicking9panic_fmt") ||
> > + str_ends_with(func->name, "_4core9panicking14panic_explicit") ||
> > + str_ends_with(func->name, "_4core9panicking18panic_bounds_check") ||
> > + strstr(func->name, "_4core9panicking11panic_const24panic_const_") ||
> > + (strstr(func->name, "_4core5slice5index24slice_") &&
> > + str_ends_with(func->name, "_fail"))))
> > + return true;
> > +
Perhaps add a helper function: is_rust_noreturn() or somesuch.
> I wonder if we should use dwarf for this. There's DW_AT_noreturn which
> tells us exactly what we want. This would also remove the need for the
> hardcoded C symbol list. I do recognise that debug info is not required
> for objtool though...
I think the slightly longer term plan here was to have noreturn.h
generated from a DWARF build but still included verbatim in the objtool
source, such that it works even on regular builds.
(and can be augmented where the compilers are being 'funny')
It's just that nobody has had time to implement this... you fancy giving
this a stab?
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH v2 5/6] objtool: list `noreturn` Rust functions
2024-07-25 8:33 ` Peter Zijlstra
@ 2024-08-21 15:28 ` Gary Guo
0 siblings, 0 replies; 22+ messages in thread
From: Gary Guo @ 2024-08-21 15:28 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Miguel Ojeda, Josh Poimboeuf, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada, x86,
H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
rust-for-linux, linux-kernel, patches
On Thu, 25 Jul 2024 10:33:55 +0200
Peter Zijlstra <peterz@infradead.org> wrote:
> On Wed, Jul 24, 2024 at 08:35:49PM +0100, Gary Guo wrote:
> > > @@ -202,10 +216,30 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
> > > if (!func)
> > > return false;
> > >
> > > - if (func->bind == STB_GLOBAL || func->bind == STB_WEAK)
> > > + if (func->bind == STB_GLOBAL || func->bind == STB_WEAK) {
> > > + /*
> > > + * Rust standard library functions.
> > > + *
> > > + * These are just heuristics -- we do not control the precise symbol
> > > + * name, due to the crate disambiguators (which depend on the compiler)
> > > + * as well as changes to the source code itself between versions.
> > > + */
> > > + if (!strncmp(func->name, "_R", 2) &&
> > > + (str_ends_with(func->name, "_4core6option13unwrap_failed") ||
> > > + str_ends_with(func->name, "_4core6result13unwrap_failed") ||
> > > + str_ends_with(func->name, "_4core9panicking5panic") ||
> > > + str_ends_with(func->name, "_4core9panicking9panic_fmt") ||
> > > + str_ends_with(func->name, "_4core9panicking14panic_explicit") ||
> > > + str_ends_with(func->name, "_4core9panicking18panic_bounds_check") ||
> > > + strstr(func->name, "_4core9panicking11panic_const24panic_const_") ||
> > > + (strstr(func->name, "_4core5slice5index24slice_") &&
> > > + str_ends_with(func->name, "_fail"))))
> > > + return true;
> > > +
>
> Perhaps add a helper function: is_rust_noreturn() or somesuch.
>
> > I wonder if we should use dwarf for this. There's DW_AT_noreturn which
> > tells us exactly what we want. This would also remove the need for the
> > hardcoded C symbol list. I do recognise that debug info is not required
> > for objtool though...
>
> I think the slightly longer term plan here was to have noreturn.h
> generated from a DWARF build but still included verbatim in the objtool
> source, such that it works even on regular builds.
>
> (and can be augmented where the compilers are being 'funny')
>
> It's just that nobody has had time to implement this... you fancy giving
> this a stab?
The information extraction from dwarf is quite easy: I produced a tiny
cargo script that would be able to extract the info from an object file
(Miguel mentioned it in one of the replies):
https://gist.github.com/nbdd0121/449692570622c2f46a29ad9f47c3379a
I think the issue is that the list of noreturn symbols changes
depending on the configuration, so it's kind of difficult to
pregenerate this information.
Do you think it makes sense to have Rust object files always have DWARF
enabled, and we check Rust noreturn symbols using DWARF, while keep the
hardcoded C symbol list?
Best,
Gary
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 6/6] objtool/kbuild/rust: enable objtool for Rust
2024-07-24 16:14 [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool` Miguel Ojeda
` (4 preceding siblings ...)
2024-07-24 16:14 ` [PATCH v2 5/6] objtool: list `noreturn` Rust functions Miguel Ojeda
@ 2024-07-24 16:14 ` Miguel Ojeda
2024-07-24 21:51 ` [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool` Benno Lossin
` (2 subsequent siblings)
8 siblings, 0 replies; 22+ messages in thread
From: Miguel Ojeda @ 2024-07-24 16:14 UTC (permalink / raw)
To: Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada
Cc: x86, H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Miguel Ojeda, Wedson Almeida Filho, Alex Gaynor, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, rust-for-linux, linux-kernel, patches, linux-kbuild
Now that we should be `objtool`-warning free, enable `objtool` for
Rust too.
Before this patch series, we were already getting warnings under e.g. IBT
builds, since those would see Rust code via `vmlinux`.
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
rust/Makefile | 22 ++++++++++++++--------
scripts/Makefile.build | 9 +++++++--
2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/rust/Makefile b/rust/Makefile
index bf05e65365da..1756238b641d 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -344,7 +344,8 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L
--crate-type rlib -L$(objtree)/$(obj) \
--crate-name $(patsubst %.o,%,$(notdir $@)) $< \
--sysroot=/dev/null \
- $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@)
+ $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) \
+ $(cmd_objtool)
rust-analyzer:
$(Q)$(srctree)/scripts/generate_rust_analyzer.py \
@@ -366,44 +367,49 @@ ifneq ($(or $(CONFIG_ARM64),$(and $(CONFIG_RISCV),$(CONFIG_64BIT))),)
__ashlti3 __lshrti3
endif
+define rule_rustc_library
+ $(call cmd_and_fixdep,rustc_library)
+ $(call cmd,gen_objtooldep)
+endef
+
$(obj)/core.o: private skip_clippy = 1
$(obj)/core.o: private skip_flags = -Wunreachable_pub
$(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym))
$(obj)/core.o: private rustc_target_flags = $(core-cfgs)
$(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs FORCE
- +$(call if_changed_dep,rustc_library)
+ +$(call if_changed_rule,rustc_library)
ifdef CONFIG_X86_64
$(obj)/core.o: scripts/target.json
endif
$(obj)/compiler_builtins.o: private rustc_objcopy = -w -W '__*'
$(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE
- +$(call if_changed_dep,rustc_library)
+ +$(call if_changed_rule,rustc_library)
$(obj)/alloc.o: private skip_clippy = 1
$(obj)/alloc.o: private skip_flags = -Wunreachable_pub
$(obj)/alloc.o: private rustc_target_flags = $(alloc-cfgs)
$(obj)/alloc.o: $(RUST_LIB_SRC)/alloc/src/lib.rs $(obj)/compiler_builtins.o FORCE
- +$(call if_changed_dep,rustc_library)
+ +$(call if_changed_rule,rustc_library)
$(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE
- +$(call if_changed_dep,rustc_library)
+ +$(call if_changed_rule,rustc_library)
$(obj)/bindings.o: $(src)/bindings/lib.rs \
$(obj)/compiler_builtins.o \
$(obj)/bindings/bindings_generated.rs \
$(obj)/bindings/bindings_helpers_generated.rs FORCE
- +$(call if_changed_dep,rustc_library)
+ +$(call if_changed_rule,rustc_library)
$(obj)/uapi.o: $(src)/uapi/lib.rs \
$(obj)/compiler_builtins.o \
$(obj)/uapi/uapi_generated.rs FORCE
- +$(call if_changed_dep,rustc_library)
+ +$(call if_changed_rule,rustc_library)
$(obj)/kernel.o: private rustc_target_flags = --extern alloc \
--extern build_error --extern macros --extern bindings --extern uapi
$(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o $(obj)/build_error.o \
$(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE
- +$(call if_changed_dep,rustc_library)
+ +$(call if_changed_rule,rustc_library)
endif # CONFIG_RUST
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index efacca63c897..72b1232b1f7d 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -288,10 +288,15 @@ rust_common_cmd = \
# would not match each other.
quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
- cmd_rustc_o_rs = $(rust_common_cmd) --emit=obj=$@ $<
+ cmd_rustc_o_rs = $(rust_common_cmd) --emit=obj=$@ $< $(cmd_objtool)
+
+define rule_rustc_o_rs
+ $(call cmd_and_fixdep,rustc_o_rs)
+ $(call cmd,gen_objtooldep)
+endef
$(obj)/%.o: $(obj)/%.rs FORCE
- +$(call if_changed_dep,rustc_o_rs)
+ +$(call if_changed_rule,rustc_o_rs)
quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
cmd_rustc_rsi_rs = \
--
2.45.2
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool`
2024-07-24 16:14 [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool` Miguel Ojeda
` (5 preceding siblings ...)
2024-07-24 16:14 ` [PATCH v2 6/6] objtool/kbuild/rust: enable objtool for Rust Miguel Ojeda
@ 2024-07-24 21:51 ` Benno Lossin
2024-07-25 8:38 ` Peter Zijlstra
2024-07-25 9:43 ` Alice Ryhl
8 siblings, 0 replies; 22+ messages in thread
From: Benno Lossin @ 2024-07-24 21:51 UTC (permalink / raw)
To: Miguel Ojeda, Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, Masahiro Yamada
Cc: x86, H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Wedson Almeida Filho, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Andreas Hindborg, Alice Ryhl,
rust-for-linux, linux-kernel, patches, linux-kbuild
On 24.07.24 18:14, Miguel Ojeda wrote:
> Hi,
>
> This is an updated series to the CPU mitigations support for Rust. It
> also has the patch to enable `objtool`, so that we can start running it
> for Rust.
>
> It would be nice to get this applied soon, so that we start being
> warning-free (since we already get warnings under IBT builds via
> `vmlinux.o`). I am happy to take it through the Rust tree if the x86 and
> objtool maintainers give an Acked-by, or through any of the other trees,
> as you prefer. Otherwise, I think at this point we would need to make
> Rust exclusive to the mitigations, which isn't great.
>
> With this series, again, x86_64 is warning-free with `objtool` enabled. I
> tested `-O2`/`-Os` and the Rust versions we support under `-O2` (mainly
> for the `noreturn` patch, which uses heuristics), as well as IBT vs. no
> IBT (i.e. running on individual object files vs. in `vmlinux`). I also
> did an arm64 build.
>
> Testing is very welcome for this one!
>
> Cheers,
> Miguel
>
> v2:
> - Add patch to enable `objtool` for Rust.
>
> - Add patch to list `noreturn` Rust functions (via heuristics) to avoid
> warnings related to that.
>
> - Make the `RETHUNK` patch not an RFC since the Rust compiler has
> support for
> it now.
>
> - Update the names of the migitation config symbols, given the changes
> at e.g.
> commit 7b75782ffd82 ("x86/bugs: Rename CONFIG_MITIGATION_SLS =>
> CONFIG_MITIGATION_SLS").
>
> Miguel Ojeda (6):
> rust: module: add static pointer to `{init,cleanup}_module()`
> x86/rust: support MITIGATION_RETPOLINE
> x86/rust: support MITIGATION_RETHUNK
> x86/rust: support MITIGATION_SLS
> objtool: list `noreturn` Rust functions
> objtool/kbuild/rust: enable objtool for Rust
>
> arch/x86/Makefile | 7 ++++++-
> rust/Makefile | 22 ++++++++++++--------
> rust/macros/module.rs | 12 +++++++++++
> scripts/Makefile.build | 9 +++++++--
> scripts/generate_rust_target.rs | 15 ++++++++++++++
> tools/objtool/check.c | 36 ++++++++++++++++++++++++++++++++-
> tools/objtool/noreturns.h | 2 ++
> 7 files changed, 91 insertions(+), 12 deletions(-)
>
>
> base-commit: b1263411112305acf2af728728591465becb45b0
> --
> 2.45.2
>
I tested this series with a config that produces the objtool warnings on
b126341 and it worked flawlessly. I also tried `-O2` and `-Os`:
Tested-by: Benno Lossin <benno.lossin@proton.me>
---
Cheers,
Benno
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool`
2024-07-24 16:14 [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool` Miguel Ojeda
` (6 preceding siblings ...)
2024-07-24 21:51 ` [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool` Benno Lossin
@ 2024-07-25 8:38 ` Peter Zijlstra
2024-07-25 9:53 ` Miguel Ojeda
2024-07-25 9:43 ` Alice Ryhl
8 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2024-07-25 8:38 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Josh Poimboeuf, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, Masahiro Yamada, x86, H. Peter Anvin,
Nathan Chancellor, Nicolas Schier, Wedson Almeida Filho,
Alex Gaynor, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, rust-for-linux,
linux-kernel, patches, linux-kbuild
On Wed, Jul 24, 2024 at 06:14:53PM +0200, Miguel Ojeda wrote:
> Hi,
>
> This is an updated series to the CPU mitigations support for Rust. It
> also has the patch to enable `objtool`, so that we can start running it
> for Rust.
>
> It would be nice to get this applied soon, so that we start being
> warning-free (since we already get warnings under IBT builds via
> `vmlinux.o`). I am happy to take it through the Rust tree if the x86 and
> objtool maintainers give an Acked-by, or through any of the other trees,
> as you prefer. Otherwise, I think at this point we would need to make
> Rust exclusive to the mitigations, which isn't great.
>
> With this series, again, x86_64 is warning-free with `objtool` enabled. I
> tested `-O2`/`-Os` and the Rust versions we support under `-O2` (mainly
> for the `noreturn` patch, which uses heuristics), as well as IBT vs. no
> IBT (i.e. running on individual object files vs. in `vmlinux`). I also
> did an arm64 build.
W00t :-)
Aside from a small niggle about maybe doing a helper function for those
Rust runtime things, I don't see anything objectionable here.
Thanks!
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool`
2024-07-25 8:38 ` Peter Zijlstra
@ 2024-07-25 9:53 ` Miguel Ojeda
0 siblings, 0 replies; 22+ messages in thread
From: Miguel Ojeda @ 2024-07-25 9:53 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Miguel Ojeda, Josh Poimboeuf, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada, x86,
H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Wedson Almeida Filho, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
rust-for-linux, linux-kernel, patches, linux-kbuild
On Thu, Jul 25, 2024 at 10:38 AM Peter Zijlstra <peterz@infradead.org> wrote:
>
> W00t :-)
>
> Aside from a small niggle about maybe doing a helper function for those
> Rust runtime things, I don't see anything objectionable here.
>
> Thanks!
Thanks for taking a look that quick, Peter, I appreciate it.
Happy to move that to a helper.
Cheers,
Miguel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool`
2024-07-24 16:14 [PATCH v2 0/6] Rust: support `CPU_MITIGATIONS` and enable `objtool` Miguel Ojeda
` (7 preceding siblings ...)
2024-07-25 8:38 ` Peter Zijlstra
@ 2024-07-25 9:43 ` Alice Ryhl
8 siblings, 0 replies; 22+ messages in thread
From: Alice Ryhl @ 2024-07-25 9:43 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Masahiro Yamada, x86,
H. Peter Anvin, Nathan Chancellor, Nicolas Schier,
Wedson Almeida Filho, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
rust-for-linux, linux-kernel, patches, linux-kbuild
On Wed, Jul 24, 2024 at 6:15 PM Miguel Ojeda <ojeda@kernel.org> wrote:
>
> Hi,
>
> This is an updated series to the CPU mitigations support for Rust. It
> also has the patch to enable `objtool`, so that we can start running it
> for Rust.
>
> It would be nice to get this applied soon, so that we start being
> warning-free (since we already get warnings under IBT builds via
> `vmlinux.o`). I am happy to take it through the Rust tree if the x86 and
> objtool maintainers give an Acked-by, or through any of the other trees,
> as you prefer. Otherwise, I think at this point we would need to make
> Rust exclusive to the mitigations, which isn't great.
>
> With this series, again, x86_64 is warning-free with `objtool` enabled. I
> tested `-O2`/`-Os` and the Rust versions we support under `-O2` (mainly
> for the `noreturn` patch, which uses heuristics), as well as IBT vs. no
> IBT (i.e. running on individual object files vs. in `vmlinux`). I also
> did an arm64 build.
>
> Testing is very welcome for this one!
Verified that this eliminates the relevant warnings in an x86 build of
the android-mainline kernel.
Tested-by: Alice Ryhl <aliceryhl@google.com>
^ permalink raw reply [flat|nested] 22+ messages in thread