Blame SOURCES/0001-vhost-discard-too-small-descriptor-chains.patch

6462e1
From bec1c5fe59fd82a1d932aece65c919cd46325d89 Mon Sep 17 00:00:00 2001
6462e1
From: Maxime Coquelin <maxime.coquelin@redhat.com>
6462e1
Date: Thu, 16 Jun 2022 11:35:56 +0200
6462e1
Subject: [PATCH v2 1/2] vhost: discard too small descriptor chains
6462e1
6462e1
This patch discards descriptor chains which are smaller
6462e1
than the Virtio-net header size, and ones that are equal.
6462e1
6462e1
Indeed, such descriptor chains sizes mean there is no
6462e1
packet data.
6462e1
6462e1
This patch also has the advantage of requesting the exact
6462e1
packets sizes for the mbufs.
6462e1
6462e1
CVE-2022-2132
6462e1
Fixes: 62250c1d0978 ("vhost: extract split ring handling from Rx and Tx functions")
6462e1
Cc: stable@dpdk.org
6462e1
6462e1
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
6462e1
---
6462e1
 lib/librte_vhost/virtio_net.c | 22 ++++++++++++++--------
6462e1
 1 file changed, 14 insertions(+), 8 deletions(-)
6462e1
6462e1
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
6462e1
index ebeec8fd18..7da440de28 100644
6462e1
--- a/lib/librte_vhost/virtio_net.c
6462e1
+++ b/lib/librte_vhost/virtio_net.c
6462e1
@@ -1112,10 +1112,10 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq,
6462e1
 	buf_iova = buf_vec[vec_idx].buf_iova;
6462e1
 	buf_len = buf_vec[vec_idx].buf_len;
6462e1
 
6462e1
-	if (unlikely(buf_len < dev->vhost_hlen && nr_vec <= 1)) {
6462e1
-		error = -1;
6462e1
-		goto out;
6462e1
-	}
6462e1
+	/*
6462e1
+	 * The caller has checked the descriptors chain is larger than the
6462e1
+	 * header size.
6462e1
+	 */
6462e1
 
6462e1
 	if (virtio_net_with_host_offload(dev)) {
6462e1
 		if (unlikely(buf_len < sizeof(struct virtio_net_hdr))) {
6462e1
@@ -1350,20 +1350,23 @@ virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq,
6462e1
 	for (i = 0; i < count; i++) {
6462e1
 		struct buf_vector buf_vec[BUF_VECTOR_MAX];
6462e1
 		uint16_t head_idx;
6462e1
-		uint32_t dummy_len;
6462e1
+		uint32_t buf_len;
6462e1
 		uint16_t nr_vec = 0;
6462e1
 		int err;
6462e1
 
6462e1
 		if (unlikely(fill_vec_buf_split(dev, vq,
6462e1
 						vq->last_avail_idx + i,
6462e1
 						&nr_vec, buf_vec,
6462e1
-						&head_idx, &dummy_len,
6462e1
+						&head_idx, &buf_len,
6462e1
 						VHOST_ACCESS_RO) < 0))
6462e1
 			break;
6462e1
 
6462e1
 		if (likely(dev->dequeue_zero_copy == 0))
6462e1
 			update_shadow_used_ring_split(vq, head_idx, 0);
6462e1
 
6462e1
+		if (unlikely(buf_len <= dev->vhost_hlen))
6462e1
+			break;
6462e1
+
6462e1
 		pkts[i] = rte_pktmbuf_alloc(mbuf_pool);
6462e1
 		if (unlikely(pkts[i] == NULL)) {
6462e1
 			RTE_LOG(ERR, VHOST_DATA,
6462e1
@@ -1460,14 +1463,14 @@ virtio_dev_tx_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,
6462e1
 	for (i = 0; i < count; i++) {
6462e1
 		struct buf_vector buf_vec[BUF_VECTOR_MAX];
6462e1
 		uint16_t buf_id;
6462e1
-		uint32_t dummy_len;
6462e1
+		uint32_t buf_len;
6462e1
 		uint16_t desc_count, nr_vec = 0;
6462e1
 		int err;
6462e1
 
6462e1
 		if (unlikely(fill_vec_buf_packed(dev, vq,
6462e1
 						vq->last_avail_idx, &desc_count,
6462e1
 						buf_vec, &nr_vec,
6462e1
-						&buf_id, &dummy_len,
6462e1
+						&buf_id, &buf_len,
6462e1
 						VHOST_ACCESS_RO) < 0))
6462e1
 			break;
6462e1
 
6462e1
@@ -1475,6 +1478,9 @@ virtio_dev_tx_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,
6462e1
 			update_shadow_used_ring_packed(vq, buf_id, 0,
6462e1
 					desc_count);
6462e1
 
6462e1
+		if (unlikely(buf_len <= dev->vhost_hlen))
6462e1
+			break;
6462e1
+
6462e1
 		pkts[i] = rte_pktmbuf_alloc(mbuf_pool);
6462e1
 		if (unlikely(pkts[i] == NULL)) {
6462e1
 			RTE_LOG(ERR, VHOST_DATA,
6462e1
-- 
6462e1
2.37.1
6462e1