From: Conor Dooley <conor@kernel.org>
To: Miguel Ojeda <ojeda@kernel.org>
Cc: "Alex Gaynor" <alex.gaynor@gmail.com>,
"Andrey Ryabinin" <ryabinin.a.a@gmail.com>,
"Masahiro Yamada" <masahiroy@kernel.org>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <benno.lossin@proton.me>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
rust-for-linux@vger.kernel.org,
"Alexander Potapenko" <glider@google.com>,
"Andrey Konovalov" <andreyknvl@gmail.com>,
"Dmitry Vyukov" <dvyukov@google.com>,
"Vincenzo Frascino" <vincenzo.frascino@arm.com>,
kasan-dev@googlegroups.com,
"Nathan Chancellor" <nathan@kernel.org>,
"Nicolas Schier" <nicolas@fjasle.eu>,
linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org,
patches@lists.linux.dev, "Matthew Maurer" <mmaurer@google.com>,
"Sami Tolvanen" <samitolvanen@google.com>,
stable@vger.kernel.org
Subject: Re: [PATCH] rust: kasan/kbuild: fix missing flags on first build
Date: Mon, 1 Sep 2025 18:45:54 +0100 [thread overview]
Message-ID: <20250901-shrimp-define-9d99cc2a012a@spud> (raw)
In-Reply-To: <20250408220311.1033475-1-ojeda@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 6456 bytes --]
Yo,
On Wed, Apr 09, 2025 at 12:03:11AM +0200, Miguel Ojeda wrote:
> If KASAN is enabled, and one runs in a clean repository e.g.:
>
> make LLVM=1 prepare
> make LLVM=1 prepare
>
> Then the Rust code gets rebuilt, which should not happen.
>
> The reason is some of the LLVM KASAN `rustc` flags are added in the
> second run:
>
> -Cllvm-args=-asan-instrumentation-with-call-threshold=10000
> -Cllvm-args=-asan-stack=0
> -Cllvm-args=-asan-globals=1
> -Cllvm-args=-asan-kernel-mem-intrinsic-prefix=1
>
> Further runs do not rebuild Rust because the flags do not change anymore.
>
> Rebuilding like that in the second run is bad, even if this just happens
> with KASAN enabled, but missing flags in the first one is even worse.
>
> The root issue is that we pass, for some architectures and for the moment,
> a generated `target.json` file. That file is not ready by the time `rustc`
> gets called for the flag test, and thus the flag test fails just because
> the file is not available, e.g.:
>
> $ ... --target=./scripts/target.json ... -Cllvm-args=...
> error: target file "./scripts/target.json" does not exist
>
> There are a few approaches we could take here to solve this. For instance,
> we could ensure that every time that the config is rebuilt, we regenerate
> the file and recompute the flags. Or we could use the LLVM version to
> check for these flags, instead of testing the flag (which may have other
> advantages, such as allowing us to detect renames on the LLVM side).
>
> However, it may be easier than that: `rustc` is aware of the `-Cllvm-args`
> regardless of the `--target` (e.g. I checked that the list printed
> is the same, plus that I can check for these flags even if I pass
> a completely unrelated target), and thus we can just eliminate the
> dependency completely.
>
> Thus filter out the target.
> This does mean that `rustc-option` cannot be used to test a flag that
> requires the right target, but we don't have other users yet, it is a
> minimal change and we want to get rid of custom targets in the future.
Hmm, while this might be true, I think it should not actually have been
true. Commit ca627e636551e ("rust: cfi: add support for CFI_CLANG with Rust")
added a cc-option check to the rust kconfig symbol, checking if the c
compiler supports the integer normalisations stuff:
depends on !CFI_CLANG || RUSTC_VERSION >= 107900 && $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers)
and also sets the relevant options in the makefile:
ifdef CONFIG_RUST
# Always pass -Zsanitizer-cfi-normalize-integers as CONFIG_RUST selects
# CONFIG_CFI_ICALL_NORMALIZE_INTEGERS.
RUSTC_FLAGS_CFI := -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers
KBUILD_RUSTFLAGS += $(RUSTC_FLAGS_CFI)
export RUSTC_FLAGS_CFI
endif
but it should also have added a rustc-option check as, unfortunately,
support for kcfi in rustc is target specific. This results in build
breakages where the arch supports CFI_CLANG and RUST, but the target in
use does not have the kcfi flag set.
I attempted to fix this by adding:
diff --git a/arch/Kconfig b/arch/Kconfig
index d1b4ffd6e0856..235709fb75152 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -916,6 +916,7 @@ config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG
config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC
def_bool y
depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG
+ depends on $(rustc-option,-C panic=abort -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers)
depends on RUSTC_VERSION >= 107900
# With GCOV/KASAN we need this fix: https://github.com/rust-lang/rust/pull/129373
depends on (RUSTC_LLVM_VERSION >= 190103 && RUSTC_VERSION >= 108200) || \
but of course this does not work for cross compilation, as you're
stripping the target information out and so the check passes on my host
even though my intended
RUSTC_BOOTSTRAP=1 rustc -C panic=abort -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers -Ctarget-cpu=generic-rv64 --target=riscv64imac-unknown-none-elf
is a failure.
I dunno too much about rustc itself, but I suspect that adding kcfi to
the target there is a "free" win, but that'll take time to trickle down
and the minimum version rustc version for the kernel isn't going to have
that.
I'm not really sure what your target.json suggestion below is, so just
reporting so that someone that understands the alternative solutions can
fix this.
Cheers,
Conor.
>
> We could only filter in the case `target.json` is used, to make it work
> in more cases, but then it would be harder to notice that it may not
> work in a couple architectures.
>
> Cc: Matthew Maurer <mmaurer@google.com>
> Cc: Sami Tolvanen <samitolvanen@google.com>
> Cc: stable@vger.kernel.org
> Fixes: e3117404b411 ("kbuild: rust: Enable KASAN support")
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> ---
> By the way, I noticed that we are not getting `asan-instrument-allocas` enabled
> in neither C nor Rust -- upstream LLVM renamed it in commit 8176ee9b5dda ("[asan]
> Rename asan-instrument-allocas -> asan-instrument-dynamic-allocas")). But it
> happened a very long time ago (9 years ago), and the addition in the kernel
> is fairly old too, in 342061ee4ef3 ("kasan: support alloca() poisoning").
> I assume it should either be renamed or removed? Happy to send a patch if so.
>
> scripts/Makefile.compiler | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler
> index 8956587b8547..7ed7f92a7daa 100644
> --- a/scripts/Makefile.compiler
> +++ b/scripts/Makefile.compiler
> @@ -80,7 +80,7 @@ ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3))
> # TODO: remove RUSTC_BOOTSTRAP=1 when we raise the minimum GNU Make version to 4.4
> __rustc-option = $(call try-run,\
> echo '#![allow(missing_docs)]#![feature(no_core)]#![no_core]' | RUSTC_BOOTSTRAP=1\
> - $(1) --sysroot=/dev/null $(filter-out --sysroot=/dev/null,$(2)) $(3)\
> + $(1) --sysroot=/dev/null $(filter-out --sysroot=/dev/null --target=%,$(2)) $(3)\
> --crate-type=rlib --out-dir=$(TMPOUT) --emit=obj=- - >/dev/null,$(3),$(4))
>
> # rustc-option
>
> base-commit: 0af2f6be1b4281385b618cb86ad946eded089ac8
> --
> 2.49.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
next prev parent reply other threads:[~2025-09-01 17:46 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-08 22:03 [PATCH] rust: kasan/kbuild: fix missing flags on first build Miguel Ojeda
2025-04-09 21:35 ` Matthew Maurer
2025-04-09 21:53 ` Miguel Ojeda
2025-04-13 22:24 ` Miguel Ojeda
2025-04-14 11:22 ` Alice Ryhl
2025-09-01 17:45 ` Conor Dooley [this message]
2025-09-02 8:29 ` Alice Ryhl
2025-09-02 10:12 ` Conor Dooley
2025-09-02 10:23 ` Alice Ryhl
2025-09-02 16:35 ` Conor Dooley
2025-09-03 9:12 ` Miguel Ojeda
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250901-shrimp-define-9d99cc2a012a@spud \
--to=conor@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=andreyknvl@gmail.com \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=dvyukov@google.com \
--cc=gary@garyguo.net \
--cc=glider@google.com \
--cc=kasan-dev@googlegroups.com \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=masahiroy@kernel.org \
--cc=mmaurer@google.com \
--cc=nathan@kernel.org \
--cc=nicolas@fjasle.eu \
--cc=ojeda@kernel.org \
--cc=patches@lists.linux.dev \
--cc=rust-for-linux@vger.kernel.org \
--cc=ryabinin.a.a@gmail.com \
--cc=samitolvanen@google.com \
--cc=stable@vger.kernel.org \
--cc=tmgross@umich.edu \
--cc=vincenzo.frascino@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).