8bba2efc03
- kvm-net-Provide-MemReentrancyGuard-to-qemu_new_nic.patch [RHEL-7309] - kvm-net-Update-MemReentrancyGuard-for-NIC.patch [RHEL-7309] - kvm-vhost-release-memory_listener-object-in-error-path.patch [RHEL-7567] - kvm-ui-fix-crash-when-there-are-no-active_console.patch [RHEL-2600] - Resolves: RHEL-7309 (CVE-2023-3019 virt:rhel/qemu-kvm: QEMU: e1000e: heap use-after-free in e1000e_write_packet_to_guest() [rhel-8]) - Resolves: RHEL-7567 ([RHEL8][clone]VM crash when guest running testpmd and delete created vhostuserclient port on host) - Resolves: RHEL-2600 (qemu core dump occurs when client connects to VNC server because qemu cmd only adds vnc but without graphics device)
106 lines
3.5 KiB
Diff
106 lines
3.5 KiB
Diff
From d58671091daf8c325a6f1cd87737d94b5fb51d12 Mon Sep 17 00:00:00 2001
|
|
From: Jon Maloy <jmaloy@redhat.com>
|
|
Date: Thu, 23 Nov 2023 11:30:46 -0500
|
|
Subject: [PATCH 2/4] net: Update MemReentrancyGuard for NIC
|
|
|
|
RH-Author: Jon Maloy <jmaloy@redhat.com>
|
|
RH-MergeRequest: 331: net: Provide MemReentrancyGuard * to qemu_new_nic()
|
|
RH-Jira: RHEL-7309
|
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
|
RH-Acked-by: Jason Wang <jasowang@redhat.com>
|
|
RH-Commit: [2/2] b116efe725dd838c2cab9bd2240112f3c6c46d6a (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2)
|
|
|
|
Jira: https://issues.redhat.com/browse/RHEL-7309
|
|
CVE: CVE-2023-3019
|
|
Upstream: Merged
|
|
|
|
commit 9050f976e447444ea6ee2ba12c9f77e4b0dc54bc
|
|
Author: Akihiko Odaki <akihiko.odaki@daynix.com>
|
|
Date: Thu Jun 1 12:18:59 2023 +0900
|
|
|
|
net: Update MemReentrancyGuard for NIC
|
|
|
|
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>
|
|
|
|
Signed-off-by: Jon Maloy <jmaloy@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 1457b6c014..11d4564ea1 100644
|
|
--- a/include/net/net.h
|
|
+++ b/include/net/net.h
|
|
@@ -112,6 +112,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 669e194c4b..b3008a52b7 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.41.0
|
|
|