Skip to content

Commit

Permalink
KVM: nVMX: Fix bad cleanup on error of get/set nested state IOCTLs
Browse files Browse the repository at this point in the history
The handlers of IOCTLs in kvm_arch_vcpu_ioctl() are expected to set
their return value in "r" local var and break out of switch block
when they encounter some error.
This is because vcpu_load() is called before the switch block which
have a proper cleanup of vcpu_put() afterwards.

However, KVM_{GET,SET}_NESTED_STATE IOCTLs handlers just return
immediately on error without performing above mentioned cleanup.

Thus, change these handlers to behave as expected.

Fixes: 8fcc4b5 ("kvm: nVMX: Introduce KVM_CAP_NESTED_STATE")

Reviewed-by: Mark Kanda <[email protected]>
Reviewed-by: Patrick Colp <[email protected]>
Signed-off-by: Liran Alon <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
Liran Alon authored and bonzini committed Sep 20, 2018
1 parent 8b56ee9 commit 26b471c
Showing 1 changed file with 14 additions and 8 deletions.
22 changes: 14 additions & 8 deletions arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -4010,19 +4010,23 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
break;

BUILD_BUG_ON(sizeof(user_data_size) != sizeof(user_kvm_nested_state->size));
r = -EFAULT;
if (get_user(user_data_size, &user_kvm_nested_state->size))
return -EFAULT;
break;

r = kvm_x86_ops->get_nested_state(vcpu, user_kvm_nested_state,
user_data_size);
if (r < 0)
return r;
break;

if (r > user_data_size) {
if (put_user(r, &user_kvm_nested_state->size))
return -EFAULT;
return -E2BIG;
r = -EFAULT;
else
r = -E2BIG;
break;
}

r = 0;
break;
}
Expand All @@ -4034,19 +4038,21 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
if (!kvm_x86_ops->set_nested_state)
break;

r = -EFAULT;
if (copy_from_user(&kvm_state, user_kvm_nested_state, sizeof(kvm_state)))
return -EFAULT;
break;

r = -EINVAL;
if (kvm_state.size < sizeof(kvm_state))
return -EINVAL;
break;

if (kvm_state.flags &
~(KVM_STATE_NESTED_RUN_PENDING | KVM_STATE_NESTED_GUEST_MODE))
return -EINVAL;
break;

/* nested_run_pending implies guest_mode. */
if (kvm_state.flags == KVM_STATE_NESTED_RUN_PENDING)
return -EINVAL;
break;

r = kvm_x86_ops->set_nested_state(vcpu, user_kvm_nested_state, &kvm_state);
break;
Expand Down

0 comments on commit 26b471c

Please sign in to comment.