mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/5] riscv: kfence: Handle the spurious fault after kfence_unprotect(), and related fixes
@ 2026-03-03  5:29 Vivian Wang
  2026-03-03  5:29 ` [PATCH v2 1/5] riscv: mm: Extract helper mark_new_valid_map() Vivian Wang
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Vivian Wang @ 2026-03-03  5:29 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Alexandre Ghiti,
	Alexander Potapenko, Marco Elver, Dmitry Vyukov, Yunhui Cui
  Cc: linux-riscv, linux-kernel, kasan-dev, Palmer Dabbelt, stable,
	Vivian Wang, Yanko Kaneti

kfence_unprotect() on RISC-V doesn't flush TLBs, because we can't send
IPIs in some contexts where kfence objects are allocated. This leads to
spurious faults and kfence false positives.

Avoid these spurious faults using the same "new_vmalloc" mechanism,
which I have renamed new_valid_map_cpus to avoid confusion, since the
kfence pool comes from the linear mapping, not vmalloc.

Commit b3431a8bb336 ("riscv: Fix IPIs usage in kfence_protect_page()")
only seemed to consider false negatives, which are indeed tolerable.
False positives on the other hand are not okay since they waste
developer time (or just my time somehow?) and spam kmsg making
diagnosing other problems difficult.

Patch 2 is the implementation to poke (what was called) new_vmalloc upon
kfence_unprotect(). Patch 1 is some refactoring that patch 2 depends on.
Patch 3 through 5 are some additional refactoring and minor fixes.

How this was found
------------------

This came up after a user reported some nonsensical kfence
use-after-free reports relating to k1_emac on SpacemiT K1, like this:

    [   64.160199] ==================================================================
    [   64.164773] BUG: KFENCE: use-after-free read in sk_skb_reason_drop+0x22/0x1e8
    [   64.164773]
    [   64.173365] Use-after-free read at 0xffffffd77fecc0cc (in kfence-#101):
    [   64.179962]  sk_skb_reason_drop+0x22/0x1e8
    [   64.179972]  dev_kfree_skb_any_reason+0x32/0x3c

    [...]

    [   64.181440] kfence-#101: 0xffffffd77fecc000-0xffffffd77fecc0cf, size=208, cache=skbuff_head_cache
    [   64.181440]
    [   64.181450] allocated by task 142 on cpu 1 at 63.665866s (0.515583s ago):
    [   64.181476]  __alloc_skb+0x66/0x244
    [   64.181484]  alloc_skb_with_frags+0x3a/0x1ac

    [...]

    [   64.182917] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.0.0-rc1-dirty #34 PREEMPTLAZY
    [   64.182926] Hardware name: Banana Pi BPI-F3 (DT)
    [   64.183111] ==================================================================

In particular, these supposed use-after-free accesses:

- Were never reported by KASAN despite being rather easy to reproduce
- Never contain a "freed by task" section
- Never happen on the same CPU as the "allocated by task" info
- And, most importantly, were not found to have been caused by the
  object being freed by anyone at that point

An interesting corollary of this observation is that the SpacemiT X60
CPU *does* cache invalid PTEs, and for a significant amount of time, or
at least long enough to be observable in practice. Or maybe only in an
wfi, given how most of these reports I've seen had the faulting CPU in
an IRQ?

---
Changes in v2:
- Reordered patches 1 through 3 to minimize what needs to be backported
- (New patch 4) Change the bitmap to use DECLARE_BITMAP (Alexander)
- (New patch 5) Additional fix
- Link to v1: https://lore.kernel.org/r/20260302-handle-kfence-protect-spurious-fault-v1-0-25c82c879d9c@iscas.ac.cn

---
Vivian Wang (5):
      riscv: mm: Extract helper mark_new_valid_map()
      riscv: kfence: Call mark_new_valid_map() for kfence_unprotect()
      riscv: mm: Rename new_vmalloc into new_valid_map_cpus
      riscv: mm: Use the bitmap API for new_valid_map_cpus
      riscv: mm: Unconditionally sfence.vma for spurious fault

 arch/riscv/include/asm/cacheflush.h | 25 +++++++++---------
 arch/riscv/include/asm/kfence.h     |  7 +++--
 arch/riscv/kernel/entry.S           | 51 ++++++++++++++++++++-----------------
 arch/riscv/mm/init.c                |  2 +-
 4 files changed, 47 insertions(+), 38 deletions(-)
---
base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
change-id: 20260228-handle-kfence-protect-spurious-fault-62100afb9734

Best regards,
-- 
Vivian "dramforever" Wang


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-06-07  6:43 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-03-03  5:29 [PATCH v2 0/5] riscv: kfence: Handle the spurious fault after kfence_unprotect(), and related fixes Vivian Wang
2026-03-03  5:29 ` [PATCH v2 1/5] riscv: mm: Extract helper mark_new_valid_map() Vivian Wang
2026-03-03  5:29 ` [PATCH v2 2/5] riscv: kfence: Call mark_new_valid_map() for kfence_unprotect() Vivian Wang
2026-03-03  5:29 ` [PATCH v2 3/5] riscv: mm: Rename new_vmalloc into new_valid_map_cpus Vivian Wang
2026-03-03  5:29 ` [PATCH v2 4/5] riscv: mm: Use the bitmap API for new_valid_map_cpus Vivian Wang
2026-03-03  5:29 ` [PATCH v2 5/5] riscv: mm: Unconditionally sfence.vma for spurious fault Vivian Wang
2026-06-07  6:40 ` [PATCH v2 0/5] riscv: kfence: Handle the spurious fault after kfence_unprotect(), and related fixes Paul Walmsley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®