Juergen Gross 7b42c1
Patch-mainline: v6.3
Juergen Gross 7b42c1
Git-commit: 853618d5886bf94812f31228091cd37d308230f7
Juergen Gross 7b42c1
References: git-fixes
Juergen Gross 7b42c1
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Juergen Gross 7b42c1
Date: Fri, 14 Apr 2023 14:08:35 +0800
Juergen Gross 7b42c1
Subject: [PATCH] virtio_net: bugfix overflow inside xdp_linearize_page()
Juergen Gross 7b42c1
Juergen Gross 7b42c1
Here we copy the data from the original buf to the new page. But we
Juergen Gross 7b42c1
not check that it may be overflow.
Juergen Gross 7b42c1
Juergen Gross 7b42c1
As long as the size received(including vnethdr) is greater than 3840
Juergen Gross 7b42c1
(PAGE_SIZE -VIRTIO_XDP_HEADROOM). Then the memcpy will overflow.
Juergen Gross 7b42c1
Juergen Gross 7b42c1
And this is completely possible, as long as the MTU is large, such
Juergen Gross 7b42c1
as 4096. In our test environment, this will cause crash. Since crash is
Juergen Gross 7b42c1
caused by the written memory, it is meaningless, so I do not include it.
Juergen Gross 7b42c1
Juergen Gross 7b42c1
Fixes: 72979a6c3590 ("virtio_net: xdp, add slowpath case for non contiguous buffers")
Juergen Gross 7b42c1
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Juergen Gross 7b42c1
Acked-by: Jason Wang <jasowang@redhat.com>
Juergen Gross 7b42c1
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Juergen Gross 7b42c1
Signed-off-by: David S. Miller <davem@davemloft.net>
Juergen Gross 7b42c1
Signed-off-by: Juergen Gross <jgross@suse.com>
Juergen Gross 7b42c1
---
Juergen Gross 7b42c1
 drivers/net/virtio_net.c | 8 ++++++--
Juergen Gross 7b42c1
 1 file changed, 6 insertions(+), 2 deletions(-)
Juergen Gross 7b42c1
Juergen Gross 7b42c1
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
Juergen Gross 7b42c1
index 2396c28c0122..ea1bd4bb326d 100644
Juergen Gross 7b42c1
--- a/drivers/net/virtio_net.c
Juergen Gross 7b42c1
+++ b/drivers/net/virtio_net.c
Juergen Gross 7b42c1
@@ -814,8 +814,13 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
Juergen Gross 7b42c1
 				       int page_off,
Juergen Gross 7b42c1
 				       unsigned int *len)
Juergen Gross 7b42c1
 {
Juergen Gross 7b42c1
-	struct page *page = alloc_page(GFP_ATOMIC);
Juergen Gross 7b42c1
+	int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
Juergen Gross 7b42c1
+	struct page *page;
Juergen Gross 7b42c1
+
Juergen Gross 7b42c1
+	if (page_off + *len + tailroom > PAGE_SIZE)
Juergen Gross 7b42c1
+		return NULL;
Juergen Gross 7b42c1
 
Juergen Gross 7b42c1
+	page = alloc_page(GFP_ATOMIC);
Juergen Gross 7b42c1
 	if (!page)
Juergen Gross 7b42c1
 		return NULL;
Juergen Gross 7b42c1
 
Juergen Gross 7b42c1
@@ -823,7 +828,6 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
Juergen Gross 7b42c1
 	page_off += *len;
Juergen Gross 7b42c1
 
Juergen Gross 7b42c1
 	while (--*num_buf) {
Juergen Gross 7b42c1
-		int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
Juergen Gross 7b42c1
 		unsigned int buflen;
Juergen Gross 7b42c1
 		void *buf;
Juergen Gross 7b42c1
 		int off;
Juergen Gross 7b42c1
-- 
Juergen Gross 7b42c1
2.35.3
Juergen Gross 7b42c1