linux/arch/riscv
Jiakai Xu dec9ed9944 RISC-V: KVM: Fix use-after-free in kvm_riscv_gstage_get_leaf()
While fuzzing KVM on RISC-V, a use-after-free was observed in
kvm_riscv_gstage_get_leaf(),  where ptep_get() dereferences a
freed gstage page table page during gfn unmap.

The crash manifests as:
  use-after-free in ptep_get include/linux/pgtable.h:340 [inline]
  use-after-free in kvm_riscv_gstage_get_leaf arch/riscv/kvm/gstage.c:89
  Call Trace:
    ptep_get include/linux/pgtable.h:340 [inline]
    kvm_riscv_gstage_get_leaf+0x2ea/0x358 arch/riscv/kvm/gstage.c:89
    kvm_riscv_gstage_unmap_range+0xf0/0x308 arch/riscv/kvm/gstage.c:265
    kvm_unmap_gfn_range+0x168/0x1fc arch/riscv/kvm/mmu.c:256
    kvm_mmu_unmap_gfn_range virt/kvm/kvm_main.c:724 [inline]
  page last free pid 808 tgid 808 stack trace:
    kvm_riscv_mmu_free_pgd+0x1b6/0x26a arch/riscv/kvm/mmu.c:457
    kvm_arch_flush_shadow_all+0x1a/0x24 arch/riscv/kvm/mmu.c:134
    kvm_flush_shadow_all virt/kvm/kvm_main.c:344 [inline]

The UAF is caused by gstage page table walks running concurrently with
gstage pgd teardown. In particular, kvm_unmap_gfn_range() can traverse
gstage page tables while kvm_arch_flush_shadow_all() frees the pgd,
leading to use-after-free of page table pages.

Fix the issue by serializing gstage unmap and pgd teardown with
kvm->mmu_lock. Holding mmu_lock ensures that gstage page tables
remain valid for the duration of unmap operations and prevents
concurrent frees.

This matches existing RISC-V KVM usage of mmu_lock to protect gstage
map/unmap operations, e.g. kvm_riscv_mmu_iounmap.

Fixes: dd82e35638 ("RISC-V: KVM: Factor-out g-stage page table management")
Signed-off-by: Jiakai Xu <xujiakai2025@iscas.ac.cn>
Signed-off-by: Jiakai Xu <jiakaiPeanut@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260202040059.1801167-1-xujiakai2025@iscas.ac.cn
Signed-off-by: Anup Patel <anup@brainfault.org>
2026-03-06 11:20:30 +05:30
..
boot soc: devicetree updates for 7.0 2026-02-10 21:11:08 -08:00
configs RISC-V updates for v7.0 2026-02-12 19:17:44 -08:00
crypto lib/crypto: riscv/aes: Migrate optimized code into library 2026-01-12 11:39:58 -08:00
errata errata/sifive: remove unreliable warn_miss_errata 2026-01-25 21:09:04 -07:00
include Loongarch: 2026-02-13 11:31:15 -08:00
kernel Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses 2026-02-22 08:26:33 -08:00
kvm RISC-V: KVM: Fix use-after-free in kvm_riscv_gstage_get_leaf() 2026-03-06 11:20:30 +05:30
lib riscv: lib: optimize strlen loop efficiency 2026-02-09 15:27:33 -07:00
mm Loongarch: 2026-02-13 11:31:15 -08:00
net Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
purgatory kcfi: Rename CONFIG_CFI_CLANG to CONFIG_CFI 2025-09-24 14:29:14 -07:00
tools riscv: Stop considering R_RISCV_NONE as bad relocations 2025-07-16 08:13:55 -07:00
Kbuild
Kconfig RISC-V updates for v7.0 2026-02-12 19:17:44 -08:00
Kconfig.debug
Kconfig.errata riscv: ERRATA_STARFIVE_JH7100: Fix missing dependency on new CONFIG_CACHEMAINT_FOR_DMA 2026-01-15 18:13:04 -07:00
Kconfig.socs Initial Anlogic Platform Support 2025-11-21 21:29:57 +01:00
Kconfig.vendor riscv: Add xmipsexectl as a vendor extension 2025-09-18 20:36:00 -06:00
Makefile arch/riscv: add dual vdso creation logic and select vdso based on hw 2026-01-29 02:38:40 -07:00
Makefile.postlink