Commit e381d2b4 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'vsock-virtio-make-the-credit-mechanism-more-robust'



Stefano Garzarella says:

====================
vsock/virtio: make the credit mechanism more robust

This series makes the credit mechanism implemented in the
virtio-vsock devices more robust.
Patch 1 sends an update to the remote peer when the buf_alloc
change.
Patch 2 prevents a malicious peer (especially the guest) can
consume all the memory of the other peer, discarding packets
when the credit available is not respected.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2e978795 ae6fcfbf
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -204,10 +204,14 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
	return virtio_transport_get_ops()->send_pkt(pkt);
}

static void virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs,
static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs,
					struct virtio_vsock_pkt *pkt)
{
	if (vvs->rx_bytes + pkt->len > vvs->buf_alloc)
		return false;

	vvs->rx_bytes += pkt->len;
	return true;
}

static void virtio_transport_dec_rx_pkt(struct virtio_vsock_sock *vvs,
@@ -458,6 +462,9 @@ void virtio_transport_set_buffer_size(struct vsock_sock *vsk, u64 val)
		vvs->buf_size_max = val;
	vvs->buf_size = val;
	vvs->buf_alloc = val;

	virtio_transport_send_credit_update(vsk, VIRTIO_VSOCK_TYPE_STREAM,
					    NULL);
}
EXPORT_SYMBOL_GPL(virtio_transport_set_buffer_size);

@@ -876,14 +883,18 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk,
			      struct virtio_vsock_pkt *pkt)
{
	struct virtio_vsock_sock *vvs = vsk->trans;
	bool free_pkt = false;
	bool can_enqueue, free_pkt = false;

	pkt->len = le32_to_cpu(pkt->hdr.len);
	pkt->off = 0;

	spin_lock_bh(&vvs->rx_lock);

	virtio_transport_inc_rx_pkt(vvs, pkt);
	can_enqueue = virtio_transport_inc_rx_pkt(vvs, pkt);
	if (!can_enqueue) {
		free_pkt = true;
		goto out;
	}

	/* Try to copy small packets into the buffer of last packet queued,
	 * to avoid wasting memory queueing the entire buffer with a small