Message ID | 20240814085618.968833-1-samuel.holland@sifive.com (mailing list archive) |
---|---|
Headers | show |
Series | kasan: RISC-V support for KASAN_SW_TAGS using pointer masking | expand |
On Wed, Aug 14, 2024 at 10:56 AM Samuel Holland <samuel.holland@sifive.com> wrote: > > 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. This is awesome! > 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: Hm, this test passes on arm64 for me. Could you share the kernel config that you used? > > ... > 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 >