[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <4a245fff-cc46-44d1-a5f9-fd2f1c3764ae@sifive.com>
Date: Mon, 21 Oct 2024 20:13:41 -0500
From: Samuel Holland <samuel.holland@...ive.com>
To: Andrey Konovalov <andreyknvl@...il.com>
Cc: Palmer Dabbelt <palmer@...belt.com>, linux-riscv@...ts.infradead.org,
Andrey Ryabinin <ryabinin.a.a@...il.com>,
Alexander Potapenko <glider@...gle.com>, Dmitry Vyukov <dvyukov@...gle.com>,
Vincenzo Frascino <vincenzo.frascino@....com>, kasan-dev@...glegroups.com,
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
Subject: Re: [RFC PATCH 0/7] kasan: RISC-V support for KASAN_SW_TAGS using
pointer masking
Hi Andrey,
On 2024-08-14 11:03 AM, Andrey Konovalov wrote:
> On Wed, Aug 14, 2024 at 10:56 AM Samuel Holland
> <samuel.holland@...ive.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?
I've attached a config where the test fails in arm64 QEMU (virt machine).
However, if I apply the patch below, the test passes. The test also passes with
a riscv defconfig build and the patch below. I think the issue is that the KUnit
test fails if it allocates from the initial percpu area created at boot. With
something like arm64 defconfig, or by decreasing the size of the initial percpu
area with my patch, the test allocates from an area with non-default KASAN tags
and passes.
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index b6321fc49159..26b97c79ad7c 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -43,7 +43,7 @@
#ifdef CONFIG_RANDOM_KMALLOC_CACHES
#define PERCPU_DYNAMIC_SIZE_SHIFT 12
#else
-#define PERCPU_DYNAMIC_SIZE_SHIFT 10
+#define PERCPU_DYNAMIC_SIZE_SHIFT 8
#endif
Regards,
Samuel
>>
>> ...
>> 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
>>
View attachment "arm64_kasan_kunit_fail.config" of type "text/plain" (104270 bytes)
Powered by blists - more mailing lists