[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240814085618.968833-1-samuel.holland@sifive.com>
Date: Wed, 14 Aug 2024 01:55:28 -0700
From: Samuel Holland <samuel.holland@...ive.com>
To: Palmer Dabbelt <palmer@...belt.com>,
linux-riscv@...ts.infradead.org,
Andrey Ryabinin <ryabinin.a.a@...il.com>,
Alexander Potapenko <glider@...gle.com>,
Andrey Konovalov <andreyknvl@...il.com>,
Dmitry Vyukov <dvyukov@...gle.com>,
Vincenzo Frascino <vincenzo.frascino@....com>,
kasan-dev@...glegroups.com
Cc: llvm@...ts.linux.dev,
linux-kernel@...r.kernel.org,
Alexandre Ghiti <alexghiti@...osinc.com>,
Evgenii Stepanov <eugenis@...gle.com>,
Andrew Morton <akpm@...ux-foundation.org>,
linux-arm-kernel@...ts.infradead.org,
Samuel Holland <samuel.holland@...ive.com>
Subject: [RFC PATCH 0/7] kasan: RISC-V support for KASAN_SW_TAGS using pointer masking
This series implements support for software tag-based KASAN using the
RISC-V pointer masking extension[1], which supports 7 and/or 16-bit
tags. This implementation uses 7-bit tags, so it is compatible with
either hardware mode. Patch 3 adds supports for KASAN_SW_TAGS with tag
widths other than 8 bits.
Pointer masking is an optional ISA extension, and it must be enabled
using an SBI call to firmware on each CPU. If the SBI call fails on the
boot CPU, KASAN is globally disabled. Patch 2 adds support for boot-time
disabling of KASAN_SW_TAGS.
The SBI call is part of the upcoming SBI Firmware Features (FWFT)
extension[2][3]. Since generic FWFT support is not yet merged to Linux,
I open-coded the sbi_ecall() in this RFC to keep this series focused.
With my RISC-V KASAN fixes series[4] applied, this implementation passes
all but one of the KASAN KUnit tests. It fails vmalloc_percpu(), which
also fails on arm64:
...
ok 65 vmalloc_oob
ok 66 vmap_tags
ok 67 vm_map_ram_tags
# vmalloc_percpu: EXPECTATION FAILED at mm/kasan/kasan_test.c:1785
Expected (u8)((u8)((u64)(c_ptr) >> 57)) < (u8)0x7f, but
(u8)((u8)((u64)(c_ptr) >> 57)) == 127 (0x7f)
(u8)0x7f == 127 (0x7f)
# vmalloc_percpu: EXPECTATION FAILED at mm/kasan/kasan_test.c:1785
Expected (u8)((u8)((u64)(c_ptr) >> 57)) < (u8)0x7f, but
(u8)((u8)((u64)(c_ptr) >> 57)) == 127 (0x7f)
(u8)0x7f == 127 (0x7f)
# vmalloc_percpu: EXPECTATION FAILED at mm/kasan/kasan_test.c:1785
Expected (u8)((u8)((u64)(c_ptr) >> 57)) < (u8)0x7f, but
(u8)((u8)((u64)(c_ptr) >> 57)) == 127 (0x7f)
(u8)0x7f == 127 (0x7f)
# vmalloc_percpu: EXPECTATION FAILED at mm/kasan/kasan_test.c:1785
Expected (u8)((u8)((u64)(c_ptr) >> 57)) < (u8)0x7f, but
(u8)((u8)((u64)(c_ptr) >> 57)) == 127 (0x7f)
(u8)0x7f == 127 (0x7f)
not ok 68 vmalloc_percpu
ok 69 match_all_not_assigned
ok 70 match_all_ptr_tag
...
# kasan: pass:62 fail:1 skip:8 total:71
# Totals: pass:62 fail:1 skip:8 total:71
I'm not sure how I'm supposed to hook in to the percpu allocator.
When running with hardware or firmware that doesn't support pointer
masking, the kernel still boots successfully:
kasan: test: Can't run KASAN tests with KASAN disabled
# kasan: # failed to initialize (-1)
not ok 1 kasan
If stack tagging is enabled but pointer masking is unsupported, an extra
change (patch 7) is required so all pointers to stack variables are
tagged with KASAN_TAG_KERENL and can be dereferenced. I'm not sure if
this change should be RISC-V specific or made more generic.
This series can be tested by applying patch series to LLVM[5], QEMU[6],
and OpenSBI[7].
[1]: https://github.com/riscv/riscv-j-extension/releases/download/pointer-masking-v1.0.0-rc2/pointer-masking-v1.0.0-rc2.pdf
[2]: https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/src/ext-firmware-features.adoc
[3]: https://github.com/riscv-non-isa/riscv-sbi-doc/pull/161
[4]: https://lore.kernel.org/linux-riscv/20240801033725.28816-1-samuel.holland@sifive.com/
[5]: https://github.com/SiFiveHolland/llvm-project/commits/up/riscv64-kernel-hwasan
[6]: https://lore.kernel.org/qemu-devel/20240511101053.1875596-1-me@deliversmonkey.space/
[7]: https://lists.infradead.org/pipermail/opensbi/2024-August/007244.html
Samuel Holland (7):
kasan: sw_tags: Use arithmetic shift for shadow computation
kasan: sw_tags: Check kasan_flag_enabled at runtime
kasan: sw_tags: Support tag widths less than 8 bits
riscv: Do not rely on KASAN to define the memory layout
riscv: Align the sv39 linear map to 16 GiB
riscv: Implement KASAN_SW_TAGS
kasan: sw_tags: Support runtime stack tagging control for RISC-V
Documentation/arch/riscv/vm-layout.rst | 10 ++---
Documentation/dev-tools/kasan.rst | 14 +++---
arch/arm64/Kconfig | 10 ++---
arch/arm64/include/asm/kasan.h | 6 ++-
arch/arm64/include/asm/memory.h | 8 ++++
arch/arm64/include/asm/uaccess.h | 1 +
arch/arm64/mm/kasan_init.c | 7 ++-
arch/riscv/Kconfig | 4 +-
arch/riscv/include/asm/cache.h | 4 ++
arch/riscv/include/asm/kasan.h | 29 +++++++++++-
arch/riscv/include/asm/page.h | 21 +++++++--
arch/riscv/include/asm/pgtable.h | 6 +++
arch/riscv/include/asm/tlbflush.h | 4 +-
arch/riscv/kernel/setup.c | 6 +++
arch/riscv/kernel/smpboot.c | 8 +++-
arch/riscv/lib/Makefile | 2 +
arch/riscv/lib/kasan_sw_tags.S | 61 ++++++++++++++++++++++++++
arch/riscv/mm/init.c | 2 +-
arch/riscv/mm/kasan_init.c | 30 ++++++++++++-
arch/riscv/mm/physaddr.c | 4 ++
include/linux/kasan-enabled.h | 15 +++----
include/linux/kasan-tags.h | 13 +++---
include/linux/kasan.h | 10 ++++-
mm/kasan/hw_tags.c | 10 -----
mm/kasan/kasan.h | 2 +
mm/kasan/sw_tags.c | 9 ++++
mm/kasan/tags.c | 10 +++++
scripts/Makefile.kasan | 5 +++
scripts/gdb/linux/mm.py | 5 ++-
29 files changed, 255 insertions(+), 61 deletions(-)
create mode 100644 arch/riscv/lib/kasan_sw_tags.S
--
2.45.1
Powered by blists - more mailing lists