Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13925502 authored by K. Y. Srinivasan's avatar K. Y. Srinivasan Committed by Greg Kroah-Hartman
Browse files

Drivers: hv: Cleanup error handling in vmbus_open()



Fix a memory leak  in the error handling path in the function vmbus_open().

Signed-off-by: default avatarK. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: default avatarHaiyang Zhang <haiyangz@microsoft.com>
Reported-by: default avatarJason Wang <jasowang@redhat.com>
Cc: Stable <stable@vger.kernel.org>
Acked-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1b207734
Loading
Loading
Loading
Loading
+13 −11
Original line number Diff line number Diff line
@@ -146,14 +146,14 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,

	if (ret != 0) {
		err = ret;
		goto errorout;
		goto error0;
	}

	ret = hv_ringbuffer_init(
		&newchannel->inbound, in, recv_ringbuffer_size);
	if (ret != 0) {
		err = ret;
		goto errorout;
		goto error0;
	}


@@ -168,7 +168,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,

	if (ret != 0) {
		err = ret;
		goto errorout;
		goto error0;
	}

	/* Create and init the channel open message */
@@ -177,7 +177,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
			   GFP_KERNEL);
	if (!open_info) {
		err = -ENOMEM;
		goto errorout;
		goto error0;
	}

	init_completion(&open_info->waitevent);
@@ -193,7 +193,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,

	if (userdatalen > MAX_USER_DEFINED_BYTES) {
		err = -EINVAL;
		goto errorout;
		goto error0;
	}

	if (userdatalen)
@@ -208,19 +208,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
			       sizeof(struct vmbus_channel_open_channel));

	if (ret != 0)
		goto cleanup;
		goto error1;

	t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ);
	if (t == 0) {
		err = -ETIMEDOUT;
		goto errorout;
		goto error1;
	}


	if (open_info->response.open_result.status)
		err = open_info->response.open_result.status;

cleanup:
	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
	list_del(&open_info->msglistentry);
	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
@@ -228,9 +227,12 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
	kfree(open_info);
	return err;

errorout:
	hv_ringbuffer_cleanup(&newchannel->outbound);
	hv_ringbuffer_cleanup(&newchannel->inbound);
error1:
	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
	list_del(&open_info->msglistentry);
	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);

error0:
	free_pages((unsigned long)out,
		get_order(send_ringbuffer_size + recv_ringbuffer_size));
	kfree(open_info);