[PATCH 2/2] kbuild: rust: Enable KASAN support

0 views
Skip to first unread message

Matthew Maurer

unread,
Jul 25, 2024, 7:21:47 PM (2 days ago) Jul 25
to Andrey Ryabinin, Masahiro Yamada, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Nathan Chancellor, 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, kasa...@googlegroups.com, linux-...@vger.kernel.org, linux-...@vger.kernel.org, rust-fo...@vger.kernel.org, ll...@lists.linux.dev
Rust supports KASAN via LLVM, but prior to this patch, the flags aren't
set properly.

Suggested-by: Miguel Ojeda <oj...@kernel.org>
Signed-off-by: Matthew Maurer <mma...@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

Andrey Konovalov

unread,
Jul 25, 2024, 7:57:14 PM (2 days ago) Jul 25
to Matthew Maurer, 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, kasa...@googlegroups.com, linux-...@vger.kernel.org, linux-...@vger.kernel.org, rust-fo...@vger.kernel.org, ll...@lists.linux.dev
On Fri, Jul 26, 2024 at 1:21 AM Matthew Maurer <mma...@google.com> wrote:
>
> Rust supports KASAN via LLVM, but prior to this patch, the flags aren't
> set properly.
>
> Suggested-by: Miguel Ojeda <oj...@kernel.org>
> Signed-off-by: Matthew Maurer <mma...@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!

Dmitry Vyukov

unread,
Jul 26, 2024, 6:23:15 AM (yesterday) Jul 26
to 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, kasa...@googlegroups.com, linux-...@vger.kernel.org, linux-...@vger.kernel.org, rust-fo...@vger.kernel.org, ll...@lists.linux.dev, Brendan Higgins
On Fri, 26 Jul 2024 at 01:57, Andrey Konovalov <andre...@gmail.com> wrote:
>
> On Fri, Jul 26, 2024 at 1:21 AM Matthew Maurer <mma...@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

Miguel Ojeda

unread,
Jul 26, 2024, 8:36:44 AM (yesterday) Jul 26
to Dmitry Vyukov, 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, kasa...@googlegroups.com, linux-...@vger.kernel.org, linux-...@vger.kernel.org, rust-fo...@vger.kernel.org, ll...@lists.linux.dev, Brendan Higgins
On Fri, Jul 26, 2024 at 12:23 PM Dmitry Vyukov <dvy...@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
Reply all
Reply to author
Forward
0 new messages