[PATCH v2] RISC-V: KVM: Synchronize hrtimer callback during teardown
Anup Patel
anup at brainfault.org
Thu Sep 10 01:44:34 PDT 2026
On Fri, Jul 31, 2026 at 10:05 PM Myeonghun Pak <mhun512 at gmail.com> wrote:
>
> The non-Sstc hrtimer callback clears next_set before its final uses of
> the enclosing vCPU. If teardown observes next_set as false while the
> callback is still running, kvm_riscv_vcpu_timer_cancel() skips
> hrtimer_cancel() and kvm_destroy_vcpus() can free the vCPU before the
> callback enters kvm_riscv_vcpu_set_interrupt().
>
> A guest can arm the timer with SBI TIME and request shutdown with SBI
> legacy shutdown or SRST. A VMM that honors KVM_EXIT_SYSTEM_EVENT and
> destroys the VM supplies the teardown side of the race; no post-launch
> host ioctl is needed to arm or request teardown.
>
> On upstream master 62cc90241548, generic KASAN reported:
>
> BUG: KASAN: slab-use-after-free in do_raw_spin_lock
> Write of size 4 at addr ff60000005e58898
>
> kvm_riscv_vcpu_set_interrupt
> kvm_riscv_vcpu_hrtimer_expired
> __hrtimer_run_queues
> hrtimer_interrupt
>
> The object was allocated by KVM_CREATE_VCPU and freed concurrently by:
>
> kvm_destroy_vcpus
> kvm_arch_destroy_vm
> kvm_destroy_vm
> __fput
>
> For deterministic validation, I added mdelay(1000) immediately after
> the existing next_set = false assignment. This only widens the
> existing post-clear callback window. A no-delay trace build naturally
> reached the callback-after-teardown-start/before-deinit ordering in 12
> of 200 runs, but 1,500 stock-kernel stress iterations did not produce a
> KASAN report, so natural reproduction is timing-sensitive.
>
> Always invoke hrtimer_cancel() for an initialized timer. Preserve the
> existing -EINVAL result when the timer is no longer set, but only after
> synchronizing with a running callback.
>
> With this patch, hrtimer_cancel() blocked for the full widened callback
> window before vCPU destruction. KASAN reported no error in 100
> fixed-and-widened runs or 200 fix-only timing-sweep runs.
>
> Fixes: 3a9f66cb25e1 ("RISC-V: KVM: Add timer functionality")
> Cc: stable at vger.kernel.org
> Assisted-by: OpenAI:GPT-5.6
> Signed-off-by: Myeonghun Pak <mhun512 at gmail.com>
LGTM.
Reviewed-by: Anup Patel <anup at brainfault.org>
Queued this patch as fix for Linux-7.3-rcX
Thanks,
Anup
> ---
> Changes in v2:
> - Add the required Assisted-by trailer.
> - Drop security at kernel.org from the recipients.
>
> arch/riscv/kvm/vcpu_timer.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> AI disclosure: I used AI assistance during the audit and am treating the
> issue as public as required by Documentation/process/security-bugs.rst.
> The reproducer and full KASAN trace have not been posted publicly and
> are available on request.
>
> diff --git a/arch/riscv/kvm/vcpu_timer.c b/arch/riscv/kvm/vcpu_timer.c
> index ae53133c7ab0..a2cd277a4059 100644
> --- a/arch/riscv/kvm/vcpu_timer.c
> +++ b/arch/riscv/kvm/vcpu_timer.c
> @@ -61,10 +61,13 @@ kvm_riscv_vcpu_hrtimer_expired(struct hrtimer *h)
>
> static int kvm_riscv_vcpu_timer_cancel(struct kvm_vcpu_timer *t)
> {
> - if (!t->init_done || !t->next_set)
> + if (!t->init_done)
> return -EINVAL;
>
> hrtimer_cancel(&t->hrt);
> +
> + if (!t->next_set)
> + return -EINVAL;
> t->next_set = false;
>
> return 0;
> --
> 2.47.2
More information about the linux-riscv
mailing list