qemu/net-Update-MemReentrancyGuard-for-NIC-CVE-2023-3019.patch
Jiabo Feng f7e6c9d33c QEMU update to version 6.2.0-89
- qga-win: Fix guest-get-fsinfo multi-disks collection
- hw/timer: fix systick trace message
- virtio-net: correctly copy vnet header when flushing TX (CVE-2023-6693)
- ui/clipboard: mark type as not available when there is no data (CVE-2023-6683)
- esp: restrict non-DMA transfer length to that of available data (CVE-2024-24474)
- hw/scsi/lsi53c895a: add missing decrement of reentrancy counter
- hw/scsi/lsi53c895a: Fix reentrancy issues in the LSI controller (CVE-2023-0330)
- net: Update MemReentrancyGuard for NIC (CVE-2023-3019)
- net: Provide MemReentrancyGuard * to qemu_new_nic()

Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
(cherry picked from commit 18db08e0e64d982b88ad7f29ccd49b19e8c656f0)
2024-03-09 16:58:34 +08:00

86 lines
2.8 KiB
Diff

From e69961a3c833e79dbcaca3f651b6f0ebfc86c93b Mon Sep 17 00:00:00 2001
From: Akihiko Odaki <akihiko.odaki@daynix.com>
Date: Thu, 1 Jun 2023 12:18:59 +0900
Subject: [PATCH] net: Update MemReentrancyGuard for NIC (CVE-2023-3019)
Recently MemReentrancyGuard was added to DeviceState to record that the
device is engaging in I/O. The network device backend needs to update it
when delivering a packet to a device.
This implementation follows what bottom half does, but it does not add
a tracepoint for the case that the network device backend started
delivering a packet to a device which is already engaging in I/O. This
is because such reentrancy frequently happens for
qemu_flush_queued_packets() and is insignificant.
Fixes: CVE-2023-3019
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Acked-by: Alexander Bulekov <alxndr@bu.edu>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
include/net/net.h | 1 +
net/net.c | 14 ++++++++++++++
2 files changed, 15 insertions(+)
diff --git a/include/net/net.h b/include/net/net.h
index f5313b7e4e..b55f6cf698 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -118,6 +118,7 @@ struct NetClientState {
typedef struct NICState {
NetClientState *ncs;
NICConf *conf;
+ MemReentrancyGuard *reentrancy_guard;
void *opaque;
bool peer_deleted;
} NICState;
diff --git a/net/net.c b/net/net.c
index e4e4cf45a2..abdb9dfdc5 100644
--- a/net/net.c
+++ b/net/net.c
@@ -312,6 +312,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
nic = g_malloc0(info->size + sizeof(NetClientState) * queues);
nic->ncs = (void *)nic + info->size;
nic->conf = conf;
+ nic->reentrancy_guard = reentrancy_guard,
nic->opaque = opaque;
for (i = 0; i < queues; i++) {
@@ -767,6 +768,7 @@ static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
int iovcnt,
void *opaque)
{
+ MemReentrancyGuard *owned_reentrancy_guard;
NetClientState *nc = opaque;
int ret;
@@ -779,12 +781,24 @@ static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
return 0;
}
+ if (nc->info->type != NET_CLIENT_DRIVER_NIC ||
+ qemu_get_nic(nc)->reentrancy_guard->engaged_in_io) {
+ owned_reentrancy_guard = NULL;
+ } else {
+ owned_reentrancy_guard = qemu_get_nic(nc)->reentrancy_guard;
+ owned_reentrancy_guard->engaged_in_io = true;
+ }
+
if (nc->info->receive_iov && !(flags & QEMU_NET_PACKET_FLAG_RAW)) {
ret = nc->info->receive_iov(nc, iov, iovcnt);
} else {
ret = nc_sendv_compat(nc, iov, iovcnt, flags);
}
+ if (owned_reentrancy_guard) {
+ owned_reentrancy_guard->engaged_in_io = false;
+ }
+
if (ret == 0) {
nc->receive_disabled = 1;
}
--
2.27.0