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

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