[PATCH] riscv: KVM: Fix memory leak in vector context allocation

Michael Neuling posted 1 patch 2 months ago
arch/riscv/kvm/vcpu_vector.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
[PATCH] riscv: KVM: Fix memory leak in vector context allocation
Posted by Michael Neuling 2 months ago
When the second kzalloc() for host_context vector data fails,
the already-allocated guest_context vector data is not freed,
causing a memory leak. This is triggerable from userspace via:

  ioctl(vm_fd, KVM_CREATE_VCPU)
    → kvm_vm_ioctl_create_vcpu()
      → kvm_arch_vcpu_create()
        → kvm_riscv_vcpu_alloc_vector_context()

Note also that kvm_vm_ioctl_create_vcpu() does not call
kvm_arch_vcpu_destroy() on kvm_arch_vcpu_create() failure:

  kvm_arch_vcpu_create()           ← fails, returns error
      goto vcpu_free_run_page;     ← line 4209

  ...
  arch_vcpu_destroy:               ← SKIPPED
      kvm_arch_vcpu_destroy(vcpu); ← which would call free_vector_context
  vcpu_free_run_page:              ← lands HERE, below arch_vcpu_destroy
      free_page(vcpu->run);
  vcpu_free:
      kmem_cache_free(vcpu);

so kvm_riscv_vcpu_free_vector_context() is never called to
clean up the partial allocation.

Fixes: 0f4b82579716 ("RISC-V: KVM: Add vector lazy save/restore support")
Assisted-By: Claude Opus 4.6 (1M context)
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 arch/riscv/kvm/vcpu_vector.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/kvm/vcpu_vector.c b/arch/riscv/kvm/vcpu_vector.c
index 05f3cc2d8e..46fbf48f25 100644
--- a/arch/riscv/kvm/vcpu_vector.c
+++ b/arch/riscv/kvm/vcpu_vector.c
@@ -80,8 +80,10 @@ int kvm_riscv_vcpu_alloc_vector_context(struct kvm_vcpu *vcpu)
 		return -ENOMEM;
 
 	vcpu->arch.host_context.vector.datap = kzalloc(riscv_v_vsize, GFP_KERNEL);
-	if (!vcpu->arch.host_context.vector.datap)
+	if (!vcpu->arch.host_context.vector.datap) {
+		kfree(vcpu->arch.guest_context.vector.datap);
 		return -ENOMEM;
+	}
 
 	return 0;
 }
-- 
2.43.0

Re: [PATCH] riscv: KVM: Fix memory leak in vector context allocation
Posted by Anup Patel 2 months ago
On Mon, Apr 13, 2026 at 11:14 AM Michael Neuling <mikey@neuling.org> wrote:
>
> When the second kzalloc() for host_context vector data fails,
> the already-allocated guest_context vector data is not freed,
> causing a memory leak. This is triggerable from userspace via:
>
>   ioctl(vm_fd, KVM_CREATE_VCPU)
>     → kvm_vm_ioctl_create_vcpu()
>       → kvm_arch_vcpu_create()
>         → kvm_riscv_vcpu_alloc_vector_context()
>
> Note also that kvm_vm_ioctl_create_vcpu() does not call
> kvm_arch_vcpu_destroy() on kvm_arch_vcpu_create() failure:
>
>   kvm_arch_vcpu_create()           ← fails, returns error
>       goto vcpu_free_run_page;     ← line 4209
>
>   ...
>   arch_vcpu_destroy:               ← SKIPPED
>       kvm_arch_vcpu_destroy(vcpu); ← which would call free_vector_context
>   vcpu_free_run_page:              ← lands HERE, below arch_vcpu_destroy
>       free_page(vcpu->run);
>   vcpu_free:
>       kmem_cache_free(vcpu);
>
> so kvm_riscv_vcpu_free_vector_context() is never called to
> clean up the partial allocation.
>
> Fixes: 0f4b82579716 ("RISC-V: KVM: Add vector lazy save/restore support")
> Assisted-By: Claude Opus 4.6 (1M context)
> Signed-off-by: Michael Neuling <mikey@neuling.org>

A similar fix is already merged for Linux-7.1
(Refer, https://lore.kernel.org/all/20260316151612.13305-1-osama.abdelkader@gmail.com/)

Regards,
Anup

> ---
>  arch/riscv/kvm/vcpu_vector.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/kvm/vcpu_vector.c b/arch/riscv/kvm/vcpu_vector.c
> index 05f3cc2d8e..46fbf48f25 100644
> --- a/arch/riscv/kvm/vcpu_vector.c
> +++ b/arch/riscv/kvm/vcpu_vector.c
> @@ -80,8 +80,10 @@ int kvm_riscv_vcpu_alloc_vector_context(struct kvm_vcpu *vcpu)
>                 return -ENOMEM;
>
>         vcpu->arch.host_context.vector.datap = kzalloc(riscv_v_vsize, GFP_KERNEL);
> -       if (!vcpu->arch.host_context.vector.datap)
> +       if (!vcpu->arch.host_context.vector.datap) {
> +               kfree(vcpu->arch.guest_context.vector.datap);
>                 return -ENOMEM;
> +       }
>
>         return 0;
>  }
> --
> 2.43.0
>