diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c index b64944367ac5..30c60a00d3ae 100644 --- a/drivers/misc/vmw_vmci/vmci_host.c +++ b/drivers/misc/vmw_vmci/vmci_host.c @@ -426,8 +426,12 @@ static int vmci_host_do_receive_datagram(struct vmci_host_dev *vmci_host_dev, return -EINVAL; } - if (copy_from_user(&recv_info, uptr, sizeof(recv_info))) - return -EFAULT; + mutex_lock(&vmci_host_dev->lock); + + if (copy_from_user(&recv_info, uptr, sizeof(recv_info))) { + retval = -EFAULT; + goto out; + } size = recv_info.len; recv_info.result = vmci_ctx_dequeue_datagram(vmci_host_dev->context, @@ -437,11 +441,17 @@ static int vmci_host_do_receive_datagram(struct vmci_host_dev *vmci_host_dev, void __user *ubuf = (void __user *)(uintptr_t)recv_info.addr; retval = copy_to_user(ubuf, dg, VMCI_DG_SIZE(dg)); kfree(dg); - if (retval != 0) - return -EFAULT; + if (retval != 0) { + retval = -EFAULT; + goto out; + } } - return copy_to_user(uptr, &recv_info, sizeof(recv_info)) ? -EFAULT : 0; + retval = copy_to_user(uptr, &recv_info, sizeof(recv_info)) ? -EFAULT : 0; + +out: + mutex_unlock(&vmci_host_dev->lock); + return retval; } static int vmci_host_do_alloc_queuepair(struct vmci_host_dev *vmci_host_dev,