From: Daniel Axtens <hidden> Date: 2021-06-17 09:30:40
Building on the work of Christophe, Aneesh and Balbir, I've ported
KASAN to 64-bit Book3S kernels running on the Radix MMU. I've been
trying this for a while, but we keep having collisions between the
kasan code in the mm tree and the code I want to put in to the ppc
tree.
This series just contains the kasan core changes that we need. These
can go in via the mm tree. I will then propose the powerpc changes for
a later cycle. (The most recent RFC for the powerpc changes is in the
v12 series at
https://lore.kernel.org/linux-mm/20210615014705.2234866-1-dja@axtens.net/
)
v15 applies to next-20210611. There should be no noticeable changes to
other platforms.
Changes since v14: Included a bunch of Reviewed-by:s, thanks
Christophe and Marco. Cleaned up the build time error #ifdefs, thanks
Christophe.
Changes since v13: move the MAX_PTR_PER_* definitions out of kasan and
into pgtable.h. Add a build time error to hopefully prevent any
confusion about when the new hook is applicable. Thanks Marco and
Christophe.
Changes since v12: respond to Marco's review comments - clean up the
help for ARCH_DISABLE_KASAN_INLINE, and add an arch readiness check to
the new granule poisioning function. Thanks Marco.
Daniel Axtens (4):
kasan: allow an architecture to disable inline instrumentation
kasan: allow architectures to provide an outline readiness check
mm: define default MAX_PTRS_PER_* in include/pgtable.h
kasan: use MAX_PTRS_PER_* for early shadow tables
arch/s390/include/asm/pgtable.h | 2 --
include/asm-generic/pgtable-nop4d.h | 1 -
include/linux/kasan.h | 6 +++---
include/linux/pgtable.h | 22 ++++++++++++++++++++++
lib/Kconfig.kasan | 14 ++++++++++++++
mm/kasan/common.c | 4 ++++
mm/kasan/generic.c | 3 +++
mm/kasan/init.c | 6 +++---
mm/kasan/kasan.h | 6 ++++++
mm/kasan/shadow.c | 8 ++++++++
10 files changed, 63 insertions(+), 9 deletions(-)
--
2.30.2
From: Daniel Axtens <hidden> Date: 2021-06-17 09:30:45
For annoying architectural reasons, it's very difficult to support inline
instrumentation on powerpc64.*
Add a Kconfig flag to allow an arch to disable inline. (It's a bit
annoying to be 'backwards', but I'm not aware of any way to have
an arch force a symbol to be 'n', rather than 'y'.)
We also disable stack instrumentation in this case as it does things that
are functionally equivalent to inline instrumentation, namely adding
code that touches the shadow directly without going through a C helper.
* on ppc64 atm, the shadow lives in virtual memory and isn't accessible in
real mode. However, before we turn on virtual memory, we parse the device
tree to determine which platform and MMU we're running under. That calls
generic DT code, which is instrumented. Inline instrumentation in DT would
unconditionally attempt to touch the shadow region, which we won't have
set up yet, and would crash. We can make outline mode wait for the arch to
be ready, but we can't change what the compiler inserts for inline mode.
Reviewed-by: Marco Elver <elver@google.com>
Signed-off-by: Daniel Axtens <redacted>
---
lib/Kconfig.kasan | 14 ++++++++++++++
1 file changed, 14 insertions(+)
From: Daniel Axtens <hidden> Date: 2021-06-17 09:30:49
Allow architectures to define a kasan_arch_is_ready() hook that bails
out of any function that's about to touch the shadow unless the arch
says that it is ready for the memory to be accessed. This is fairly
uninvasive and should have a negligible performance penalty.
This will only work in outline mode, so an arch must specify
ARCH_DISABLE_KASAN_INLINE if it requires this.
Cc: Balbir Singh <bsingharora@gmail.com>
Cc: Aneesh Kumar K.V <redacted>
Suggested-by: Christophe Leroy <redacted>
Reviewed-by: Marco Elver <elver@google.com>
Signed-off-by: Daniel Axtens <redacted>
--
Both previous RFCs for ppc64 - by 2 different people - have
needed this trick! See:
- https://lore.kernel.org/patchwork/patch/592820/ # ppc64 hash series
- https://patchwork.ozlabs.org/patch/795211/ # ppc radix series
Build tested on arm64 with SW_TAGS and x86 with INLINE: the error fires
if I add a kasan_arch_is_ready define.
---
mm/kasan/common.c | 4 ++++
mm/kasan/generic.c | 3 +++
mm/kasan/kasan.h | 6 ++++++
mm/kasan/shadow.c | 8 ++++++++
4 files changed, 21 insertions(+)
From: Daniel Axtens <hidden> Date: 2021-06-17 09:31:24
powerpc has a variable number of PTRS_PER_*, set at runtime based
on the MMU that the kernel is booted under.
This means the PTRS_PER_* are no longer constants, and therefore
breaks the build. Switch to using MAX_PTRS_PER_*, which are constant.
Suggested-by: Christophe Leroy <redacted>
Suggested-by: Balbir Singh <bsingharora@gmail.com>
Reviewed-by: Christophe Leroy <redacted>
Reviewed-by: Balbir Singh <bsingharora@gmail.com>
Reviewed-by: Marco Elver <elver@google.com>
Signed-off-by: Daniel Axtens <redacted>
---
include/linux/kasan.h | 6 +++---
mm/kasan/init.c | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
From: Daniel Axtens <hidden> Date: 2021-06-17 09:31:24
Commit c65e774fb3f6 ("x86/mm: Make PGDIR_SHIFT and PTRS_PER_P4D variable")
made PTRS_PER_P4D variable on x86 and introduced MAX_PTRS_PER_P4D as a
constant for cases which need a compile-time constant (e.g. fixed-size
arrays).
powerpc likewise has boot-time selectable MMU features which can cause
other mm "constants" to vary. For KASAN, we have some static
PTE/PMD/PUD/P4D arrays so we need compile-time maximums for all these
constants. Extend the MAX_PTRS_PER_ idiom, and place default definitions
in include/pgtable.h. These define MAX_PTRS_PER_x to be PTRS_PER_x unless
an architecture has defined MAX_PTRS_PER_x in its arch headers.
Clean up pgtable-nop4d.h and s390's MAX_PTRS_PER_P4D definitions while
we're at it: both can just pick up the default now.
Reviewed-by: Christophe Leroy <redacted>
Reviewed-by: Marco Elver <elver@google.com>
Signed-off-by: Daniel Axtens <redacted>
---
s390 was compile tested only.
---
arch/s390/include/asm/pgtable.h | 2 --
include/asm-generic/pgtable-nop4d.h | 1 -
include/linux/pgtable.h | 22 ++++++++++++++++++++++
3 files changed, 22 insertions(+), 3 deletions(-)
On Thu, Jun 17, 2021 at 07:30:28PM +1000, Daniel Axtens wrote:
Building on the work of Christophe, Aneesh and Balbir, I've ported
KASAN to 64-bit Book3S kernels running on the Radix MMU. I've been
trying this for a while, but we keep having collisions between the
kasan code in the mm tree and the code I want to put in to the ppc
tree.
This series just contains the kasan core changes that we need. These
can go in via the mm tree. I will then propose the powerpc changes for
a later cycle. (The most recent RFC for the powerpc changes is in the
v12 series at
https://lore.kernel.org/linux-mm/20210615014705.2234866-1-dja@axtens.net/
)
v15 applies to next-20210611. There should be no noticeable changes to
other platforms.
Changes since v14: Included a bunch of Reviewed-by:s, thanks
Christophe and Marco. Cleaned up the build time error #ifdefs, thanks
Christophe.
Changes since v13: move the MAX_PTR_PER_* definitions out of kasan and
into pgtable.h. Add a build time error to hopefully prevent any
confusion about when the new hook is applicable. Thanks Marco and
Christophe.
Changes since v12: respond to Marco's review comments - clean up the
help for ARCH_DISABLE_KASAN_INLINE, and add an arch readiness check to
the new granule poisioning function. Thanks Marco.
Daniel Axtens (4):
kasan: allow an architecture to disable inline instrumentation
kasan: allow architectures to provide an outline readiness check
mm: define default MAX_PTRS_PER_* in include/pgtable.h
kasan: use MAX_PTRS_PER_* for early shadow tables
The series seems reasonable
Reviewed-by: Balbir Singh <bsingharora@gmail.com>
On Thu, Jun 17, 2021 at 12:30 PM Daniel Axtens [off-list ref] wrote:
quoted hunk
For annoying architectural reasons, it's very difficult to support inline
instrumentation on powerpc64.*
Add a Kconfig flag to allow an arch to disable inline. (It's a bit
annoying to be 'backwards', but I'm not aware of any way to have
an arch force a symbol to be 'n', rather than 'y'.)
We also disable stack instrumentation in this case as it does things that
are functionally equivalent to inline instrumentation, namely adding
code that touches the shadow directly without going through a C helper.
* on ppc64 atm, the shadow lives in virtual memory and isn't accessible in
real mode. However, before we turn on virtual memory, we parse the device
tree to determine which platform and MMU we're running under. That calls
generic DT code, which is instrumented. Inline instrumentation in DT would
unconditionally attempt to touch the shadow region, which we won't have
set up yet, and would crash. We can make outline mode wait for the arch to
be ready, but we can't change what the compiler inserts for inline mode.
Reviewed-by: Marco Elver <elver@google.com>
Signed-off-by: Daniel Axtens <redacted>
---
lib/Kconfig.kasan | 14 ++++++++++++++
1 file changed, 14 insertions(+)
This seems too wordy.
How about: "An architecture might not support inline instrumentation.
When this option is selected, inline and stack instrumentation are
disabled."
@@ -130,6 +139,7 @@ config KASAN_OUTLINE config KASAN_INLINE bool "Inline instrumentation"+ depends on !ARCH_DISABLE_KASAN_INLINE help Compiler directly inserts code checking shadow memory before memory accesses. This is faster than outline (in some workloads
@@ -141,6 +151,7 @@ endchoice config KASAN_STACK bool "Enable stack instrumentation (unsafe)" if CC_IS_CLANG && !COMPILE_TEST depends on KASAN_GENERIC || KASAN_SW_TAGS+ depends on !ARCH_DISABLE_KASAN_INLINE default y if CC_IS_GCC help The LLVM stack address sanitizer has a know problem that
@@ -154,6 +165,9 @@ config KASAN_STACK but clang users can still enable it for builds without CONFIG_COMPILE_TEST. On gcc it is assumed to always be safe to use and enabled by default.+ If the architecture disables inline instrumentation, this is
this => stack instrumentation
+ also disabled as it adds inline-style instrumentation that
+ is run unconditionally.
config KASAN_SW_TAGS_IDENTIFY
bool "Enable memory corruption identification"
--
2.30.2
On Thu, Jun 17, 2021 at 12:30 PM Daniel Axtens [off-list ref] wrote:
quoted hunk
Allow architectures to define a kasan_arch_is_ready() hook that bails
out of any function that's about to touch the shadow unless the arch
says that it is ready for the memory to be accessed. This is fairly
uninvasive and should have a negligible performance penalty.
This will only work in outline mode, so an arch must specify
ARCH_DISABLE_KASAN_INLINE if it requires this.
Cc: Balbir Singh <bsingharora@gmail.com>
Cc: Aneesh Kumar K.V <redacted>
Suggested-by: Christophe Leroy <redacted>
Reviewed-by: Marco Elver <elver@google.com>
Signed-off-by: Daniel Axtens <redacted>
--
Both previous RFCs for ppc64 - by 2 different people - have
needed this trick! See:
- https://lore.kernel.org/patchwork/patch/592820/ # ppc64 hash series
- https://patchwork.ozlabs.org/patch/795211/ # ppc radix series
Build tested on arm64 with SW_TAGS and x86 with INLINE: the error fires
if I add a kasan_arch_is_ready define.
---
mm/kasan/common.c | 4 ++++
mm/kasan/generic.c | 3 +++
mm/kasan/kasan.h | 6 ++++++
mm/kasan/shadow.c | 8 ++++++++
4 files changed, 21 insertions(+)
On Thu, Jun 17, 2021 at 12:30 PM Daniel Axtens [off-list ref] wrote:
quoted hunk
Commit c65e774fb3f6 ("x86/mm: Make PGDIR_SHIFT and PTRS_PER_P4D variable")
made PTRS_PER_P4D variable on x86 and introduced MAX_PTRS_PER_P4D as a
constant for cases which need a compile-time constant (e.g. fixed-size
arrays).
powerpc likewise has boot-time selectable MMU features which can cause
other mm "constants" to vary. For KASAN, we have some static
PTE/PMD/PUD/P4D arrays so we need compile-time maximums for all these
constants. Extend the MAX_PTRS_PER_ idiom, and place default definitions
in include/pgtable.h. These define MAX_PTRS_PER_x to be PTRS_PER_x unless
an architecture has defined MAX_PTRS_PER_x in its arch headers.
Clean up pgtable-nop4d.h and s390's MAX_PTRS_PER_P4D definitions while
we're at it: both can just pick up the default now.
Reviewed-by: Christophe Leroy <redacted>
Reviewed-by: Marco Elver <elver@google.com>
Signed-off-by: Daniel Axtens <redacted>
---
s390 was compile tested only.
---
arch/s390/include/asm/pgtable.h | 2 --
include/asm-generic/pgtable-nop4d.h | 1 -
include/linux/pgtable.h | 22 ++++++++++++++++++++++
3 files changed, 22 insertions(+), 3 deletions(-)
On Thu, Jun 17, 2021 at 12:30 PM Daniel Axtens [off-list ref] wrote:
quoted hunk
powerpc has a variable number of PTRS_PER_*, set at runtime based
on the MMU that the kernel is booted under.
This means the PTRS_PER_* are no longer constants, and therefore
breaks the build. Switch to using MAX_PTRS_PER_*, which are constant.
Suggested-by: Christophe Leroy <redacted>
Suggested-by: Balbir Singh <bsingharora@gmail.com>
Reviewed-by: Christophe Leroy <redacted>
Reviewed-by: Balbir Singh <bsingharora@gmail.com>
Reviewed-by: Marco Elver <elver@google.com>
Signed-off-by: Daniel Axtens <redacted>
---
include/linux/kasan.h | 6 +++---
mm/kasan/init.c | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
@@ -331,6 +331,10 @@ static inline bool ____kasan_slab_free(struct kmem_cache *cache, void *object,u8tag;void*tagged_object;+/* Bail if the arch isn't ready */
This comment brings no value. The fact that we bail is clear from the
following line. The comment should explain why we bail.
quoted
+ if (!kasan_arch_is_ready())
+ return false;
Fair enough, I've just dropped the comments as I don't think there's
really a lot of scope for the generic/core comment to explain why a
particular architecture might not be ready.
Have you considered including these checks into the high-level
wrappers in include/linux/kasan.h? Would that work?
I don't think those wrappers will catch the outline check functions
like __asan_load*, which also need guarding.
Kind regards,
Daniel