From 5b3c25e6ee2c68887aae166aed57d0b4af91fa60 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Thu, 16 Jun 2022 11:35:56 +0200 Subject: [PATCH] vhost: discard too small descriptor chains This patch discards descriptor chains which are smaller than the Virtio-net header size, and ones that are equal. Indeed, such descriptor chains sizes mean there is no packet data. This patch also has the advantage of requesting the exact packets sizes for the mbufs. CVE-2022-2132 Fixes: 62250c1d0978 ("vhost: extract split ring handling from Rx and Tx functions") Fixes: c3ff0ac70acb ("vhost: improve performance by supporting large buffer") Cc: stable@dpdk.org Signed-off-by: Maxime Coquelin Conflict: NA Reference: https://git.dpdk.org/dpdk-stable/commit/?id=5b3c25e6ee --- lib/librte_vhost/virtio_net.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c index ae4e54a442..1fcbc1aca9 100644 --- a/lib/librte_vhost/virtio_net.c +++ b/lib/librte_vhost/virtio_net.c @@ -1412,10 +1412,10 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq, buf_iova = buf_vec[vec_idx].buf_iova; buf_len = buf_vec[vec_idx].buf_len; - if (unlikely(buf_len < dev->vhost_hlen && nr_vec <= 1)) { - error = -1; - goto out; - } + /* + * The caller has checked the descriptors chain is larger than the + * header size. + */ if (virtio_net_with_host_offload(dev)) { if (unlikely(buf_len < sizeof(struct virtio_net_hdr))) { @@ -1742,6 +1742,14 @@ virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq, if (likely(dev->dequeue_zero_copy == 0)) update_shadow_used_ring_split(vq, head_idx, 0); + if (unlikely(buf_len <= dev->vhost_hlen)) { + dropped += 1; + i++; + break; + } + + buf_len -= dev->vhost_hlen; + pkts[i] = virtio_dev_pktmbuf_alloc(dev, mbuf_pool, buf_len); if (unlikely(pkts[i] == NULL)) { /* @@ -1955,6 +1963,11 @@ vhost_dequeue_single_packed(struct virtio_net *dev, VHOST_ACCESS_RO) < 0)) return -1; + if (unlikely(buf_len <= dev->vhost_hlen)) + return -1; + + buf_len -= dev->vhost_hlen; + *pkts = virtio_dev_pktmbuf_alloc(dev, mbuf_pool, buf_len); if (unlikely(*pkts == NULL)) { if (!allocerr_warned) { -- 2.23.0