Commit ae6fcfbf authored by Stefano Garzarella's avatar Stefano Garzarella Committed by David S. Miller

vsock/virtio: discard packets if credit is not respected

If the remote peer doesn't respect the credit information
(buf_alloc, fwd_cnt), sending more data than it can send,
we should drop the packets to prevent a malicious peer
from using all of our memory.

This is patch follows the VIRTIO spec: "VIRTIO_VSOCK_OP_RW data
packets MUST only be transmitted when the peer has sufficient
free buffer space for the payload"
Signed-off-by: default avatarStefano Garzarella <sgarzare@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ec3359b6
...@@ -204,10 +204,14 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, ...@@ -204,10 +204,14 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
return virtio_transport_get_ops()->send_pkt(pkt); 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) struct virtio_vsock_pkt *pkt)
{ {
if (vvs->rx_bytes + pkt->len > vvs->buf_alloc)
return false;
vvs->rx_bytes += pkt->len; vvs->rx_bytes += pkt->len;
return true;
} }
static void virtio_transport_dec_rx_pkt(struct virtio_vsock_sock *vvs, static void virtio_transport_dec_rx_pkt(struct virtio_vsock_sock *vvs,
...@@ -879,14 +883,18 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk, ...@@ -879,14 +883,18 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk,
struct virtio_vsock_pkt *pkt) struct virtio_vsock_pkt *pkt)
{ {
struct virtio_vsock_sock *vvs = vsk->trans; 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->len = le32_to_cpu(pkt->hdr.len);
pkt->off = 0; pkt->off = 0;
spin_lock_bh(&vvs->rx_lock); 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, /* Try to copy small packets into the buffer of last packet queued,
* to avoid wasting memory queueing the entire buffer with a small * to avoid wasting memory queueing the entire buffer with a small
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment