From 18db08e0e64d982b88ad7f29ccd49b19e8c656f0 Mon Sep 17 00:00:00 2001 From: Jiabo Feng Date: Sat, 9 Mar 2024 14:37:51 +0800 Subject: [PATCH] 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 --- ...-DMA-transfer-length-to-that-of-avai.patch | 43 ++ ...5a-Fix-reentrancy-issues-in-the-LSI-.patch | 124 ++++ ...5a-add-missing-decrement-of-reentran.patch | 39 ++ hw-timer-fix-systick-trace-message.patch | 37 ++ memory-prevent-dma-reentracy-issues.patch | 132 ++++ ...e-MemReentrancyGuard-to-qemu_new_nic.patch | 604 ++++++++++++++++++ ...eentrancyGuard-for-NIC-CVE-2023-3019.patch | 85 +++ qemu.spec | 23 +- ...st-get-fsinfo-multi-disks-collection.patch | 40 ++ ...k-type-as-not-available-when-there-i.patch | 89 +++ ...ctly-copy-vnet-header-when-flushing-.patch | 72 +++ 11 files changed, 1287 insertions(+), 1 deletion(-) create mode 100644 esp-restrict-non-DMA-transfer-length-to-that-of-avai.patch create mode 100644 hw-scsi-lsi53c895a-Fix-reentrancy-issues-in-the-LSI-.patch create mode 100644 hw-scsi-lsi53c895a-add-missing-decrement-of-reentran.patch create mode 100644 hw-timer-fix-systick-trace-message.patch create mode 100644 memory-prevent-dma-reentracy-issues.patch create mode 100644 net-Provide-MemReentrancyGuard-to-qemu_new_nic.patch create mode 100644 net-Update-MemReentrancyGuard-for-NIC-CVE-2023-3019.patch create mode 100644 qga-win-Fix-guest-get-fsinfo-multi-disks-collection.patch create mode 100644 ui-clipboard-mark-type-as-not-available-when-there-i.patch create mode 100644 virtio-net-correctly-copy-vnet-header-when-flushing-.patch diff --git a/esp-restrict-non-DMA-transfer-length-to-that-of-avai.patch b/esp-restrict-non-DMA-transfer-length-to-that-of-avai.patch new file mode 100644 index 0000000..8304046 --- /dev/null +++ b/esp-restrict-non-DMA-transfer-length-to-that-of-avai.patch @@ -0,0 +1,43 @@ +From 67f1bc4fc4d1864a55f6c626967defe5467f5134 Mon Sep 17 00:00:00 2001 +From: Mark Cave-Ayland +Date: Wed, 13 Sep 2023 21:44:09 +0100 +Subject: [PATCH] esp: restrict non-DMA transfer length to that of available + data (CVE-2024-24474) + +In the case where a SCSI layer transfer is incorrectly terminated, it is +possible for a TI command to cause a SCSI buffer overflow due to the +expected transfer data length being less than the available data in the +FIFO. When this occurs the unsigned async_len variable underflows and +becomes a large offset which writes past the end of the allocated SCSI +buffer. + +Restrict the non-DMA transfer length to be the smallest of the expected +transfer length and the available FIFO data to ensure that it is no longer +possible for the SCSI buffer overflow to occur. + +Signed-off-by: Mark Cave-Ayland +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1810 +Reviewed-by: Thomas Huth +Message-ID: <20230913204410.65650-3-mark.cave-ayland@ilande.co.uk> +Signed-off-by: Paolo Bonzini +--- + hw/scsi/esp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c +index f38231f8cd..435a81bbfd 100644 +--- a/hw/scsi/esp.c ++++ b/hw/scsi/esp.c +@@ -754,7 +754,8 @@ static void esp_do_nodma(ESPState *s) + } + + if (to_device) { +- len = MIN(fifo8_num_used(&s->fifo), ESP_FIFO_SZ); ++ len = MIN(s->async_len, ESP_FIFO_SZ); ++ len = MIN(len, fifo8_num_used(&s->fifo)); + esp_fifo_pop_buf(&s->fifo, s->async_buf, len); + s->async_buf += len; + s->async_len -= len; +-- +2.27.0 + diff --git a/hw-scsi-lsi53c895a-Fix-reentrancy-issues-in-the-LSI-.patch b/hw-scsi-lsi53c895a-Fix-reentrancy-issues-in-the-LSI-.patch new file mode 100644 index 0000000..6917058 --- /dev/null +++ b/hw-scsi-lsi53c895a-Fix-reentrancy-issues-in-the-LSI-.patch @@ -0,0 +1,124 @@ +From ef9a2635bf418f2a625e2421d3bfe1fe58ac0bec Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Mon, 22 May 2023 11:10:11 +0200 +Subject: [PATCH] hw/scsi/lsi53c895a: Fix reentrancy issues in the LSI + controller (CVE-2023-0330) + +We cannot use the generic reentrancy guard in the LSI code, so +we have to manually prevent endless reentrancy here. The problematic +lsi_execute_script() function has already a way to detect whether +too many instructions have been executed - we just have to slightly +change the logic here that it also takes into account if the function +has been called too often in a reentrant way. + +The code in fuzz-lsi53c895a-test.c has been taken from an earlier +patch by Mauro Matteo Cascella. + +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1563 +Message-Id: <20230522091011.1082574-1-thuth@redhat.com> +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Alexander Bulekov +Signed-off-by: Thomas Huth +Signed-off-by: liuxiangdong +--- + hw/scsi/lsi53c895a.c | 23 +++++++++++++++------ + tests/qtest/fuzz-lsi53c895a-test.c | 32 ++++++++++++++++++++++++++++++ + 2 files changed, 49 insertions(+), 6 deletions(-) + +diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c +index b9c9eb0dac..f7559051c5 100644 +--- a/hw/scsi/lsi53c895a.c ++++ b/hw/scsi/lsi53c895a.c +@@ -1134,15 +1134,24 @@ static void lsi_execute_script(LSIState *s) + uint32_t addr, addr_high; + int opcode; + int insn_processed = 0; ++ static int reentrancy_level; ++ ++ reentrancy_level++; + + s->istat1 |= LSI_ISTAT1_SRUN; + again: +- if (++insn_processed > LSI_MAX_INSN) { +- /* Some windows drivers make the device spin waiting for a memory +- location to change. If we have been executed a lot of code then +- assume this is the case and force an unexpected device disconnect. +- This is apparently sufficient to beat the drivers into submission. +- */ ++ /* ++ * Some windows drivers make the device spin waiting for a memory location ++ * to change. If we have executed more than LSI_MAX_INSN instructions then ++ * assume this is the case and force an unexpected device disconnect. This ++ * is apparently sufficient to beat the drivers into submission. ++ * ++ * Another issue (CVE-2023-0330) can occur if the script is programmed to ++ * trigger itself again and again. Avoid this problem by stopping after ++ * being called multiple times in a reentrant way (8 is an arbitrary value ++ * which should be enough for all valid use cases). ++ */ ++ if (++insn_processed > LSI_MAX_INSN || reentrancy_level > 8) { + if (!(s->sien0 & LSI_SIST0_UDC)) { + qemu_log_mask(LOG_GUEST_ERROR, + "lsi_scsi: inf. loop with UDC masked"); +@@ -1596,6 +1605,8 @@ again: + } + } + trace_lsi_execute_script_stop(); ++ ++ reentrancy_level--; + } + + static uint8_t lsi_reg_readb(LSIState *s, int offset) +diff --git a/tests/qtest/fuzz-lsi53c895a-test.c b/tests/qtest/fuzz-lsi53c895a-test.c +index 0f968024c8..9c50958796 100644 +--- a/tests/qtest/fuzz-lsi53c895a-test.c ++++ b/tests/qtest/fuzz-lsi53c895a-test.c +@@ -8,6 +8,36 @@ + #include "qemu/osdep.h" + #include "libqos/libqtest.h" + ++/* ++ * This used to trigger a DMA reentrancy issue ++ * leading to memory corruption bugs like stack ++ * overflow or use-after-free ++ * https://gitlab.com/qemu-project/qemu/-/issues/1563 ++ */ ++static void test_lsi_dma_reentrancy(void) ++{ ++ QTestState *s; ++ ++ s = qtest_init("-M q35 -m 512M -nodefaults " ++ "-blockdev driver=null-co,node-name=null0 " ++ "-device lsi53c810 -device scsi-cd,drive=null0"); ++ ++ qtest_outl(s, 0xcf8, 0x80000804); /* PCI Command Register */ ++ qtest_outw(s, 0xcfc, 0x7); /* Enables accesses */ ++ qtest_outl(s, 0xcf8, 0x80000814); /* Memory Bar 1 */ ++ qtest_outl(s, 0xcfc, 0xff100000); /* Set MMIO Address*/ ++ qtest_outl(s, 0xcf8, 0x80000818); /* Memory Bar 2 */ ++ qtest_outl(s, 0xcfc, 0xff000000); /* Set RAM Address*/ ++ qtest_writel(s, 0xff000000, 0xc0000024); ++ qtest_writel(s, 0xff000114, 0x00000080); ++ qtest_writel(s, 0xff00012c, 0xff000000); ++ qtest_writel(s, 0xff000004, 0xff000114); ++ qtest_writel(s, 0xff000008, 0xff100014); ++ qtest_writel(s, 0xff10002f, 0x000000ff); ++ ++ qtest_quit(s); ++} ++ + /* + * This used to trigger a UAF in lsi_do_msgout() + * https://gitlab.com/qemu-project/qemu/-/issues/972 +@@ -121,6 +151,8 @@ int main(int argc, char **argv) + test_lsi_do_dma_empty_queue); + qtest_add_func("fuzz/lsi53c895a/lsi_do_msgout_cancel_req", + test_lsi_do_msgout_cancel_req); ++ qtest_add_func("fuzz/lsi53c895a/lsi_dma_reentrancy", ++ test_lsi_dma_reentrancy); + } + + return g_test_run(); +-- +2.27.0 + diff --git a/hw-scsi-lsi53c895a-add-missing-decrement-of-reentran.patch b/hw-scsi-lsi53c895a-add-missing-decrement-of-reentran.patch new file mode 100644 index 0000000..6d286a6 --- /dev/null +++ b/hw-scsi-lsi53c895a-add-missing-decrement-of-reentran.patch @@ -0,0 +1,39 @@ +From 19692eed451101e16399673cd5c3ee9c684cfde0 Mon Sep 17 00:00:00 2001 +From: Sven Schnelle +Date: Sun, 28 Jan 2024 21:22:14 +0100 +Subject: [PATCH] hw/scsi/lsi53c895a: add missing decrement of reentrancy + counter + +When the maximum count of SCRIPTS instructions is reached, the code +stops execution and returns, but fails to decrement the reentrancy +counter. This effectively renders the SCSI controller unusable +because on next entry the reentrancy counter is still above the limit. + +This bug was seen on HP-UX 10.20 which seems to trigger SCRIPTS +loops. + +Fixes: b987718bbb ("hw/scsi/lsi53c895a: Fix reentrancy issues in the LSI controller (CVE-2023-0330)") +Signed-off-by: Sven Schnelle +Message-ID: <20240128202214.2644768-1-svens@stackframe.org> +Reviewed-by: Thomas Huth +Tested-by: Helge Deller +Signed-off-by: Thomas Huth +--- + hw/scsi/lsi53c895a.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c +index f7559051c5..71f1505227 100644 +--- a/hw/scsi/lsi53c895a.c ++++ b/hw/scsi/lsi53c895a.c +@@ -1159,6 +1159,7 @@ again: + lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0); + lsi_disconnect(s); + trace_lsi_execute_script_stop(); ++ reentrancy_level--; + return; + } + insn = read_dword(s, s->dsp); +-- +2.27.0 + diff --git a/hw-timer-fix-systick-trace-message.patch b/hw-timer-fix-systick-trace-message.patch new file mode 100644 index 0000000..42e6a26 --- /dev/null +++ b/hw-timer-fix-systick-trace-message.patch @@ -0,0 +1,37 @@ +From 81e188ec0547708416c0cfc426ba9ffcd56fcfc2 Mon Sep 17 00:00:00 2001 +From: qihao +Date: Thu, 8 Feb 2024 11:31:02 +0800 +Subject: [PATCH] hw/timer: fix systick trace message +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from 7c8faaf2a4fa8ad2d291662ac7e7eeea1fe8d47c + +Signed-off-by: Samuel Tardieu +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Laurent Vivier +Message-id: 20240109184508.3189599-1-sam@rfc1149.net +Fixes: ff68dacbc786 ("armv7m: Split systick out from NVIC") +Signed-off-by: Peter Maydell +Signed-off-by: qihao_yewu +--- + hw/timer/trace-events | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/timer/trace-events b/hw/timer/trace-events +index 3eccef8385..8145e18e3d 100644 +--- a/hw/timer/trace-events ++++ b/hw/timer/trace-events +@@ -35,7 +35,7 @@ aspeed_timer_read(uint64_t offset, unsigned size, uint64_t value) "From 0x%" PRI + + # armv7m_systick.c + systick_reload(void) "systick reload" +-systick_timer_tick(void) "systick reload" ++systick_timer_tick(void) "systick tick" + systick_read(uint64_t addr, uint32_t value, unsigned size) "systick read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" + systick_write(uint64_t addr, uint32_t value, unsigned size) "systick write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" + +-- +2.27.0 + diff --git a/memory-prevent-dma-reentracy-issues.patch b/memory-prevent-dma-reentracy-issues.patch new file mode 100644 index 0000000..913dd18 --- /dev/null +++ b/memory-prevent-dma-reentracy-issues.patch @@ -0,0 +1,132 @@ +From 26bda91b2bc6d880f75344f0a8efd3f3af8a358f Mon Sep 17 00:00:00 2001 +From: Alexander Bulekov +Date: Thu, 27 Apr 2023 17:10:06 -0400 +Subject: [PATCH] memory: prevent dma-reentracy issues + +Add a flag to the DeviceState, when a device is engaged in PIO/MMIO/DMA. +This flag is set/checked prior to calling a device's MemoryRegion +handlers, and set when device code initiates DMA. The purpose of this +flag is to prevent two types of DMA-based reentrancy issues: + +1.) mmio -> dma -> mmio case +2.) bh -> dma write -> mmio case + +These issues have led to problems such as stack-exhaustion and +use-after-frees. + +Summary of the problem from Peter Maydell: +https://lore.kernel.org/qemu-devel/CAFEAcA_23vc7hE3iaM-JVA6W38LK4hJoWae5KcknhPRD5fPBZA@mail.gmail.com + +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/62 +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/540 +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/541 +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/556 +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/557 +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/827 +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1282 +Resolves: CVE-2023-0330 + +Signed-off-by: Alexander Bulekov +Reviewed-by: Thomas Huth +Message-Id: <20230427211013.2994127-2-alxndr@bu.edu> +[thuth: Replace warn_report() with warn_report_once()] +Signed-off-by: Thomas Huth +Signed-off-by: liuxiangdong +--- + include/exec/memory.h | 5 +++++ + include/hw/qdev-core.h | 7 +++++++ + softmmu/memory.c | 16 ++++++++++++++++ + 3 files changed, 28 insertions(+) + +diff --git a/include/exec/memory.h b/include/exec/memory.h +index abb838f194..bbf1468d59 100644 +--- a/include/exec/memory.h ++++ b/include/exec/memory.h +@@ -737,6 +737,8 @@ struct MemoryRegion { + bool is_iommu; + RAMBlock *ram_block; + Object *owner; ++ /* owner as TYPE_DEVICE. Used for re-entrancy checks in MR access hotpath */ ++ DeviceState *dev; + + const MemoryRegionOps *ops; + void *opaque; +@@ -760,6 +762,9 @@ struct MemoryRegion { + unsigned ioeventfd_nb; + MemoryRegionIoeventfd *ioeventfds; + RamDiscardManager *rdm; /* Only for RAM */ ++ ++ /* For devices designed to perform re-entrant IO into their own IO MRs */ ++ bool disable_reentrancy_guard; + }; + + struct IOMMUMemoryRegion { +diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h +index 83774a1c68..45b1aec86b 100644 +--- a/include/hw/qdev-core.h ++++ b/include/hw/qdev-core.h +@@ -162,6 +162,10 @@ struct NamedClockList { + QLIST_ENTRY(NamedClockList) node; + }; + ++typedef struct { ++ bool engaged_in_io; ++} MemReentrancyGuard; ++ + /** + * DeviceState: + * @realized: Indicates whether the device has been fully constructed. +@@ -193,6 +197,9 @@ struct DeviceState { + int instance_id_alias; + int alias_required_for_version; + ResettableState reset; ++ ++ /* Is the device currently in mmio/pio/dma? Used to prevent re-entrancy */ ++ MemReentrancyGuard mem_reentrancy_guard; + }; + + struct DeviceListener { +diff --git a/softmmu/memory.c b/softmmu/memory.c +index 7340e19ff5..102f0a4248 100644 +--- a/softmmu/memory.c ++++ b/softmmu/memory.c +@@ -541,6 +541,18 @@ static MemTxResult access_with_adjusted_size(hwaddr addr, + access_size_max = 4; + } + ++ /* Do not allow more than one simultaneous access to a device's IO Regions */ ++ if (mr->dev && !mr->disable_reentrancy_guard && ++ !mr->ram_device && !mr->ram && !mr->rom_device && !mr->readonly) { ++ if (mr->dev->mem_reentrancy_guard.engaged_in_io) { ++ warn_report_once("Blocked re-entrant IO on MemoryRegion: " ++ "%s at addr: 0x%" HWADDR_PRIX, ++ memory_region_name(mr), addr); ++ return MEMTX_ACCESS_ERROR; ++ } ++ mr->dev->mem_reentrancy_guard.engaged_in_io = true; ++ } ++ + /* FIXME: support unaligned access? */ + access_size = MAX(MIN(size, access_size_max), access_size_min); + access_mask = MAKE_64BIT_MASK(0, access_size * 8); +@@ -555,6 +567,9 @@ static MemTxResult access_with_adjusted_size(hwaddr addr, + access_mask, attrs); + } + } ++ if (mr->dev) { ++ mr->dev->mem_reentrancy_guard.engaged_in_io = false; ++ } + return r; + } + +@@ -1169,6 +1184,7 @@ static void memory_region_do_init(MemoryRegion *mr, + } + mr->name = g_strdup(name); + mr->owner = owner; ++ mr->dev = (DeviceState *) object_dynamic_cast(mr->owner, TYPE_DEVICE); + mr->ram_block = NULL; + + if (name) { +-- +2.27.0 + diff --git a/net-Provide-MemReentrancyGuard-to-qemu_new_nic.patch b/net-Provide-MemReentrancyGuard-to-qemu_new_nic.patch new file mode 100644 index 0000000..d913ff6 --- /dev/null +++ b/net-Provide-MemReentrancyGuard-to-qemu_new_nic.patch @@ -0,0 +1,604 @@ +From cfb14ba8c266935afd660bcada152a36cafce521 Mon Sep 17 00:00:00 2001 +From: Akihiko Odaki +Date: Thu, 1 Jun 2023 12:18:58 +0900 +Subject: [PATCH] net: Provide MemReentrancyGuard * to qemu_new_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. + +In preparation for such a change, add MemReentrancyGuard * as a +parameter of qemu_new_nic(). + +Signed-off-by: Akihiko Odaki +Reviewed-by: Alexander Bulekov +Signed-off-by: Jason Wang +Signed-off-by: liuxiangdong +--- + hw/arm/musicpal.c | 3 ++- + hw/net/allwinner-sun8i-emac.c | 3 ++- + hw/net/allwinner_emac.c | 3 ++- + hw/net/cadence_gem.c | 3 ++- + hw/net/dp8393x.c | 3 ++- + hw/net/e1000.c | 3 ++- + hw/net/e1000e.c | 2 +- + hw/net/eepro100.c | 4 +++- + hw/net/etraxfs_eth.c | 3 ++- + hw/net/fsl_etsec/etsec.c | 3 ++- + hw/net/ftgmac100.c | 3 ++- + hw/net/i82596.c | 2 +- + hw/net/imx_fec.c | 2 +- + hw/net/lan9118.c | 3 ++- + hw/net/mcf_fec.c | 3 ++- + hw/net/mipsnet.c | 3 ++- + hw/net/msf2-emac.c | 3 ++- + hw/net/ne2000-isa.c | 3 ++- + hw/net/ne2000-pci.c | 3 ++- + hw/net/npcm7xx_emc.c | 3 ++- + hw/net/opencores_eth.c | 3 ++- + hw/net/pcnet.c | 3 ++- + hw/net/rocker/rocker_fp.c | 4 ++-- + hw/net/rtl8139.c | 3 ++- + hw/net/smc91c111.c | 3 ++- + hw/net/spapr_llan.c | 3 ++- + hw/net/stellaris_enet.c | 3 ++- + hw/net/sungem.c | 2 +- + hw/net/sunhme.c | 3 ++- + hw/net/tulip.c | 3 ++- + hw/net/virtio-net.c | 6 ++++-- + hw/net/vmxnet3.c | 2 +- + hw/net/xen_nic.c | 2 +- + hw/net/xgmac.c | 3 ++- + hw/net/xilinx_axienet.c | 3 ++- + hw/net/xilinx_ethlite.c | 3 ++- + hw/usb/dev-network.c | 3 ++- + include/net/net.h | 1 + + net/net.c | 1 + + 39 files changed, 73 insertions(+), 39 deletions(-) + +diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c +index 2680ec55b5..15fc7fee41 100644 +--- a/hw/arm/musicpal.c ++++ b/hw/arm/musicpal.c +@@ -418,7 +418,8 @@ static void mv88w8618_eth_realize(DeviceState *dev, Error **errp) + + address_space_init(&s->dma_as, s->dma_mr, "emac-dma"); + s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + } + + static const VMStateDescription mv88w8618_eth_vmsd = { +diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c +index ecc0245fe8..cf93b2fdac 100644 +--- a/hw/net/allwinner-sun8i-emac.c ++++ b/hw/net/allwinner-sun8i-emac.c +@@ -816,7 +816,8 @@ static void allwinner_sun8i_emac_realize(DeviceState *dev, Error **errp) + + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_allwinner_sun8i_emac_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + } + +diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c +index ddddf35c45..b3d73143bf 100644 +--- a/hw/net/allwinner_emac.c ++++ b/hw/net/allwinner_emac.c +@@ -453,7 +453,8 @@ static void aw_emac_realize(DeviceState *dev, Error **errp) + + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_aw_emac_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + + fifo8_create(&s->rx_fifo, RX_FIFO_SIZE); +diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c +index 21e1bd091f..bd7585c018 100644 +--- a/hw/net/cadence_gem.c ++++ b/hw/net/cadence_gem.c +@@ -1633,7 +1633,8 @@ static void gem_realize(DeviceState *dev, Error **errp) + qemu_macaddr_default_if_unset(&s->conf.macaddr); + + s->nic = qemu_new_nic(&net_gem_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + + if (s->jumbo_max_len > MAX_FRAME_SIZE) { + error_setg(errp, "jumbo-max-len is greater than %d", +diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c +index 45b954e46c..abfcc6f69f 100644 +--- a/hw/net/dp8393x.c ++++ b/hw/net/dp8393x.c +@@ -943,7 +943,8 @@ static void dp8393x_realize(DeviceState *dev, Error **errp) + "dp8393x-regs", SONIC_REG_COUNT << s->it_shift); + + s->nic = qemu_new_nic(&net_dp83932_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + + s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s); +diff --git a/hw/net/e1000.c b/hw/net/e1000.c +index e26e0a64c1..33cd33a8ff 100644 +--- a/hw/net/e1000.c ++++ b/hw/net/e1000.c +@@ -1736,7 +1736,8 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp) + macaddr); + + d->nic = qemu_new_nic(&net_e1000_info, &d->conf, +- object_get_typename(OBJECT(d)), dev->id, d); ++ object_get_typename(OBJECT(d)), dev->id, ++ &dev->mem_reentrancy_guard, d); + + qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr); + +diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c +index ac96f7665a..b6e9b0e178 100644 +--- a/hw/net/e1000e.c ++++ b/hw/net/e1000e.c +@@ -328,7 +328,7 @@ e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, uint8_t *macaddr) + int i; + + s->nic = qemu_new_nic(&net_e1000e_info, &s->conf, +- object_get_typename(OBJECT(s)), dev->id, s); ++ object_get_typename(OBJECT(s)), dev->id, &dev->mem_reentrancy_guard, s); + + s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 0; + +diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c +index 9c178c1448..074d54ec97 100644 +--- a/hw/net/eepro100.c ++++ b/hw/net/eepro100.c +@@ -1886,7 +1886,9 @@ static void e100_nic_realize(PCIDevice *pci_dev, Error **errp) + nic_reset(s); + + s->nic = qemu_new_nic(&net_eepro100_info, &s->conf, +- object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s); ++ object_get_typename(OBJECT(pci_dev)), ++ pci_dev->qdev.id, ++ &pci_dev->qdev.mem_reentrancy_guard, s); + + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + TRACE(OTHER, logout("%s\n", qemu_get_queue(s->nic)->info_str)); +diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c +index 1b82aec794..ba57a978d1 100644 +--- a/hw/net/etraxfs_eth.c ++++ b/hw/net/etraxfs_eth.c +@@ -618,7 +618,8 @@ static void etraxfs_eth_realize(DeviceState *dev, Error **errp) + + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf, +- object_get_typename(OBJECT(s)), dev->id, s); ++ object_get_typename(OBJECT(s)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + + s->phy.read = tdk_read; +diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c +index bd9d62b559..f790613b52 100644 +--- a/hw/net/fsl_etsec/etsec.c ++++ b/hw/net/fsl_etsec/etsec.c +@@ -391,7 +391,8 @@ static void etsec_realize(DeviceState *dev, Error **errp) + eTSEC *etsec = ETSEC_COMMON(dev); + + etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf, +- object_get_typename(OBJECT(dev)), dev->id, etsec); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, etsec); + qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a); + + etsec->ptimer = ptimer_init(etsec_timer_hit, etsec, PTIMER_POLICY_DEFAULT); +diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c +index d3bf14be53..be2cf63c08 100644 +--- a/hw/net/ftgmac100.c ++++ b/hw/net/ftgmac100.c +@@ -1118,7 +1118,8 @@ static void ftgmac100_realize(DeviceState *dev, Error **errp) + qemu_macaddr_default_if_unset(&s->conf.macaddr); + + s->nic = qemu_new_nic(&net_ftgmac100_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + } + +diff --git a/hw/net/i82596.c b/hw/net/i82596.c +index ec21e2699a..dc64246f75 100644 +--- a/hw/net/i82596.c ++++ b/hw/net/i82596.c +@@ -743,7 +743,7 @@ void i82596_common_init(DeviceState *dev, I82596State *s, NetClientInfo *info) + qemu_macaddr_default_if_unset(&s->conf.macaddr); + } + s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), +- dev->id, s); ++ dev->id, &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + + if (USE_TIMER) { +diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c +index 0db9aaf76a..74e7e0d122 100644 +--- a/hw/net/imx_fec.c ++++ b/hw/net/imx_fec.c +@@ -1318,7 +1318,7 @@ static void imx_eth_realize(DeviceState *dev, Error **errp) + + s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf, + object_get_typename(OBJECT(dev)), +- dev->id, s); ++ dev->id, &dev->mem_reentrancy_guard, s); + + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + } +diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c +index 6aff424cbe..942bce9ae6 100644 +--- a/hw/net/lan9118.c ++++ b/hw/net/lan9118.c +@@ -1354,7 +1354,8 @@ static void lan9118_realize(DeviceState *dev, Error **errp) + qemu_macaddr_default_if_unset(&s->conf.macaddr); + + s->nic = qemu_new_nic(&net_lan9118_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + s->eeprom[0] = 0xa5; + for (i = 0; i < 6; i++) { +diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c +index 25e3e453ab..a6be7bf413 100644 +--- a/hw/net/mcf_fec.c ++++ b/hw/net/mcf_fec.c +@@ -643,7 +643,8 @@ static void mcf_fec_realize(DeviceState *dev, Error **errp) + mcf_fec_state *s = MCF_FEC_NET(dev); + + s->nic = qemu_new_nic(&net_mcf_fec_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + } + +diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c +index 2ade72dea0..8e925de867 100644 +--- a/hw/net/mipsnet.c ++++ b/hw/net/mipsnet.c +@@ -255,7 +255,8 @@ static void mipsnet_realize(DeviceState *dev, Error **errp) + sysbus_init_irq(sbd, &s->irq); + + s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + } + +diff --git a/hw/net/msf2-emac.c b/hw/net/msf2-emac.c +index 9278fdce0b..1efa3dbf01 100644 +--- a/hw/net/msf2-emac.c ++++ b/hw/net/msf2-emac.c +@@ -527,7 +527,8 @@ static void msf2_emac_realize(DeviceState *dev, Error **errp) + + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_msf2_emac_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + } + +diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c +index dd6f6e34d3..30bd20c293 100644 +--- a/hw/net/ne2000-isa.c ++++ b/hw/net/ne2000-isa.c +@@ -74,7 +74,8 @@ static void isa_ne2000_realizefn(DeviceState *dev, Error **errp) + ne2000_reset(s); + + s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a); + } + +diff --git a/hw/net/ne2000-pci.c b/hw/net/ne2000-pci.c +index 9e5d10859a..4f8a699081 100644 +--- a/hw/net/ne2000-pci.c ++++ b/hw/net/ne2000-pci.c +@@ -71,7 +71,8 @@ static void pci_ne2000_realize(PCIDevice *pci_dev, Error **errp) + + s->nic = qemu_new_nic(&net_ne2000_info, &s->c, + object_get_typename(OBJECT(pci_dev)), +- pci_dev->qdev.id, s); ++ pci_dev->qdev.id, ++ &pci_dev->qdev.mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a); + } + +diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c +index 9a2328935c..cafda78772 100644 +--- a/hw/net/npcm7xx_emc.c ++++ b/hw/net/npcm7xx_emc.c +@@ -804,7 +804,8 @@ static void npcm7xx_emc_realize(DeviceState *dev, Error **errp) + + qemu_macaddr_default_if_unset(&emc->conf.macaddr); + emc->nic = qemu_new_nic(&net_npcm7xx_emc_info, &emc->conf, +- object_get_typename(OBJECT(dev)), dev->id, emc); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, emc); + qemu_format_nic_info_str(qemu_get_queue(emc->nic), emc->conf.macaddr.a); + } + +diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c +index 0b3dc3146e..f96d6ea2cc 100644 +--- a/hw/net/opencores_eth.c ++++ b/hw/net/opencores_eth.c +@@ -732,7 +732,8 @@ static void sysbus_open_eth_realize(DeviceState *dev, Error **errp) + sysbus_init_irq(sbd, &s->irq); + + s->nic = qemu_new_nic(&net_open_eth_info, &s->conf, +- object_get_typename(OBJECT(s)), dev->id, s); ++ object_get_typename(OBJECT(s)), dev->id, ++ &dev->mem_reentrancy_guard, s); + } + + static void qdev_open_eth_reset(DeviceState *dev) +diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c +index dcd3fc4948..da910a70bf 100644 +--- a/hw/net/pcnet.c ++++ b/hw/net/pcnet.c +@@ -1718,7 +1718,8 @@ void pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info) + s->poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pcnet_poll_timer, s); + + qemu_macaddr_default_if_unset(&s->conf.macaddr); +- s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s); ++ s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), ++ dev->id, &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + + /* Initialize the PROM */ +diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c +index cbeed65bd5..0d21948ada 100644 +--- a/hw/net/rocker/rocker_fp.c ++++ b/hw/net/rocker/rocker_fp.c +@@ -241,8 +241,8 @@ FpPort *fp_port_alloc(Rocker *r, char *sw_name, + port->conf.bootindex = -1; + port->conf.peers = *peers; + +- port->nic = qemu_new_nic(&fp_port_info, &port->conf, +- sw_name, NULL, port); ++ port->nic = qemu_new_nic(&fp_port_info, &port->conf, sw_name, NULL, ++ &DEVICE(r)->mem_reentrancy_guard, port); + qemu_format_nic_info_str(qemu_get_queue(port->nic), + port->conf.macaddr.a); + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index 90b4fc63ce..43d65d7252 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -3398,7 +3398,8 @@ static void pci_rtl8139_realize(PCIDevice *dev, Error **errp) + s->eeprom.contents[9] = s->conf.macaddr.a[4] | s->conf.macaddr.a[5] << 8; + + s->nic = qemu_new_nic(&net_rtl8139_info, &s->conf, +- object_get_typename(OBJECT(dev)), d->id, s); ++ object_get_typename(OBJECT(dev)), d->id, ++ &d->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + + s->cplus_txbuffer = NULL; +diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c +index ad778cd8fc..4eda971ef3 100644 +--- a/hw/net/smc91c111.c ++++ b/hw/net/smc91c111.c +@@ -783,7 +783,8 @@ static void smc91c111_realize(DeviceState *dev, Error **errp) + sysbus_init_irq(sbd, &s->irq); + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + /* ??? Save/restore. */ + } +diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c +index a6876a936d..475d5f3a34 100644 +--- a/hw/net/spapr_llan.c ++++ b/hw/net/spapr_llan.c +@@ -325,7 +325,8 @@ static void spapr_vlan_realize(SpaprVioDevice *sdev, Error **errp) + memcpy(&dev->perm_mac.a, &dev->nicconf.macaddr.a, sizeof(dev->perm_mac.a)); + + dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf, +- object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev); ++ object_get_typename(OBJECT(sdev)), sdev->qdev.id, ++ &sdev->qdev.mem_reentrancy_guard, dev); + qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a); + + dev->rxp_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, spapr_vlan_flush_rx_queue, +diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c +index 8dd60783d8..6768a6912f 100644 +--- a/hw/net/stellaris_enet.c ++++ b/hw/net/stellaris_enet.c +@@ -492,7 +492,8 @@ static void stellaris_enet_realize(DeviceState *dev, Error **errp) + qemu_macaddr_default_if_unset(&s->conf.macaddr); + + s->nic = qemu_new_nic(&net_stellaris_enet_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + } + +diff --git a/hw/net/sungem.c b/hw/net/sungem.c +index 3684a4d733..c12d44e9dc 100644 +--- a/hw/net/sungem.c ++++ b/hw/net/sungem.c +@@ -1361,7 +1361,7 @@ static void sungem_realize(PCIDevice *pci_dev, Error **errp) + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_sungem_info, &s->conf, + object_get_typename(OBJECT(dev)), +- dev->id, s); ++ dev->id, &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), + s->conf.macaddr.a); + } +diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c +index fc34905f87..fa98528d71 100644 +--- a/hw/net/sunhme.c ++++ b/hw/net/sunhme.c +@@ -892,7 +892,8 @@ static void sunhme_realize(PCIDevice *pci_dev, Error **errp) + + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_sunhme_info, &s->conf, +- object_get_typename(OBJECT(d)), d->id, s); ++ object_get_typename(OBJECT(d)), d->id, ++ &d->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + } + +diff --git a/hw/net/tulip.c b/hw/net/tulip.c +index b9e42c322a..d319f9fb80 100644 +--- a/hw/net/tulip.c ++++ b/hw/net/tulip.c +@@ -985,7 +985,8 @@ static void pci_tulip_realize(PCIDevice *pci_dev, Error **errp) + + s->nic = qemu_new_nic(&net_tulip_info, &s->c, + object_get_typename(OBJECT(pci_dev)), +- pci_dev->qdev.id, s); ++ pci_dev->qdev.id, ++ &pci_dev->qdev.mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a); + } + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index 3e1fa6adf3..d7405c3bf1 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -3585,10 +3585,12 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) + * Happen when virtio_net_set_netclient_name has been called. + */ + n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf, +- n->netclient_type, n->netclient_name, n); ++ n->netclient_type, n->netclient_name, ++ &dev->mem_reentrancy_guard, n); + } else { + n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf, +- object_get_typename(OBJECT(dev)), dev->id, n); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, n); + } + + for (i = 0; i < n->max_queue_pairs; i++) { +diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c +index a2037583bf..2a32ab32ea 100644 +--- a/hw/net/vmxnet3.c ++++ b/hw/net/vmxnet3.c +@@ -2080,7 +2080,7 @@ static void vmxnet3_net_init(VMXNET3State *s) + + s->nic = qemu_new_nic(&net_vmxnet3_info, &s->conf, + object_get_typename(OBJECT(s)), +- d->id, s); ++ d->id, &d->mem_reentrancy_guard, s); + + s->peer_has_vhdr = vmxnet3_peer_has_vnet_hdr(s); + s->tx_sop = true; +diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c +index 5c815b4f0c..712fe6706d 100644 +--- a/hw/net/xen_nic.c ++++ b/hw/net/xen_nic.c +@@ -294,7 +294,7 @@ static int net_init(struct XenLegacyDevice *xendev) + } + + netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf, +- "xen", NULL, netdev); ++ "xen", NULL, &xendev->qdev.mem_reentrancy_guard, netdev); + + snprintf(qemu_get_queue(netdev->nic)->info_str, + sizeof(qemu_get_queue(netdev->nic)->info_str), +diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c +index 0ab6ae91aa..1f4f277d84 100644 +--- a/hw/net/xgmac.c ++++ b/hw/net/xgmac.c +@@ -402,7 +402,8 @@ static void xgmac_enet_realize(DeviceState *dev, Error **errp) + + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_xgmac_enet_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + + s->regs[XGMAC_ADDR_HIGH(0)] = (s->conf.macaddr.a[5] << 8) | +diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c +index 990ff3a1c2..8a34243803 100644 +--- a/hw/net/xilinx_axienet.c ++++ b/hw/net/xilinx_axienet.c +@@ -968,7 +968,8 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp) + + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_xilinx_enet_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + + tdk_init(&s->TEMAC.phy); +diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c +index 6e09f7e422..80cb869e22 100644 +--- a/hw/net/xilinx_ethlite.c ++++ b/hw/net/xilinx_ethlite.c +@@ -235,7 +235,8 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) + + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf, +- object_get_typename(OBJECT(dev)), dev->id, s); ++ object_get_typename(OBJECT(dev)), dev->id, ++ &dev->mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + } + +diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c +index 6c49c16015..ae447a8bc3 100644 +--- a/hw/usb/dev-network.c ++++ b/hw/usb/dev-network.c +@@ -1362,7 +1362,8 @@ static void usb_net_realize(USBDevice *dev, Error **errp) + + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_usbnet_info, &s->conf, +- object_get_typename(OBJECT(s)), s->dev.qdev.id, s); ++ object_get_typename(OBJECT(s)), s->dev.qdev.id, ++ &s->dev.qdev.mem_reentrancy_guard, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + snprintf(s->usbstring_mac, sizeof(s->usbstring_mac), + "%02x%02x%02x%02x%02x%02x", +diff --git a/include/net/net.h b/include/net/net.h +index 81d0b21def..f5313b7e4e 100644 +--- a/include/net/net.h ++++ b/include/net/net.h +@@ -151,6 +151,7 @@ NICState *qemu_new_nic(NetClientInfo *info, + NICConf *conf, + const char *model, + const char *name, ++ MemReentrancyGuard *reentrancy_guard, + void *opaque); + void qemu_del_nic(NICState *nic); + NetClientState *qemu_get_subqueue(NICState *nic, int queue_index); +diff --git a/net/net.c b/net/net.c +index daad8784ec..e4e4cf45a2 100644 +--- a/net/net.c ++++ b/net/net.c +@@ -299,6 +299,7 @@ NICState *qemu_new_nic(NetClientInfo *info, + NICConf *conf, + const char *model, + const char *name, ++ MemReentrancyGuard *reentrancy_guard, + void *opaque) + { + NetClientState **peers = conf->peers.ncs; +-- +2.27.0 + diff --git a/net-Update-MemReentrancyGuard-for-NIC-CVE-2023-3019.patch b/net-Update-MemReentrancyGuard-for-NIC-CVE-2023-3019.patch new file mode 100644 index 0000000..88ce75f --- /dev/null +++ b/net-Update-MemReentrancyGuard-for-NIC-CVE-2023-3019.patch @@ -0,0 +1,85 @@ +From e69961a3c833e79dbcaca3f651b6f0ebfc86c93b Mon Sep 17 00:00:00 2001 +From: Akihiko Odaki +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 +Signed-off-by: Akihiko Odaki +Acked-by: Alexander Bulekov +Signed-off-by: Jason Wang +--- + 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 + diff --git a/qemu.spec b/qemu.spec index 130ec0f..9faf51e 100644 --- a/qemu.spec +++ b/qemu.spec @@ -3,7 +3,7 @@ Name: qemu Version: 6.2.0 -Release: 88 +Release: 89 Epoch: 10 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -865,6 +865,16 @@ Patch0850: linux-user-fix-sockaddr_in6-endianness.patch Patch0851: migration-multifd-Remove-unnecessary-usage-of-local-.patch Patch0852: hw-i386-Fix-comment-style-in-topology.h.patch Patch0853: ui-vnc.c-Fixed-a-deadlock-bug.patch +Patch0854: memory-prevent-dma-reentracy-issues.patch +Patch0855: net-Provide-MemReentrancyGuard-to-qemu_new_nic.patch +Patch0856: net-Update-MemReentrancyGuard-for-NIC-CVE-2023-3019.patch +Patch0857: hw-scsi-lsi53c895a-Fix-reentrancy-issues-in-the-LSI-.patch +Patch0858: hw-scsi-lsi53c895a-add-missing-decrement-of-reentran.patch +Patch0859: esp-restrict-non-DMA-transfer-length-to-that-of-avai.patch +Patch0860: ui-clipboard-mark-type-as-not-available-when-there-i.patch +Patch0861: virtio-net-correctly-copy-vnet-header-when-flushing-.patch +Patch0862: hw-timer-fix-systick-trace-message.patch +Patch0863: qga-win-Fix-guest-get-fsinfo-multi-disks-collection.patch BuildRequires: flex BuildRequires: gcc @@ -1463,6 +1473,17 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Sat Mar 9 2024 - 10: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() + * Wed Feb 21 2024 - 10:6.2.0-88 - ui/vnc.c: Fixed a deadlock bug. - hw/i386: Fix comment style in topology.h diff --git a/qga-win-Fix-guest-get-fsinfo-multi-disks-collection.patch b/qga-win-Fix-guest-get-fsinfo-multi-disks-collection.patch new file mode 100644 index 0000000..2683aff --- /dev/null +++ b/qga-win-Fix-guest-get-fsinfo-multi-disks-collection.patch @@ -0,0 +1,40 @@ +From bf48c640251cfe8d9ed7744bc88f5a858b694275 Mon Sep 17 00:00:00 2001 +From: qihao +Date: Wed, 7 Feb 2024 17:26:58 +0800 +Subject: [PATCH] qga-win: Fix guest-get-fsinfo multi-disks collection + +cheery-pick from 7c4486350a79532580a37d42abdeb1dc7e4fa6c9 + +When a volume has more than one disk, all disks cannot be +returned correctly because there is not enough malloced memory +for disk extents, so before executing DeviceIoControl for the +second time, get the correct size of the required memory space +to store all disk extents. + +Details: +https://learn.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-volume_disk_extents + +Signed-off-by: Peng Ji +Reviewed-by: Konstantin Kostiuk +Signed-off-by: Konstantin Kostiuk +Signed-off-by: qihao_yewu +--- + qga/commands-win32.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/qga/commands-win32.c b/qga/commands-win32.c +index 4e84afd83b..30e50f1769 100644 +--- a/qga/commands-win32.c ++++ b/qga/commands-win32.c +@@ -904,6 +904,8 @@ static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp) + DWORD last_err = GetLastError(); + if (last_err == ERROR_MORE_DATA) { + /* Try once more with big enough buffer */ ++ size = sizeof(VOLUME_DISK_EXTENTS) + ++ (sizeof(DISK_EXTENT) * (extents->NumberOfDiskExtents - 1)); + g_free(extents); + extents = g_malloc0(size); + if (!DeviceIoControl( +-- +2.27.0 + diff --git a/ui-clipboard-mark-type-as-not-available-when-there-i.patch b/ui-clipboard-mark-type-as-not-available-when-there-i.patch new file mode 100644 index 0000000..e698dec --- /dev/null +++ b/ui-clipboard-mark-type-as-not-available-when-there-i.patch @@ -0,0 +1,89 @@ +From 6c61db85b2410480a203febabd12130a81f6f975 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +Date: Wed, 24 Jan 2024 11:57:48 +0100 +Subject: [PATCH] ui/clipboard: mark type as not available when there is no + data (CVE-2023-6683) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With VNC, a client can send a non-extended VNC_MSG_CLIENT_CUT_TEXT +message with len=0. In qemu_clipboard_set_data(), the clipboard info +will be updated setting data to NULL (because g_memdup(data, size) +returns NULL when size is 0). If the client does not set the +VNC_ENCODING_CLIPBOARD_EXT feature when setting up the encodings, then +the 'request' callback for the clipboard peer is not initialized. +Later, because data is NULL, qemu_clipboard_request() can be reached +via vdagent_chr_write() and vdagent_clipboard_recv_request() and +there, the clipboard owner's 'request' callback will be attempted to +be called, but that is a NULL pointer. + +In particular, this can happen when using the KRDC (22.12.3) VNC +client. + +Another scenario leading to the same issue is with two clients (say +noVNC and KRDC): + +The noVNC client sets the extension VNC_FEATURE_CLIPBOARD_EXT and +initializes its cbpeer. + +The KRDC client does not, but triggers a vnc_client_cut_text() (note +it's not the _ext variant)). There, a new clipboard info with it as +the 'owner' is created and via qemu_clipboard_set_data() is called, +which in turn calls qemu_clipboard_update() with that info. + +In qemu_clipboard_update(), the notifier for the noVNC client will be +called, i.e. vnc_clipboard_notify() and also set vs->cbinfo for the +noVNC client. The 'owner' in that clipboard info is the clipboard peer +for the KRDC client, which did not initialize the 'request' function. +That sounds correct to me, it is the owner of that clipboard info. + +Then when noVNC sends a VNC_MSG_CLIENT_CUT_TEXT message (it did set +the VNC_FEATURE_CLIPBOARD_EXT feature correctly, so a check for it +passes), that clipboard info is passed to qemu_clipboard_request() and +the original segfault still happens. + +Fix the issue by handling updates with size 0 differently. In +particular, mark in the clipboard info that the type is not available. + +While at it, switch to g_memdup2(), because g_memdup() is deprecated. + +Cc: qemu-stable@nongnu.org +Fixes: CVE-2023-6683 +Reported-by: Markus Frank +Suggested-by: Marc-André Lureau +Signed-off-by: Fiona Ebner +Reviewed-by: Marc-André Lureau +Tested-by: Markus Frank +Message-ID: <20240124105749.204610-1-f.ebner@proxmox.com> +Signed-off-by: liuxiangdong +--- + ui/clipboard.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/ui/clipboard.c b/ui/clipboard.c +index d7b008d62a..6721852cb6 100644 +--- a/ui/clipboard.c ++++ b/ui/clipboard.c +@@ -123,9 +123,15 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer, + } + + g_free(info->types[type].data); +- info->types[type].data = g_memdup(data, size); +- info->types[type].size = size; +- info->types[type].available = true; ++ if (size) { ++ info->types[type].data = g_memdup(data, size); ++ info->types[type].size = size; ++ info->types[type].available = true; ++ } else { ++ info->types[type].data = NULL; ++ info->types[type].size = 0; ++ info->types[type].available = false; ++ } + + if (update) { + qemu_clipboard_update(info); +-- +2.27.0 + diff --git a/virtio-net-correctly-copy-vnet-header-when-flushing-.patch b/virtio-net-correctly-copy-vnet-header-when-flushing-.patch new file mode 100644 index 0000000..850fb29 --- /dev/null +++ b/virtio-net-correctly-copy-vnet-header-when-flushing-.patch @@ -0,0 +1,72 @@ +From 15f89b0447956d16f9ff20e243fa9076e5dd9af1 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Tue, 2 Jan 2024 11:29:01 +0800 +Subject: [PATCH] virtio-net: correctly copy vnet header when flushing TX + (CVE-2023-6693) + +When HASH_REPORT is negotiated, the guest_hdr_len might be larger than +the size of the mergeable rx buffer header. Using +virtio_net_hdr_mrg_rxbuf during the header swap might lead a stack +overflow in this case. Fixing this by using virtio_net_hdr_v1_hash +instead. + +Reported-by: Xiao Lei +Cc: Yuri Benditovich +Cc: qemu-stable@nongnu.org +Cc: Mauro Matteo Cascella +Fixes: CVE-2023-6693 +Fixes: e22f0603fb2f ("virtio-net: reference implementation of hash report") +Reviewed-by: Michael Tokarev +Signed-off-by: Jason Wang +--- + hw/net/virtio-net.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index d7405c3bf1..cdf1313053 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -600,6 +600,11 @@ static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs, + + n->mergeable_rx_bufs = mergeable_rx_bufs; + ++ /* ++ * Note: when extending the vnet header, please make sure to ++ * change the vnet header copying logic in virtio_net_flush_tx() ++ * as well. ++ */ + if (version_1) { + n->guest_hdr_len = hash_report ? + sizeof(struct virtio_net_hdr_v1_hash) : +@@ -2586,7 +2591,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) + ssize_t ret; + unsigned int out_num; + struct iovec sg[VIRTQUEUE_MAX_SIZE], sg2[VIRTQUEUE_MAX_SIZE + 1], *out_sg; +- struct virtio_net_hdr_mrg_rxbuf mhdr; ++ struct virtio_net_hdr_v1_hash vhdr; + + elem = virtqueue_pop(q->tx_vq, sizeof(VirtQueueElement)); + if (!elem) { +@@ -2603,7 +2608,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) + } + + if (n->has_vnet_hdr) { +- if (iov_to_buf(out_sg, out_num, 0, &mhdr, n->guest_hdr_len) < ++ if (iov_to_buf(out_sg, out_num, 0, &vhdr, n->guest_hdr_len) < + n->guest_hdr_len) { + virtio_error(vdev, "virtio-net header incorrect"); + virtqueue_detach_element(q->tx_vq, elem, 0); +@@ -2611,8 +2616,8 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) + return -EINVAL; + } + if (n->needs_vnet_hdr_swap) { +- virtio_net_hdr_swap(vdev, (void *) &mhdr); +- sg2[0].iov_base = &mhdr; ++ virtio_net_hdr_swap(vdev, (void *) &vhdr); ++ sg2[0].iov_base = &vhdr; + sg2[0].iov_len = n->guest_hdr_len; + out_num = iov_copy(&sg2[1], ARRAY_SIZE(sg2) - 1, + out_sg, out_num, +-- +2.27.0 + -- Gitee