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: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
ec3359b685
Коммит
ae6fcfbf5f
|
@ -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,
|
||||
|
@ -879,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
|
||||
|
|
Загрузка…
Ссылка в новой задаче