* [PATCH 0/2] Rust KASAN Support @ 2024-07-25 23:20 Matthew Maurer 2024-07-25 23:20 ` [PATCH 1/2] kbuild: rust: Define probing macros for rustc Matthew Maurer 2024-07-25 23:20 ` [PATCH 2/2] kbuild: rust: Enable KASAN support Matthew Maurer 0 siblings, 2 replies; 6+ messages in thread From: Matthew Maurer @ 2024-07-25 23:20 UTC (permalink / raw) To: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Nathan Chancellor Cc: Matthew Maurer, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Nick Desaulniers, Bill Wendling, Justin Stitt, rust-for-linux, llvm Right now, if we turn on KASAN, Rust code will cause violations because it's not enabled properly. This series: 1. Adds flag probe macros for Rust - now that we're setting a minimum rustc version instead of an exact one, these could be useful in general. We need them in this patch because we don't set a restriction on which LLVM rustc is using, which is what KASAN actually cares about. 2. Makes `rustc` enable the relevant KASAN sanitizer flags when C does. Matthew Maurer (2): kbuild: rust: Define probing macros for rustc kbuild: rust: Enable KASAN support scripts/Kconfig.include | 8 +++++++ scripts/Makefile.compiler | 15 +++++++++++++ scripts/Makefile.kasan | 46 ++++++++++++++++++++++++++++++++++++++- scripts/Makefile.lib | 3 +++ 4 files changed, 71 insertions(+), 1 deletion(-) -- 2.46.0.rc1.232.g9752f9e123-goog ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] kbuild: rust: Define probing macros for rustc 2024-07-25 23:20 [PATCH 0/2] Rust KASAN Support Matthew Maurer @ 2024-07-25 23:20 ` Matthew Maurer 2024-07-25 23:20 ` [PATCH 2/2] kbuild: rust: Enable KASAN support Matthew Maurer 1 sibling, 0 replies; 6+ messages in thread From: Matthew Maurer @ 2024-07-25 23:20 UTC (permalink / raw) To: Masahiro Yamada, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Nathan Chancellor Cc: Matthew Maurer, Nicolas Schier, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Nick Desaulniers, Bill Wendling, Justin Stitt, linux-kbuild, linux-kernel, rust-for-linux, llvm Creates flag probe macro variants for `rustc`. These are helpful because: 1. `rustc` support will soon be a minimum rather than a pinned version. 2. We already support multiple LLVMs linked into `rustc`, and these are needed to probe what LLVM parameters `rustc` will accept. Signed-off-by: Matthew Maurer <mmaurer@google.com> --- scripts/Kconfig.include | 8 ++++++++ scripts/Makefile.compiler | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include index 3ee8ecfb8c04..ffafe269fe9e 100644 --- a/scripts/Kconfig.include +++ b/scripts/Kconfig.include @@ -63,3 +63,11 @@ ld-version := $(shell,set -- $(ld-info) && echo $2) cc-option-bit = $(if-success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null,$(1)) m32-flag := $(cc-option-bit,-m32) m64-flag := $(cc-option-bit,-m64) + +# $(rustc-option,<flag>) +# Return y if the Rust compiler supports <flag>, n otherwise +# Calls to this should be guarded so that they are not evaluated if +# CONFIG_HAVE_RUST is not set. +# If you are testing for unstable features, consider `rustc-min-version` +# instead, as features may have different completeness while available. +rustc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(RUSTC) $(1) --crate-type=rlib /dev/null -o .tmp_$$/tmp.rlib) diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler index 92be0c9a13ee..485d66768a32 100644 --- a/scripts/Makefile.compiler +++ b/scripts/Makefile.compiler @@ -72,3 +72,18 @@ clang-min-version = $(call test-ge, $(CONFIG_CLANG_VERSION), $1) # ld-option # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3)) + +# __rustc-option +# Usage: MY_RUSTFLAGS += $(call __rustc-option,$(RUSTC),$(MY_RUSTFLAGS),-Cinstrument-coverage,-Zinstrument-coverage) +__rustc-option = $(call try-run,\ + $(1) $(2) $(3) --crate-type=rlib /dev/null -o "$$TMP",$(3),$(4)) + +# rustc-option +# Usage: rustflags-y += $(call rustc-option,-Cinstrument-coverage,-Zinstrument-coverage) +rustc-option = $(call __rustc-option, $(RUSTC),\ + $(KBUILD_RUSTFLAGS),$(1),$(2)) + +# rustc-option-yn +# Usage: flag := $(call rustc-option-yn,-Cinstrument-coverage) +rustc-option-yn = $(call try-run,\ + $(RUSTC) $(KBUILD_RUSTFLAGS) $(1) --crate-type=rlib /dev/null -o "$$TMP",y,n) -- 2.46.0.rc1.232.g9752f9e123-goog ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] kbuild: rust: Enable KASAN support 2024-07-25 23:20 [PATCH 0/2] Rust KASAN Support Matthew Maurer 2024-07-25 23:20 ` [PATCH 1/2] kbuild: rust: Define probing macros for rustc Matthew Maurer @ 2024-07-25 23:20 ` Matthew Maurer 2024-07-25 23:57 ` Andrey Konovalov 1 sibling, 1 reply; 6+ messages in thread From: Matthew Maurer @ 2024-07-25 23:20 UTC (permalink / raw) To: Andrey Ryabinin, Masahiro Yamada, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Nathan Chancellor Cc: Matthew Maurer, Alexander Potapenko, Andrey Konovalov, Dmitry Vyukov, Vincenzo Frascino, Nicolas Schier, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Nick Desaulniers, Bill Wendling, Justin Stitt, kasan-dev, linux-kbuild, linux-kernel, rust-for-linux, llvm Rust supports KASAN via LLVM, but prior to this patch, the flags aren't set properly. Suggested-by: Miguel Ojeda <ojeda@kernel.org> Signed-off-by: Matthew Maurer <mmaurer@google.com> --- scripts/Makefile.kasan | 46 +++++++++++++++++++++++++++++++++++++++++- scripts/Makefile.lib | 3 +++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index 390658a2d5b7..84572c473e23 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -12,6 +12,7 @@ endif KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET) cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1))) +rustc-param = $(call rustc-option, -Cllvm-args=-$(1),) ifdef CONFIG_KASAN_STACK stack_enable := 1 @@ -28,6 +29,7 @@ else endif CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address +RUSTFLAGS_KASAN_MINIMAL := -Zsanitizer=kernel-address -Zsanitizer-recover=kernel-address # -fasan-shadow-offset fails without -fsanitize CFLAGS_KASAN_SHADOW := $(call cc-option, -fsanitize=kernel-address \ @@ -36,13 +38,36 @@ CFLAGS_KASAN_SHADOW := $(call cc-option, -fsanitize=kernel-address \ -mllvm -asan-mapping-offset=$(KASAN_SHADOW_OFFSET))) ifeq ($(strip $(CFLAGS_KASAN_SHADOW)),) + KASAN_SHADOW_SUPPORTED := n +else + KASAN_SHADOW_SUPPORTED := y +endif + +ifdef CONFIG_RUST + RUSTFLAGS_KASAN_SHADOW := $(call rustc-option $(RUSTFLAGS_KASAN_MINIMAL) \ + -Cllvm-args=-asan-mapping-offset=$(KASAN_SHADOW_OFFSET)) + ifeq ($(strip $(RUSTFLAGS_KASAN_SHADOW)),) + KASAN_SHADOW_SUPPORTED := n + endif +endif + +ifeq ($(KASAN_SHADOW_SUPPORTED),y) CFLAGS_KASAN := $(CFLAGS_KASAN_MINIMAL) + ifdef CONFIG_RUST + RUSTFLAGS_KASAN := $(RUSTFLAGS_KASAN_MINIMAL) + endif else # Now add all the compiler specific options that are valid standalone CFLAGS_KASAN := $(CFLAGS_KASAN_SHADOW) \ $(call cc-param,asan-globals=1) \ $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ $(call cc-param,asan-instrument-allocas=1) + ifdef CONFIG_RUST + RUSTFLAGS_KASAN := $(RUSTFLAGS_KASAN_SHADOW) \ + $(call rustc-param,asan-globals=1) \ + $(call rustc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ + $(call rustc-param,asan-instrument-allocas=1) + endif endif CFLAGS_KASAN += $(call cc-param,asan-stack=$(stack_enable)) @@ -52,6 +77,11 @@ CFLAGS_KASAN += $(call cc-param,asan-stack=$(stack_enable)) # memintrinsics won't be checked by KASAN on GENERIC_ENTRY architectures. CFLAGS_KASAN += $(call cc-param,asan-kernel-mem-intrinsic-prefix=1) +ifdef CONFIG_RUST + RUSTFLAGS_KASAN += $(call rustc-param,asan-stack=$(stack_enable)) + RUSTFLAGS_KASAN += $(call rustc-param,asan-kernel-mem-intrinsic-prefix=1) +endif + endif # CONFIG_KASAN_GENERIC ifdef CONFIG_KASAN_SW_TAGS @@ -73,6 +103,20 @@ ifeq ($(call clang-min-version, 150000)$(call gcc-min-version, 130000),y) CFLAGS_KASAN += $(call cc-param,hwasan-kernel-mem-intrinsic-prefix=1) endif +ifdef CONFIG_RUST + ifdef CONFIG_KASAN_INLINE + rust_instrumentation_flags := $(call rustc-param,hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET)) + else + rust_instrumentation_flags := $(call rustc-param,hwasan-instrument-with-calls=1) + endif + RUSTFLAGS_KASAN := -Zsanitizer=kernel-hwaddress -Zsanitizer-recover=kernel-hwaddress \ + $(call rustc-param,hwasan-instrument-stack=$(stack_enable)) \ + $(call rustc-param,hwasan-use-short-granules=0) \ + $(call rustc-param,hwasan-inline-all-checks=0) \ + $(call rustc-param,hwasan-kernel-mem-intrinsic-prefix=1) \ + $(instrumentation_flags) +endif + endif # CONFIG_KASAN_SW_TAGS -export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE +export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE RUSTFLAGS_KASAN diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 9f06f6aaf7fc..4a58636705e0 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -167,6 +167,9 @@ ifneq ($(CONFIG_KASAN_HW_TAGS),y) _c_flags += $(if $(patsubst n%,, \ $(KASAN_SANITIZE_$(target-stem).o)$(KASAN_SANITIZE)$(is-kernel-object)), \ $(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE)) +_rust_flags += $(if $(patsubst n%,, \ + $(KASAN_SANITIZE_$(target-stem).o)$(KASAN_SANITIZE)$(is-kernel-object)), \ + $(RUSTFLAGS_KASAN)) endif endif -- 2.46.0.rc1.232.g9752f9e123-goog ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] kbuild: rust: Enable KASAN support 2024-07-25 23:20 ` [PATCH 2/2] kbuild: rust: Enable KASAN support Matthew Maurer @ 2024-07-25 23:57 ` Andrey Konovalov 2024-07-26 10:23 ` Dmitry Vyukov 0 siblings, 1 reply; 6+ messages in thread From: Andrey Konovalov @ 2024-07-25 23:57 UTC (permalink / raw) To: Matthew Maurer Cc: Andrey Ryabinin, Masahiro Yamada, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Nathan Chancellor, Alexander Potapenko, Dmitry Vyukov, Vincenzo Frascino, Nicolas Schier, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Nick Desaulniers, Bill Wendling, Justin Stitt, kasan-dev, linux-kbuild, linux-kernel, rust-for-linux, llvm On Fri, Jul 26, 2024 at 1:21 AM Matthew Maurer <mmaurer@google.com> wrote: > > Rust supports KASAN via LLVM, but prior to this patch, the flags aren't > set properly. > > Suggested-by: Miguel Ojeda <ojeda@kernel.org> > Signed-off-by: Matthew Maurer <mmaurer@google.com> Hi Matthew, > CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address > +RUSTFLAGS_KASAN_MINIMAL := -Zsanitizer=kernel-address -Zsanitizer-recover=kernel-address If I recall correctly, the reason we need CFLAGS_KASAN_MINIMAL is because older compilers don't support some of the additional options. With Rust, this shouldn't be needed, as it requires a modern compiler that does support all needed options. E.g., for CONFIG_KASAN_SW_TAGS, we also don't have the MINIMAL thing for the same reason. (Possibly, we also already don't need this for GENERIC KASAN, as the GCC version requirement was raised a few times since KASAN was introduced.) > # Now add all the compiler specific options that are valid standalone > CFLAGS_KASAN := $(CFLAGS_KASAN_SHADOW) \ > $(call cc-param,asan-globals=1) \ > $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ > $(call cc-param,asan-instrument-allocas=1) > + ifdef CONFIG_RUST > + RUSTFLAGS_KASAN := $(RUSTFLAGS_KASAN_SHADOW) \ > + $(call rustc-param,asan-globals=1) \ > + $(call rustc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ > + $(call rustc-param,asan-instrument-allocas=1) I'm wondering if there's a way to avoid duplicating all options for Rust. Perhaps, some kind of macro? Thanks! ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] kbuild: rust: Enable KASAN support 2024-07-25 23:57 ` Andrey Konovalov @ 2024-07-26 10:23 ` Dmitry Vyukov 2024-07-26 12:36 ` Miguel Ojeda 0 siblings, 1 reply; 6+ messages in thread From: Dmitry Vyukov @ 2024-07-26 10:23 UTC (permalink / raw) To: Andrey Konovalov Cc: Matthew Maurer, Andrey Ryabinin, Masahiro Yamada, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Nathan Chancellor, Alexander Potapenko, Vincenzo Frascino, Nicolas Schier, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Nick Desaulniers, Bill Wendling, Justin Stitt, kasan-dev, linux-kbuild, linux-kernel, rust-for-linux, llvm, Brendan Higgins On Fri, 26 Jul 2024 at 01:57, Andrey Konovalov <andreyknvl@gmail.com> wrote: > > On Fri, Jul 26, 2024 at 1:21 AM Matthew Maurer <mmaurer@google.com> wrote: > > > > Rust supports KASAN via LLVM, but prior to this patch, the flags aren't > > set properly. This is great, thanks, Matthew! Does Rust support KUnit tests? It would be good to add at least a simple positive test similar to the existing ones so that the support does not get rotten soon. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/kasan/kasan_test.c > > Suggested-by: Miguel Ojeda <ojeda@kernel.org> > > Signed-off-by: Matthew Maurer <mmaurer@google.com> > > Hi Matthew, > > > CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address > > +RUSTFLAGS_KASAN_MINIMAL := -Zsanitizer=kernel-address -Zsanitizer-recover=kernel-address > > If I recall correctly, the reason we need CFLAGS_KASAN_MINIMAL is > because older compilers don't support some of the additional options. > With Rust, this shouldn't be needed, as it requires a modern compiler > that does support all needed options. E.g., for CONFIG_KASAN_SW_TAGS, > we also don't have the MINIMAL thing for the same reason. (Possibly, > we also already don't need this for GENERIC KASAN, as the GCC version > requirement was raised a few times since KASAN was introduced.) > > > # Now add all the compiler specific options that are valid standalone > > CFLAGS_KASAN := $(CFLAGS_KASAN_SHADOW) \ > > $(call cc-param,asan-globals=1) \ > > $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ > > $(call cc-param,asan-instrument-allocas=1) > > + ifdef CONFIG_RUST > > + RUSTFLAGS_KASAN := $(RUSTFLAGS_KASAN_SHADOW) \ > > + $(call rustc-param,asan-globals=1) \ > > + $(call rustc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ > > + $(call rustc-param,asan-instrument-allocas=1) > > I'm wondering if there's a way to avoid duplicating all options for > Rust. Perhaps, some kind of macro? > > Thanks! ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] kbuild: rust: Enable KASAN support 2024-07-26 10:23 ` Dmitry Vyukov @ 2024-07-26 12:36 ` Miguel Ojeda 0 siblings, 0 replies; 6+ messages in thread From: Miguel Ojeda @ 2024-07-26 12:36 UTC (permalink / raw) To: Dmitry Vyukov Cc: Andrey Konovalov, Matthew Maurer, Andrey Ryabinin, Masahiro Yamada, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Nathan Chancellor, Alexander Potapenko, Vincenzo Frascino, Nicolas Schier, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Nick Desaulniers, Bill Wendling, Justin Stitt, kasan-dev, linux-kbuild, linux-kernel, rust-for-linux, llvm, Brendan Higgins On Fri, Jul 26, 2024 at 12:23 PM Dmitry Vyukov <dvyukov@google.com> wrote: > > This is great, thanks, Matthew! > > Does Rust support KUnit tests? > It would be good to add at least a simple positive test similar to the > existing ones so that the support does not get rotten soon. > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/kasan/kasan_test.c Yeah, we have Rust doctests converted into KUnit tests, as well as upcoming `#[test]`s support (also handled as KUnit tests). For this, I assume the latter would make more sense, but we have to merge it. Cheers, Miguel ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-07-26 12:36 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-07-25 23:20 [PATCH 0/2] Rust KASAN Support Matthew Maurer 2024-07-25 23:20 ` [PATCH 1/2] kbuild: rust: Define probing macros for rustc Matthew Maurer 2024-07-25 23:20 ` [PATCH 2/2] kbuild: rust: Enable KASAN support Matthew Maurer 2024-07-25 23:57 ` Andrey Konovalov 2024-07-26 10:23 ` Dmitry Vyukov 2024-07-26 12:36 ` Miguel Ojeda
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).