rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).