Re: [PATCH] KVM: nVMX: Fix bad cleanup on error of get/set nested state IOCTLs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2018-09-13 at 00:00 +0300, Liran Alon wrote:
> 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: 8fcc4b5923af ("kvm: nVMX: Introduce KVM_CAP_NESTED_STATE")
> 
> Reviewed-by: Mark Kanda <mark.kanda@xxxxxxxxxx>
> Signed-off-by: Liran Alon <liran.alon@xxxxxxxxxx>

Reviewed-by: Patrick Colp <patrick.colp@xxxxxxxxxx>

> ---
>  arch/x86/kvm/x86.c | 21 +++++++++++++--------
>  1 file changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 805c1df7c77e..8f3acdae8b14 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -4007,19 +4007,22 @@ 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) {
> +			r = -E2BIG;
>  			if (put_user(r, &user_kvm_nested_state->size))
> -				return -EFAULT;
> -			return -E2BIG;
> +				r = -EFAULT;
> +			break;
>  		}
> +
>  		r = 0;
>  		break;
>  	}
> @@ -4031,19 +4034,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;




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux