From 95afd9a3ed5c25b44c2910962774c37466ff3b50 Mon Sep 17 00:00:00 2001 From: Jiakai Xu Date: Tue, 26 May 2026 03:15:17 +0000 Subject: [PATCH] RISC-V: KVM: Fix NULL pointer dereference in AIA IMSIC functions Fuzzer reported a NULL pointer dereference in kvm_riscv_vcpu_aia_imsic_put() when a VCPU's imsic_state was NULL while kvm_riscv_aia_initialized() returned true. The global initialized flag is set per-VM in aia_init(), but imsic_state is allocated per-VCPU in kvm_riscv_vcpu_aia_imsic_init(). If a VCPU is created after aia_init() has already run, its imsic_state remains NULL while the global flag is true. When this VCPU is preempted, kvm_sched_out() calls kvm_arch_vcpu_put() -> kvm_riscv_vcpu_aia_put() -> kvm_riscv_vcpu_aia_imsic_put() which dereferences NULL. Add NULL pointer guards to kvm_riscv_vcpu_aia_imsic_put(), consistent with the NULL checks already present in all other functions in the same file. Also add a NULL guard to kvm_riscv_vcpu_aia_imsic_release() and kvm_riscv_vcpu_aia_imsic_has_interrupt() for the same reason. Fixes: 4cec89db80ba ("RISC-V: KVM: Move HGEI[E|P] CSR access to IMSIC virtualization") Signed-off-by: Jiakai Xu Signed-off-by: Jiakai Xu Assisted-by: YuanSheng:DeepSeek-V3.2 Signed-off-by: Linux RISC-V bot --- arch/riscv/kvm/aia_imsic.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c index 8786f52cf65a2c..d38f5de0834c5b 100644 --- a/arch/riscv/kvm/aia_imsic.c +++ b/arch/riscv/kvm/aia_imsic.c @@ -683,6 +683,9 @@ bool kvm_riscv_vcpu_aia_imsic_has_interrupt(struct kvm_vcpu *vcpu) unsigned long flags; bool ret = false; + if (!imsic) + return false; + /* * The IMSIC SW-file directly injects interrupt via hvip so * only check for interrupt when IMSIC VS-file is being used. @@ -722,6 +725,9 @@ void kvm_riscv_vcpu_aia_imsic_put(struct kvm_vcpu *vcpu) struct imsic *imsic = vcpu->arch.aia_context.imsic_state; unsigned long flags; + if (!imsic) + return; + if (!kvm_vcpu_is_blocking(vcpu)) return; @@ -738,6 +744,9 @@ void kvm_riscv_vcpu_aia_imsic_release(struct kvm_vcpu *vcpu) int old_vsfile_hgei, old_vsfile_cpu; struct imsic *imsic = vcpu->arch.aia_context.imsic_state; + if (!imsic) + return; + /* Read and clear IMSIC VS-file details */ write_lock_irqsave(&imsic->vsfile_lock, flags); old_vsfile_hgei = imsic->vsfile_hgei;