aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorStefano Garzarella <sgarzare@redhat.com>2019-10-17 08:44:03 -0400
committerDavid S. Miller <davem@davemloft.net>2019-10-18 13:19:43 -0400
commitae6fcfbf5f03de3407b809aaee319330d3dc7f8b (patch)
tree5fbcf9656666a376a80edc90c21a1de0da79e343 /net
parentec3359b685db834c249953db6ac5717bf5cde425 (diff)
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>
Diffstat (limited to 'net')
-rw-r--r--net/vmw_vsock/virtio_transport_common.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index db127a69f5c3..481f7f8a1655 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -204,10 +204,14 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
204 return virtio_transport_get_ops()->send_pkt(pkt); 204 return virtio_transport_get_ops()->send_pkt(pkt);
205} 205}
206 206
207static void virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs, 207static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs,
208 struct virtio_vsock_pkt *pkt) 208 struct virtio_vsock_pkt *pkt)
209{ 209{
210 if (vvs->rx_bytes + pkt->len > vvs->buf_alloc)
211 return false;
212
210 vvs->rx_bytes += pkt->len; 213 vvs->rx_bytes += pkt->len;
214 return true;
211} 215}
212 216
213static void virtio_transport_dec_rx_pkt(struct virtio_vsock_sock *vvs, 217static void virtio_transport_dec_rx_pkt(struct virtio_vsock_sock *vvs,
@@ -879,14 +883,18 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk,
879 struct virtio_vsock_pkt *pkt) 883 struct virtio_vsock_pkt *pkt)
880{ 884{
881 struct virtio_vsock_sock *vvs = vsk->trans; 885 struct virtio_vsock_sock *vvs = vsk->trans;
882 bool free_pkt = false; 886 bool can_enqueue, free_pkt = false;
883 887
884 pkt->len = le32_to_cpu(pkt->hdr.len); 888 pkt->len = le32_to_cpu(pkt->hdr.len);
885 pkt->off = 0; 889 pkt->off = 0;
886 890
887 spin_lock_bh(&vvs->rx_lock); 891 spin_lock_bh(&vvs->rx_lock);
888 892
889 virtio_transport_inc_rx_pkt(vvs, pkt); 893 can_enqueue = virtio_transport_inc_rx_pkt(vvs, pkt);
894 if (!can_enqueue) {
895 free_pkt = true;
896 goto out;
897 }
890 898
891 /* Try to copy small packets into the buffer of last packet queued, 899 /* Try to copy small packets into the buffer of last packet queued,
892 * to avoid wasting memory queueing the entire buffer with a small 900 * to avoid wasting memory queueing the entire buffer with a small