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

Commit 692a998b authored by Jason Wang's avatar Jason Wang Committed by David S. Miller
Browse files

vhost_net: correct error handling in vhost_net_set_backend()



Currently, when vhost_init_used() fails the sock refcnt and ubufs were
leaked. Correct this by calling vhost_init_used() before assign ubufs and
restore the oldsock when it fails.

Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent af668b3c
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -827,15 +827,16 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
			r = PTR_ERR(ubufs);
			goto err_ubufs;
		}
		oldubufs = vq->ubufs;
		vq->ubufs = ubufs;

		vhost_net_disable_vq(n, vq);
		rcu_assign_pointer(vq->private_data, sock);
		vhost_net_enable_vq(n, vq);

		r = vhost_init_used(vq);
		if (r)
			goto err_vq;
			goto err_used;
		vhost_net_enable_vq(n, vq);

		oldubufs = vq->ubufs;
		vq->ubufs = ubufs;

		n->tx_packets = 0;
		n->tx_zcopy_err = 0;
@@ -859,6 +860,11 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
	mutex_unlock(&n->dev.mutex);
	return 0;

err_used:
	rcu_assign_pointer(vq->private_data, oldsock);
	vhost_net_enable_vq(n, vq);
	if (ubufs)
		vhost_ubuf_put_and_wait(ubufs);
err_ubufs:
	fput(sock->file);
err_vq: