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

6cae2f
From f167022606b5ccca27a627ae599538ce2348ef67 Mon Sep 17 00:00:00 2001
6cae2f
Message-Id: <f167022606b5ccca27a627ae599538ce2348ef67.1666780268.git.tredaelli@redhat.com>
6cae2f
From: Maxime Coquelin <maxime.coquelin@redhat.com>
6cae2f
Date: Thu, 16 Jun 2022 11:35:56 +0200
6cae2f
Subject: [PATCH 1/2] vhost: discard too small descriptor chains
6cae2f
6cae2f
[ upstream commit 71bd0cc536ad6d84188d947d6f24c17400d8f623 ]
6cae2f
6cae2f
This patch discards descriptor chains which are smaller
6cae2f
than the Virtio-net header size, and ones that are equal.
6cae2f
6cae2f
Indeed, such descriptor chains sizes mean there is no
6cae2f
packet data.
6cae2f
6cae2f
This patch also has the advantage of requesting the exact
6cae2f
packets sizes for the mbufs.
6cae2f
6cae2f
CVE-2022-2132
6cae2f
Fixes: 62250c1d0978 ("vhost: extract split ring handling from Rx and Tx functions")
6cae2f
Fixes: c3ff0ac70acb ("vhost: improve performance by supporting large buffer")
6cae2f
Fixes: 84d5204310d7 ("vhost: support async dequeue for split ring")
6cae2f
6cae2f
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
6cae2f
Acked-by: Chenbo Xia <chenbo.xia@intel.com>
6cae2f
Reviewed-by: David Marchand <david.marchand@redhat.com>
6cae2f
---
6cae2f
 lib/vhost/virtio_net.c | 21 +++++++++++++++++----
6cae2f
 1 file changed, 17 insertions(+), 4 deletions(-)
6cae2f
6cae2f
diff --git a/lib/vhost/virtio_net.c b/lib/vhost/virtio_net.c
6cae2f
index 858187d1b0..991a7a2bd4 100644
6cae2f
--- a/lib/vhost/virtio_net.c
6cae2f
+++ b/lib/vhost/virtio_net.c
6cae2f
@@ -2334,10 +2334,10 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq,
6cae2f
 	buf_addr = buf_vec[vec_idx].buf_addr;
6cae2f
 	buf_len = buf_vec[vec_idx].buf_len;
6cae2f
 
6cae2f
-	if (unlikely(buf_len < dev->vhost_hlen && nr_vec <= 1)) {
6cae2f
-		error = -1;
6cae2f
-		goto out;
6cae2f
-	}
6cae2f
+	/*
6cae2f
+	 * The caller has checked the descriptors chain is larger than the
6cae2f
+	 * header size.
6cae2f
+	 */
6cae2f
 
6cae2f
 	if (virtio_net_with_host_offload(dev)) {
6cae2f
 		if (unlikely(buf_len < sizeof(struct virtio_net_hdr))) {
6cae2f
@@ -2568,6 +2568,14 @@ virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq,
6cae2f
 
6cae2f
 		update_shadow_used_ring_split(vq, head_idx, 0);
6cae2f
 
6cae2f
+		if (unlikely(buf_len <= dev->vhost_hlen)) {
6cae2f
+			dropped += 1;
6cae2f
+			i++;
6cae2f
+			break;
6cae2f
+		}
6cae2f
+
6cae2f
+		buf_len -= dev->vhost_hlen;
6cae2f
+
6cae2f
 		err = virtio_dev_pktmbuf_prep(dev, pkts[i], buf_len);
6cae2f
 		if (unlikely(err)) {
6cae2f
 			/*
6cae2f
@@ -2771,6 +2779,11 @@ vhost_dequeue_single_packed(struct virtio_net *dev,
6cae2f
 					 VHOST_ACCESS_RO) < 0))
6cae2f
 		return -1;
6cae2f
 
6cae2f
+	if (unlikely(buf_len <= dev->vhost_hlen))
6cae2f
+		return -1;
6cae2f
+
6cae2f
+	buf_len -= dev->vhost_hlen;
6cae2f
+
6cae2f
 	if (unlikely(virtio_dev_pktmbuf_prep(dev, pkts, buf_len))) {
6cae2f
 		if (!allocerr_warned) {
6cae2f
 			VHOST_LOG_DATA(ERR,
6cae2f
-- 
6cae2f
2.37.3
6cae2f