Commit 5c1f50ab authored by Dan Carpenter's avatar Dan Carpenter Committed by Sean Christopherson

KVM: Fix a goof where kvm_create_vm() returns 0 instead of -ENOMEM

The error path for OOM when allocating buses used to return -ENOMEM using
the local variable 'r', where 'r' was initialized at the top of the
function.  But a new "r = kvm_init_irq_routing(kvm);" was introduced in
the middle of the function, so now the error code is not set and it
eventually leads to a NULL dereference due to kvm_dev_ioctl_create_vm()
thinking kvm_create_vm() succeeded.  Set the error code back to -ENOMEM.

Opportunistically tweak the logic to pre-set "r = -ENOMEM" immediately
before the flows that can fail due to memory allocation failure to make
it less likely that the bug recurs in the future.

Fixes: fbe4a7e8 ("KVM: Setup empty IRQ routing when creating a VM")
Signed-off-by: default avatarDan Carpenter <dan.carpenter@linaro.org>
Link: https://lore.kernel.org/r/02051e0a-09d8-49a2-917f-7c2f278a1ba1@moroto.mountain
[sean: tweak all of the "r = -ENOMEM" sites, massage changelog]
Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent 3dee3b18
...@@ -1143,8 +1143,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname) ...@@ -1143,8 +1143,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
{ {
struct kvm *kvm = kvm_arch_alloc_vm(); struct kvm *kvm = kvm_arch_alloc_vm();
struct kvm_memslots *slots; struct kvm_memslots *slots;
int r = -ENOMEM; int r, i, j;
int i, j;
if (!kvm) if (!kvm)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -1181,6 +1180,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname) ...@@ -1181,6 +1180,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
snprintf(kvm->stats_id, sizeof(kvm->stats_id), "kvm-%d", snprintf(kvm->stats_id, sizeof(kvm->stats_id), "kvm-%d",
task_pid_nr(current)); task_pid_nr(current));
r = -ENOMEM;
if (init_srcu_struct(&kvm->srcu)) if (init_srcu_struct(&kvm->srcu))
goto out_err_no_srcu; goto out_err_no_srcu;
if (init_srcu_struct(&kvm->irq_srcu)) if (init_srcu_struct(&kvm->irq_srcu))
...@@ -1209,6 +1209,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname) ...@@ -1209,6 +1209,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
rcu_assign_pointer(kvm->memslots[i], &kvm->__memslots[i][0]); rcu_assign_pointer(kvm->memslots[i], &kvm->__memslots[i][0]);
} }
r = -ENOMEM;
for (i = 0; i < KVM_NR_BUSES; i++) { for (i = 0; i < KVM_NR_BUSES; i++) {
rcu_assign_pointer(kvm->buses[i], rcu_assign_pointer(kvm->buses[i],
kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL_ACCOUNT)); kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL_ACCOUNT));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment