diff options
| author | Yogita Urade <yogita.urade@windriver.com> | 2024-10-24 08:02:35 +0000 |
|---|---|---|
| committer | Steve Sakoman <steve@sakoman.com> | 2024-11-02 06:32:36 -0700 |
| commit | e50d61d7df1aaa7a8850a4cc1ae661d657c311d5 (patch) | |
| tree | 48dce4615f579c389a972cf93ae22556fd73ac64 | |
| parent | bce20db02a0c33f1cdb1a83c062b4699b6676928 (diff) | |
| download | poky-e50d61d7df1aaa7a8850a4cc1ae661d657c311d5.tar.gz | |
qemu: fix CVE-2023-3019
A DMA reentrancy issue leading to a use-after-free error
was found in the e1000e NIC emulation code in QEMU. This
issue could allow a privileged guest user to crash the
QEMU process on the host, resulting in a denial of service.
CVE-2023-3019-0002 is the CVE fix and CVE-2023-3019-0001
is dependent CVE fix.
fix indent issue in qemu.inc file.
CVE-2023-3019 patch required Mem ReenttranceyGuard structure
definition, it's defined in commit:
https://github.com/qemu/qemu/commit/a2e1753b8054344f32cf94f31c6399a58794a380
but the patch is causing errors:
Failed: qemux86 does not shutdown within timeout(120)
so backported only required structure definition.
Reference:
https://nvd.nist.gov/vuln/detail/CVE-2023-3019
Upstream patches:
https://github.com/qemu/qemu/commit/7d0fefdf81f5973334c344f6b8e1896c309dff66
https://github.com/qemu/qemu/commit/3c0463a650008aec7de29cf84540652730510921
(From OE-Core rev: 3782e1b21882ffc5e4cc466418e066179470241e)
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu.inc | 18 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2023-3019-0001.patch | 622 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2023-3019-0002.patch | 91 |
3 files changed, 723 insertions, 8 deletions
diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc index 6ff3c2f9bc..1c0e8a93f1 100644 --- a/meta/recipes-devtools/qemu/qemu.inc +++ b/meta/recipes-devtools/qemu/qemu.inc | |||
| @@ -97,14 +97,14 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \ | |||
| 97 | file://CVE-2023-3301.patch \ | 97 | file://CVE-2023-3301.patch \ |
| 98 | file://CVE-2023-3255.patch \ | 98 | file://CVE-2023-3255.patch \ |
| 99 | file://CVE-2023-2861.patch \ | 99 | file://CVE-2023-2861.patch \ |
| 100 | file://CVE-2020-14394.patch \ | 100 | file://CVE-2020-14394.patch \ |
| 101 | file://CVE-2023-3354.patch \ | 101 | file://CVE-2023-3354.patch \ |
| 102 | file://CVE-2023-3180.patch \ | 102 | file://CVE-2023-3180.patch \ |
| 103 | file://CVE-2021-3638.patch \ | 103 | file://CVE-2021-3638.patch \ |
| 104 | file://CVE-2023-1544.patch \ | 104 | file://CVE-2023-1544.patch \ |
| 105 | file://CVE-2023-5088.patch \ | 105 | file://CVE-2023-5088.patch \ |
| 106 | file://CVE-2024-24474.patch \ | 106 | file://CVE-2024-24474.patch \ |
| 107 | file://CVE-2023-6693.patch \ | 107 | file://CVE-2023-6693.patch \ |
| 108 | file://scsi-disk-allow-MODE-SELECT-block-desriptor-to-set-the-block-size.patch \ | 108 | file://scsi-disk-allow-MODE-SELECT-block-desriptor-to-set-the-block-size.patch \ |
| 109 | file://scsi-disk-ensure-block-size-is-non-zero-and-changes-limited-to-bits-8-15.patch \ | 109 | file://scsi-disk-ensure-block-size-is-non-zero-and-changes-limited-to-bits-8-15.patch \ |
| 110 | file://CVE-2023-42467.patch \ | 110 | file://CVE-2023-42467.patch \ |
| @@ -118,6 +118,8 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \ | |||
| 118 | file://CVE-2024-4467-0003.patch \ | 118 | file://CVE-2024-4467-0003.patch \ |
| 119 | file://CVE-2024-4467-0004.patch \ | 119 | file://CVE-2024-4467-0004.patch \ |
| 120 | file://CVE-2024-4467-0005.patch \ | 120 | file://CVE-2024-4467-0005.patch \ |
| 121 | file://CVE-2023-3019-0001.patch \ | ||
| 122 | file://CVE-2023-3019-0002.patch \ | ||
| 121 | " | 123 | " |
| 122 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" | 124 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" |
| 123 | 125 | ||
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2023-3019-0001.patch b/meta/recipes-devtools/qemu/qemu/CVE-2023-3019-0001.patch new file mode 100644 index 0000000000..fccfe7d114 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2023-3019-0001.patch | |||
| @@ -0,0 +1,622 @@ | |||
| 1 | From 7d0fefdf81f5973334c344f6b8e1896c309dff66 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
| 3 | Date: Thu, 1 Jun 2023 12:18:58 +0900 | ||
| 4 | Subject: [PATCH] net: Provide MemReentrancyGuard * to qemu_new_nic() | ||
| 5 | |||
| 6 | Recently MemReentrancyGuard was added to DeviceState to record that the | ||
| 7 | device is engaging in I/O. The network device backend needs to update it | ||
| 8 | when delivering a packet to a device. | ||
| 9 | |||
| 10 | In preparation for such a change, add MemReentrancyGuard * as a | ||
| 11 | parameter of qemu_new_nic(). | ||
| 12 | |||
| 13 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
| 14 | Reviewed-by: Alexander Bulekov <alxndr@bu.edu> | ||
| 15 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
| 16 | |||
| 17 | CVE: CVE-2023-3019 | ||
| 18 | Upstream-Status: Backport [https://github.com/qemu/qemu/commit/7d0fefdf81f5973334c344f6b8e1896c309dff66] | ||
| 19 | |||
| 20 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
| 21 | --- | ||
| 22 | hw/arm/musicpal.c | 3 ++- | ||
| 23 | hw/net/allwinner-sun8i-emac.c | 3 ++- | ||
| 24 | hw/net/allwinner_emac.c | 3 ++- | ||
| 25 | hw/net/cadence_gem.c | 3 ++- | ||
| 26 | hw/net/dp8393x.c | 3 ++- | ||
| 27 | hw/net/e1000.c | 3 ++- | ||
| 28 | hw/net/e1000e.c | 2 +- | ||
| 29 | hw/net/eepro100.c | 4 +++- | ||
| 30 | hw/net/etraxfs_eth.c | 3 ++- | ||
| 31 | hw/net/fsl_etsec/etsec.c | 3 ++- | ||
| 32 | hw/net/ftgmac100.c | 3 ++- | ||
| 33 | hw/net/imx_fec.c | 2 +- | ||
| 34 | hw/net/lan9118.c | 3 ++- | ||
| 35 | hw/net/mcf_fec.c | 3 ++- | ||
| 36 | hw/net/mipsnet.c | 3 ++- | ||
| 37 | hw/net/msf2-emac.c | 3 ++- | ||
| 38 | hw/net/ne2000-isa.c | 3 ++- | ||
| 39 | hw/net/ne2000-pci.c | 3 ++- | ||
| 40 | hw/net/npcm7xx_emc.c | 3 ++- | ||
| 41 | hw/net/opencores_eth.c | 3 ++- | ||
| 42 | hw/net/pcnet.c | 3 ++- | ||
| 43 | hw/net/rocker/rocker_fp.c | 4 ++-- | ||
| 44 | hw/net/rtl8139.c | 3 ++- | ||
| 45 | hw/net/smc91c111.c | 3 ++- | ||
| 46 | hw/net/spapr_llan.c | 3 ++- | ||
| 47 | hw/net/stellaris_enet.c | 3 ++- | ||
| 48 | hw/net/sungem.c | 2 +- | ||
| 49 | hw/net/sunhme.c | 3 ++- | ||
| 50 | hw/net/tulip.c | 3 ++- | ||
| 51 | hw/net/virtio-net.c | 6 ++++-- | ||
| 52 | hw/net/vmxnet3.c | 2 +- | ||
| 53 | hw/net/xen_nic.c | 4 +++- | ||
| 54 | hw/net/xgmac.c | 3 ++- | ||
| 55 | hw/net/xilinx_axienet.c | 3 ++- | ||
| 56 | hw/net/xilinx_ethlite.c | 3 ++- | ||
| 57 | hw/usb/dev-network.c | 3 ++- | ||
| 58 | include/hw/qdev-core.h | 7 +++++++ | ||
| 59 | include/net/net.h | 1 + | ||
| 60 | net/net.c | 1 + | ||
| 61 | 39 files changed, 81 insertions(+), 38 deletions(-) | ||
| 62 | |||
| 63 | diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c | ||
| 64 | index 2680ec55b..15fc7fee4 100644 | ||
| 65 | --- a/hw/arm/musicpal.c | ||
| 66 | +++ b/hw/arm/musicpal.c | ||
| 67 | @@ -418,7 +418,8 @@ static void mv88w8618_eth_realize(DeviceState *dev, Error **errp) | ||
| 68 | |||
| 69 | address_space_init(&s->dma_as, s->dma_mr, "emac-dma"); | ||
| 70 | s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf, | ||
| 71 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 72 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 73 | + &dev->mem_reentrancy_guard, s); | ||
| 74 | } | ||
| 75 | |||
| 76 | static const VMStateDescription mv88w8618_eth_vmsd = { | ||
| 77 | diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c | ||
| 78 | index ecc0245fe..cf93b2fda 100644 | ||
| 79 | --- a/hw/net/allwinner-sun8i-emac.c | ||
| 80 | +++ b/hw/net/allwinner-sun8i-emac.c | ||
| 81 | @@ -816,7 +816,8 @@ static void allwinner_sun8i_emac_realize(DeviceState *dev, Error **errp) | ||
| 82 | |||
| 83 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 84 | s->nic = qemu_new_nic(&net_allwinner_sun8i_emac_info, &s->conf, | ||
| 85 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 86 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 87 | + &dev->mem_reentrancy_guard, s); | ||
| 88 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 89 | } | ||
| 90 | |||
| 91 | diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c | ||
| 92 | index ddddf35c4..b3d73143b 100644 | ||
| 93 | --- a/hw/net/allwinner_emac.c | ||
| 94 | +++ b/hw/net/allwinner_emac.c | ||
| 95 | @@ -453,7 +453,8 @@ static void aw_emac_realize(DeviceState *dev, Error **errp) | ||
| 96 | |||
| 97 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 98 | s->nic = qemu_new_nic(&net_aw_emac_info, &s->conf, | ||
| 99 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 100 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 101 | + &dev->mem_reentrancy_guard, s); | ||
| 102 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 103 | |||
| 104 | fifo8_create(&s->rx_fifo, RX_FIFO_SIZE); | ||
| 105 | diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c | ||
| 106 | index 24b3a0ff6..cb61a7641 100644 | ||
| 107 | --- a/hw/net/cadence_gem.c | ||
| 108 | +++ b/hw/net/cadence_gem.c | ||
| 109 | @@ -1633,7 +1633,8 @@ static void gem_realize(DeviceState *dev, Error **errp) | ||
| 110 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 111 | |||
| 112 | s->nic = qemu_new_nic(&net_gem_info, &s->conf, | ||
| 113 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 114 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 115 | + &dev->mem_reentrancy_guard, s); | ||
| 116 | |||
| 117 | if (s->jumbo_max_len > MAX_FRAME_SIZE) { | ||
| 118 | error_setg(errp, "jumbo-max-len is greater than %d", | ||
| 119 | diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c | ||
| 120 | index 45b954e46..abfcc6f69 100644 | ||
| 121 | --- a/hw/net/dp8393x.c | ||
| 122 | +++ b/hw/net/dp8393x.c | ||
| 123 | @@ -943,7 +943,8 @@ static void dp8393x_realize(DeviceState *dev, Error **errp) | ||
| 124 | "dp8393x-regs", SONIC_REG_COUNT << s->it_shift); | ||
| 125 | |||
| 126 | s->nic = qemu_new_nic(&net_dp83932_info, &s->conf, | ||
| 127 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 128 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 129 | + &dev->mem_reentrancy_guard, s); | ||
| 130 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 131 | |||
| 132 | s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s); | ||
| 133 | diff --git a/hw/net/e1000.c b/hw/net/e1000.c | ||
| 134 | index f5bc81296..0857c2e7d 100644 | ||
| 135 | --- a/hw/net/e1000.c | ||
| 136 | +++ b/hw/net/e1000.c | ||
| 137 | @@ -1733,7 +1733,8 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp) | ||
| 138 | macaddr); | ||
| 139 | |||
| 140 | d->nic = qemu_new_nic(&net_e1000_info, &d->conf, | ||
| 141 | - object_get_typename(OBJECT(d)), dev->id, d); | ||
| 142 | + object_get_typename(OBJECT(d)), dev->id, | ||
| 143 | + &dev->mem_reentrancy_guard, d); | ||
| 144 | |||
| 145 | qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr); | ||
| 146 | |||
| 147 | diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c | ||
| 148 | index ac96f7665..b6e9b0e17 100644 | ||
| 149 | --- a/hw/net/e1000e.c | ||
| 150 | +++ b/hw/net/e1000e.c | ||
| 151 | @@ -328,7 +328,7 @@ e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, uint8_t *macaddr) | ||
| 152 | int i; | ||
| 153 | |||
| 154 | s->nic = qemu_new_nic(&net_e1000e_info, &s->conf, | ||
| 155 | - object_get_typename(OBJECT(s)), dev->id, s); | ||
| 156 | + object_get_typename(OBJECT(s)), dev->id, &dev->mem_reentrancy_guard, s); | ||
| 157 | |||
| 158 | s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 0; | ||
| 159 | |||
| 160 | diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c | ||
| 161 | index 679f52f80..871d9a095 100644 | ||
| 162 | --- a/hw/net/eepro100.c | ||
| 163 | +++ b/hw/net/eepro100.c | ||
| 164 | @@ -1874,7 +1874,9 @@ static void e100_nic_realize(PCIDevice *pci_dev, Error **errp) | ||
| 165 | nic_reset(s); | ||
| 166 | |||
| 167 | s->nic = qemu_new_nic(&net_eepro100_info, &s->conf, | ||
| 168 | - object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s); | ||
| 169 | + object_get_typename(OBJECT(pci_dev)), | ||
| 170 | + pci_dev->qdev.id, | ||
| 171 | + &pci_dev->qdev.mem_reentrancy_guard, s); | ||
| 172 | |||
| 173 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 174 | TRACE(OTHER, logout("%s\n", qemu_get_queue(s->nic)->info_str)); | ||
| 175 | diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c | ||
| 176 | index 1b82aec79..ba57a978d 100644 | ||
| 177 | --- a/hw/net/etraxfs_eth.c | ||
| 178 | +++ b/hw/net/etraxfs_eth.c | ||
| 179 | @@ -618,7 +618,8 @@ static void etraxfs_eth_realize(DeviceState *dev, Error **errp) | ||
| 180 | |||
| 181 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 182 | s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf, | ||
| 183 | - object_get_typename(OBJECT(s)), dev->id, s); | ||
| 184 | + object_get_typename(OBJECT(s)), dev->id, | ||
| 185 | + &dev->mem_reentrancy_guard, s); | ||
| 186 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 187 | |||
| 188 | s->phy.read = tdk_read; | ||
| 189 | diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c | ||
| 190 | index bd9d62b55..f790613b5 100644 | ||
| 191 | --- a/hw/net/fsl_etsec/etsec.c | ||
| 192 | +++ b/hw/net/fsl_etsec/etsec.c | ||
| 193 | @@ -391,7 +391,8 @@ static void etsec_realize(DeviceState *dev, Error **errp) | ||
| 194 | eTSEC *etsec = ETSEC_COMMON(dev); | ||
| 195 | |||
| 196 | etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf, | ||
| 197 | - object_get_typename(OBJECT(dev)), dev->id, etsec); | ||
| 198 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 199 | + &dev->mem_reentrancy_guard, etsec); | ||
| 200 | qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a); | ||
| 201 | |||
| 202 | etsec->ptimer = ptimer_init(etsec_timer_hit, etsec, PTIMER_POLICY_DEFAULT); | ||
| 203 | diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c | ||
| 204 | index 83ef0a783..346485ab4 100644 | ||
| 205 | --- a/hw/net/ftgmac100.c | ||
| 206 | +++ b/hw/net/ftgmac100.c | ||
| 207 | @@ -1118,7 +1118,8 @@ static void ftgmac100_realize(DeviceState *dev, Error **errp) | ||
| 208 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 209 | |||
| 210 | s->nic = qemu_new_nic(&net_ftgmac100_info, &s->conf, | ||
| 211 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 212 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 213 | + &dev->mem_reentrancy_guard, s); | ||
| 214 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 215 | } | ||
| 216 | |||
| 217 | diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c | ||
| 218 | index 0db9aaf76..74e7e0d12 100644 | ||
| 219 | --- a/hw/net/imx_fec.c | ||
| 220 | +++ b/hw/net/imx_fec.c | ||
| 221 | @@ -1318,7 +1318,7 @@ static void imx_eth_realize(DeviceState *dev, Error **errp) | ||
| 222 | |||
| 223 | s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf, | ||
| 224 | object_get_typename(OBJECT(dev)), | ||
| 225 | - dev->id, s); | ||
| 226 | + dev->id, &dev->mem_reentrancy_guard, s); | ||
| 227 | |||
| 228 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 229 | } | ||
| 230 | diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c | ||
| 231 | index 6aff424cb..942bce9ae 100644 | ||
| 232 | --- a/hw/net/lan9118.c | ||
| 233 | +++ b/hw/net/lan9118.c | ||
| 234 | @@ -1354,7 +1354,8 @@ static void lan9118_realize(DeviceState *dev, Error **errp) | ||
| 235 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 236 | |||
| 237 | s->nic = qemu_new_nic(&net_lan9118_info, &s->conf, | ||
| 238 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 239 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 240 | + &dev->mem_reentrancy_guard, s); | ||
| 241 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 242 | s->eeprom[0] = 0xa5; | ||
| 243 | for (i = 0; i < 6; i++) { | ||
| 244 | diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c | ||
| 245 | index 25e3e453a..a6be7bf41 100644 | ||
| 246 | --- a/hw/net/mcf_fec.c | ||
| 247 | +++ b/hw/net/mcf_fec.c | ||
| 248 | @@ -643,7 +643,8 @@ static void mcf_fec_realize(DeviceState *dev, Error **errp) | ||
| 249 | mcf_fec_state *s = MCF_FEC_NET(dev); | ||
| 250 | |||
| 251 | s->nic = qemu_new_nic(&net_mcf_fec_info, &s->conf, | ||
| 252 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 253 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 254 | + &dev->mem_reentrancy_guard, s); | ||
| 255 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 256 | } | ||
| 257 | |||
| 258 | diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c | ||
| 259 | index 2ade72dea..8e925de86 100644 | ||
| 260 | --- a/hw/net/mipsnet.c | ||
| 261 | +++ b/hw/net/mipsnet.c | ||
| 262 | @@ -255,7 +255,8 @@ static void mipsnet_realize(DeviceState *dev, Error **errp) | ||
| 263 | sysbus_init_irq(sbd, &s->irq); | ||
| 264 | |||
| 265 | s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf, | ||
| 266 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 267 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 268 | + &dev->mem_reentrancy_guard, s); | ||
| 269 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 270 | } | ||
| 271 | |||
| 272 | diff --git a/hw/net/msf2-emac.c b/hw/net/msf2-emac.c | ||
| 273 | index 9278fdce0..1efa3dbf0 100644 | ||
| 274 | --- a/hw/net/msf2-emac.c | ||
| 275 | +++ b/hw/net/msf2-emac.c | ||
| 276 | @@ -527,7 +527,8 @@ static void msf2_emac_realize(DeviceState *dev, Error **errp) | ||
| 277 | |||
| 278 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 279 | s->nic = qemu_new_nic(&net_msf2_emac_info, &s->conf, | ||
| 280 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 281 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 282 | + &dev->mem_reentrancy_guard, s); | ||
| 283 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 284 | } | ||
| 285 | |||
| 286 | diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c | ||
| 287 | index dd6f6e34d..30bd20c29 100644 | ||
| 288 | --- a/hw/net/ne2000-isa.c | ||
| 289 | +++ b/hw/net/ne2000-isa.c | ||
| 290 | @@ -74,7 +74,8 @@ static void isa_ne2000_realizefn(DeviceState *dev, Error **errp) | ||
| 291 | ne2000_reset(s); | ||
| 292 | |||
| 293 | s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c, | ||
| 294 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 295 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 296 | + &dev->mem_reentrancy_guard, s); | ||
| 297 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a); | ||
| 298 | } | ||
| 299 | |||
| 300 | diff --git a/hw/net/ne2000-pci.c b/hw/net/ne2000-pci.c | ||
| 301 | index 9e5d10859..4f8a69908 100644 | ||
| 302 | --- a/hw/net/ne2000-pci.c | ||
| 303 | +++ b/hw/net/ne2000-pci.c | ||
| 304 | @@ -71,7 +71,8 @@ static void pci_ne2000_realize(PCIDevice *pci_dev, Error **errp) | ||
| 305 | |||
| 306 | s->nic = qemu_new_nic(&net_ne2000_info, &s->c, | ||
| 307 | object_get_typename(OBJECT(pci_dev)), | ||
| 308 | - pci_dev->qdev.id, s); | ||
| 309 | + pci_dev->qdev.id, | ||
| 310 | + &pci_dev->qdev.mem_reentrancy_guard, s); | ||
| 311 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a); | ||
| 312 | } | ||
| 313 | |||
| 314 | diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c | ||
| 315 | index df2efe1bf..82e063ae9 100644 | ||
| 316 | --- a/hw/net/npcm7xx_emc.c | ||
| 317 | +++ b/hw/net/npcm7xx_emc.c | ||
| 318 | @@ -806,7 +806,8 @@ static void npcm7xx_emc_realize(DeviceState *dev, Error **errp) | ||
| 319 | |||
| 320 | qemu_macaddr_default_if_unset(&emc->conf.macaddr); | ||
| 321 | emc->nic = qemu_new_nic(&net_npcm7xx_emc_info, &emc->conf, | ||
| 322 | - object_get_typename(OBJECT(dev)), dev->id, emc); | ||
| 323 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 324 | + &dev->mem_reentrancy_guard, emc); | ||
| 325 | qemu_format_nic_info_str(qemu_get_queue(emc->nic), emc->conf.macaddr.a); | ||
| 326 | } | ||
| 327 | |||
| 328 | diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c | ||
| 329 | index 0b3dc3146..f96d6ea2c 100644 | ||
| 330 | --- a/hw/net/opencores_eth.c | ||
| 331 | +++ b/hw/net/opencores_eth.c | ||
| 332 | @@ -732,7 +732,8 @@ static void sysbus_open_eth_realize(DeviceState *dev, Error **errp) | ||
| 333 | sysbus_init_irq(sbd, &s->irq); | ||
| 334 | |||
| 335 | s->nic = qemu_new_nic(&net_open_eth_info, &s->conf, | ||
| 336 | - object_get_typename(OBJECT(s)), dev->id, s); | ||
| 337 | + object_get_typename(OBJECT(s)), dev->id, | ||
| 338 | + &dev->mem_reentrancy_guard, s); | ||
| 339 | } | ||
| 340 | |||
| 341 | static void qdev_open_eth_reset(DeviceState *dev) | ||
| 342 | diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c | ||
| 343 | index dcd3fc494..da910a70b 100644 | ||
| 344 | --- a/hw/net/pcnet.c | ||
| 345 | +++ b/hw/net/pcnet.c | ||
| 346 | @@ -1718,7 +1718,8 @@ void pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info) | ||
| 347 | s->poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pcnet_poll_timer, s); | ||
| 348 | |||
| 349 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 350 | - s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 351 | + s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), | ||
| 352 | + dev->id, &dev->mem_reentrancy_guard, s); | ||
| 353 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 354 | |||
| 355 | /* Initialize the PROM */ | ||
| 356 | diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c | ||
| 357 | index cbeed65bd..0d21948ad 100644 | ||
| 358 | --- a/hw/net/rocker/rocker_fp.c | ||
| 359 | +++ b/hw/net/rocker/rocker_fp.c | ||
| 360 | @@ -241,8 +241,8 @@ FpPort *fp_port_alloc(Rocker *r, char *sw_name, | ||
| 361 | port->conf.bootindex = -1; | ||
| 362 | port->conf.peers = *peers; | ||
| 363 | |||
| 364 | - port->nic = qemu_new_nic(&fp_port_info, &port->conf, | ||
| 365 | - sw_name, NULL, port); | ||
| 366 | + port->nic = qemu_new_nic(&fp_port_info, &port->conf, sw_name, NULL, | ||
| 367 | + &DEVICE(r)->mem_reentrancy_guard, port); | ||
| 368 | qemu_format_nic_info_str(qemu_get_queue(port->nic), | ||
| 369 | port->conf.macaddr.a); | ||
| 370 | |||
| 371 | diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c | ||
| 372 | index 90b4fc63c..43d65d725 100644 | ||
| 373 | --- a/hw/net/rtl8139.c | ||
| 374 | +++ b/hw/net/rtl8139.c | ||
| 375 | @@ -3398,7 +3398,8 @@ static void pci_rtl8139_realize(PCIDevice *dev, Error **errp) | ||
| 376 | s->eeprom.contents[9] = s->conf.macaddr.a[4] | s->conf.macaddr.a[5] << 8; | ||
| 377 | |||
| 378 | s->nic = qemu_new_nic(&net_rtl8139_info, &s->conf, | ||
| 379 | - object_get_typename(OBJECT(dev)), d->id, s); | ||
| 380 | + object_get_typename(OBJECT(dev)), d->id, | ||
| 381 | + &d->mem_reentrancy_guard, s); | ||
| 382 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 383 | |||
| 384 | s->cplus_txbuffer = NULL; | ||
| 385 | diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c | ||
| 386 | index ad778cd8f..4eda971ef 100644 | ||
| 387 | --- a/hw/net/smc91c111.c | ||
| 388 | +++ b/hw/net/smc91c111.c | ||
| 389 | @@ -783,7 +783,8 @@ static void smc91c111_realize(DeviceState *dev, Error **errp) | ||
| 390 | sysbus_init_irq(sbd, &s->irq); | ||
| 391 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 392 | s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf, | ||
| 393 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 394 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 395 | + &dev->mem_reentrancy_guard, s); | ||
| 396 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 397 | /* ??? Save/restore. */ | ||
| 398 | } | ||
| 399 | diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c | ||
| 400 | index a6876a936..475d5f3a3 100644 | ||
| 401 | --- a/hw/net/spapr_llan.c | ||
| 402 | +++ b/hw/net/spapr_llan.c | ||
| 403 | @@ -325,7 +325,8 @@ static void spapr_vlan_realize(SpaprVioDevice *sdev, Error **errp) | ||
| 404 | memcpy(&dev->perm_mac.a, &dev->nicconf.macaddr.a, sizeof(dev->perm_mac.a)); | ||
| 405 | |||
| 406 | dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf, | ||
| 407 | - object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev); | ||
| 408 | + object_get_typename(OBJECT(sdev)), sdev->qdev.id, | ||
| 409 | + &sdev->qdev.mem_reentrancy_guard, dev); | ||
| 410 | qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a); | ||
| 411 | |||
| 412 | dev->rxp_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, spapr_vlan_flush_rx_queue, | ||
| 413 | diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c | ||
| 414 | index 8dd60783d..6768a6912 100644 | ||
| 415 | --- a/hw/net/stellaris_enet.c | ||
| 416 | +++ b/hw/net/stellaris_enet.c | ||
| 417 | @@ -492,7 +492,8 @@ static void stellaris_enet_realize(DeviceState *dev, Error **errp) | ||
| 418 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 419 | |||
| 420 | s->nic = qemu_new_nic(&net_stellaris_enet_info, &s->conf, | ||
| 421 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 422 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 423 | + &dev->mem_reentrancy_guard, s); | ||
| 424 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 425 | } | ||
| 426 | |||
| 427 | diff --git a/hw/net/sungem.c b/hw/net/sungem.c | ||
| 428 | index 3684a4d73..c12d44e9d 100644 | ||
| 429 | --- a/hw/net/sungem.c | ||
| 430 | +++ b/hw/net/sungem.c | ||
| 431 | @@ -1361,7 +1361,7 @@ static void sungem_realize(PCIDevice *pci_dev, Error **errp) | ||
| 432 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 433 | s->nic = qemu_new_nic(&net_sungem_info, &s->conf, | ||
| 434 | object_get_typename(OBJECT(dev)), | ||
| 435 | - dev->id, s); | ||
| 436 | + dev->id, &dev->mem_reentrancy_guard, s); | ||
| 437 | qemu_format_nic_info_str(qemu_get_queue(s->nic), | ||
| 438 | s->conf.macaddr.a); | ||
| 439 | } | ||
| 440 | diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c | ||
| 441 | index fc34905f8..fa98528d7 100644 | ||
| 442 | --- a/hw/net/sunhme.c | ||
| 443 | +++ b/hw/net/sunhme.c | ||
| 444 | @@ -892,7 +892,8 @@ static void sunhme_realize(PCIDevice *pci_dev, Error **errp) | ||
| 445 | |||
| 446 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 447 | s->nic = qemu_new_nic(&net_sunhme_info, &s->conf, | ||
| 448 | - object_get_typename(OBJECT(d)), d->id, s); | ||
| 449 | + object_get_typename(OBJECT(d)), d->id, | ||
| 450 | + &d->mem_reentrancy_guard, s); | ||
| 451 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 452 | } | ||
| 453 | |||
| 454 | diff --git a/hw/net/tulip.c b/hw/net/tulip.c | ||
| 455 | index 5f8badefc..ccaa26fd8 100644 | ||
| 456 | --- a/hw/net/tulip.c | ||
| 457 | +++ b/hw/net/tulip.c | ||
| 458 | @@ -985,7 +985,8 @@ static void pci_tulip_realize(PCIDevice *pci_dev, Error **errp) | ||
| 459 | |||
| 460 | s->nic = qemu_new_nic(&net_tulip_info, &s->c, | ||
| 461 | object_get_typename(OBJECT(pci_dev)), | ||
| 462 | - pci_dev->qdev.id, s); | ||
| 463 | + pci_dev->qdev.id, | ||
| 464 | + &pci_dev->qdev.mem_reentrancy_guard, s); | ||
| 465 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a); | ||
| 466 | } | ||
| 467 | |||
| 468 | diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c | ||
| 469 | index 42e66697f..f916813bc 100644 | ||
| 470 | --- a/hw/net/virtio-net.c | ||
| 471 | +++ b/hw/net/virtio-net.c | ||
| 472 | @@ -3473,10 +3473,12 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) | ||
| 473 | * Happen when virtio_net_set_netclient_name has been called. | ||
| 474 | */ | ||
| 475 | n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf, | ||
| 476 | - n->netclient_type, n->netclient_name, n); | ||
| 477 | + n->netclient_type, n->netclient_name, | ||
| 478 | + &dev->mem_reentrancy_guard, n); | ||
| 479 | } else { | ||
| 480 | n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf, | ||
| 481 | - object_get_typename(OBJECT(dev)), dev->id, n); | ||
| 482 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 483 | + &dev->mem_reentrancy_guard, n); | ||
| 484 | } | ||
| 485 | |||
| 486 | for (i = 0; i < n->max_queue_pairs; i++) { | ||
| 487 | diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c | ||
| 488 | index f65af4e9e..d4df039c5 100644 | ||
| 489 | --- a/hw/net/vmxnet3.c | ||
| 490 | +++ b/hw/net/vmxnet3.c | ||
| 491 | @@ -2078,7 +2078,7 @@ static void vmxnet3_net_init(VMXNET3State *s) | ||
| 492 | |||
| 493 | s->nic = qemu_new_nic(&net_vmxnet3_info, &s->conf, | ||
| 494 | object_get_typename(OBJECT(s)), | ||
| 495 | - d->id, s); | ||
| 496 | + d->id, &d->mem_reentrancy_guard, s); | ||
| 497 | |||
| 498 | s->peer_has_vhdr = vmxnet3_peer_has_vnet_hdr(s); | ||
| 499 | s->tx_sop = true; | ||
| 500 | diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c | ||
| 501 | index 5c815b4f0..0472ed81b 100644 | ||
| 502 | --- a/hw/net/xen_nic.c | ||
| 503 | +++ b/hw/net/xen_nic.c | ||
| 504 | @@ -294,7 +294,9 @@ static int net_init(struct XenLegacyDevice *xendev) | ||
| 505 | } | ||
| 506 | |||
| 507 | netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf, | ||
| 508 | - "xen", NULL, netdev); | ||
| 509 | + "xen", | ||
| 510 | + DEVICE(xendev)->id, | ||
| 511 | + &xendev->qdev.mem_reentrancy_guard, netdev); | ||
| 512 | |||
| 513 | snprintf(qemu_get_queue(netdev->nic)->info_str, | ||
| 514 | sizeof(qemu_get_queue(netdev->nic)->info_str), | ||
| 515 | diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c | ||
| 516 | index 0ab6ae91a..1f4f277d8 100644 | ||
| 517 | --- a/hw/net/xgmac.c | ||
| 518 | +++ b/hw/net/xgmac.c | ||
| 519 | @@ -402,7 +402,8 @@ static void xgmac_enet_realize(DeviceState *dev, Error **errp) | ||
| 520 | |||
| 521 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 522 | s->nic = qemu_new_nic(&net_xgmac_enet_info, &s->conf, | ||
| 523 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 524 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 525 | + &dev->mem_reentrancy_guard, s); | ||
| 526 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 527 | |||
| 528 | s->regs[XGMAC_ADDR_HIGH(0)] = (s->conf.macaddr.a[5] << 8) | | ||
| 529 | diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c | ||
| 530 | index 990ff3a1c..8a3424380 100644 | ||
| 531 | --- a/hw/net/xilinx_axienet.c | ||
| 532 | +++ b/hw/net/xilinx_axienet.c | ||
| 533 | @@ -968,7 +968,8 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp) | ||
| 534 | |||
| 535 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 536 | s->nic = qemu_new_nic(&net_xilinx_enet_info, &s->conf, | ||
| 537 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 538 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 539 | + &dev->mem_reentrancy_guard, s); | ||
| 540 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 541 | |||
| 542 | tdk_init(&s->TEMAC.phy); | ||
| 543 | diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c | ||
| 544 | index 6e09f7e42..80cb869e2 100644 | ||
| 545 | --- a/hw/net/xilinx_ethlite.c | ||
| 546 | +++ b/hw/net/xilinx_ethlite.c | ||
| 547 | @@ -235,7 +235,8 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) | ||
| 548 | |||
| 549 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 550 | s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf, | ||
| 551 | - object_get_typename(OBJECT(dev)), dev->id, s); | ||
| 552 | + object_get_typename(OBJECT(dev)), dev->id, | ||
| 553 | + &dev->mem_reentrancy_guard, s); | ||
| 554 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 555 | } | ||
| 556 | |||
| 557 | diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c | ||
| 558 | index 6c49c1601..ae447a8bc 100644 | ||
| 559 | --- a/hw/usb/dev-network.c | ||
| 560 | +++ b/hw/usb/dev-network.c | ||
| 561 | @@ -1362,7 +1362,8 @@ static void usb_net_realize(USBDevice *dev, Error **errp) | ||
| 562 | |||
| 563 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
| 564 | s->nic = qemu_new_nic(&net_usbnet_info, &s->conf, | ||
| 565 | - object_get_typename(OBJECT(s)), s->dev.qdev.id, s); | ||
| 566 | + object_get_typename(OBJECT(s)), s->dev.qdev.id, | ||
| 567 | + &s->dev.qdev.mem_reentrancy_guard, s); | ||
| 568 | qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); | ||
| 569 | snprintf(s->usbstring_mac, sizeof(s->usbstring_mac), | ||
| 570 | "%02x%02x%02x%02x%02x%02x", | ||
| 571 | diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h | ||
| 572 | index 20d306659..77c0455d8 100644 | ||
| 573 | --- a/include/hw/qdev-core.h | ||
| 574 | +++ b/include/hw/qdev-core.h | ||
| 575 | @@ -162,6 +162,10 @@ struct NamedClockList { | ||
| 576 | QLIST_ENTRY(NamedClockList) node; | ||
| 577 | }; | ||
| 578 | |||
| 579 | +typedef struct { | ||
| 580 | + bool engaged_in_io; | ||
| 581 | +} MemReentrancyGuard; | ||
| 582 | + | ||
| 583 | /** | ||
| 584 | * DeviceState: | ||
| 585 | * @realized: Indicates whether the device has been fully constructed. | ||
| 586 | @@ -193,6 +197,9 @@ struct DeviceState { | ||
| 587 | int instance_id_alias; | ||
| 588 | int alias_required_for_version; | ||
| 589 | ResettableState reset; | ||
| 590 | + | ||
| 591 | + /* Is the device currently in mmio/pio/dma? Used to prevent re-entrancy */ | ||
| 592 | + MemReentrancyGuard mem_reentrancy_guard; | ||
| 593 | }; | ||
| 594 | |||
| 595 | struct DeviceListener { | ||
| 596 | diff --git a/include/net/net.h b/include/net/net.h | ||
| 597 | index 523136c7a..1457b6c01 100644 | ||
| 598 | --- a/include/net/net.h | ||
| 599 | +++ b/include/net/net.h | ||
| 600 | @@ -145,6 +145,7 @@ NICState *qemu_new_nic(NetClientInfo *info, | ||
| 601 | NICConf *conf, | ||
| 602 | const char *model, | ||
| 603 | const char *name, | ||
| 604 | + MemReentrancyGuard *reentrancy_guard, | ||
| 605 | void *opaque); | ||
| 606 | void qemu_del_nic(NICState *nic); | ||
| 607 | NetClientState *qemu_get_subqueue(NICState *nic, int queue_index); | ||
| 608 | diff --git a/net/net.c b/net/net.c | ||
| 609 | index f0d14dbfc..669e194c4 100644 | ||
| 610 | --- a/net/net.c | ||
| 611 | +++ b/net/net.c | ||
| 612 | @@ -299,6 +299,7 @@ NICState *qemu_new_nic(NetClientInfo *info, | ||
| 613 | NICConf *conf, | ||
| 614 | const char *model, | ||
| 615 | const char *name, | ||
| 616 | + MemReentrancyGuard *reentrancy_guard, | ||
| 617 | void *opaque) | ||
| 618 | { | ||
| 619 | NetClientState **peers = conf->peers.ncs; | ||
| 620 | -- | ||
| 621 | 2.40.0 | ||
| 622 | |||
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2023-3019-0002.patch b/meta/recipes-devtools/qemu/qemu/CVE-2023-3019-0002.patch new file mode 100644 index 0000000000..0f1d201c31 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2023-3019-0002.patch | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | From 3c0463a650008aec7de29cf84540652730510921 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
| 3 | Date: Thu, 1 Jun 2023 12:18:59 +0900 | ||
| 4 | Subject: [PATCH] net: Update MemReentrancyGuard for NIC | ||
| 5 | |||
| 6 | Recently MemReentrancyGuard was added to DeviceState to record that the | ||
| 7 | device is engaging in I/O. The network device backend needs to update it | ||
| 8 | when delivering a packet to a device. | ||
| 9 | |||
| 10 | This implementation follows what bottom half does, but it does not add | ||
| 11 | a tracepoint for the case that the network device backend started | ||
| 12 | delivering a packet to a device which is already engaging in I/O. This | ||
| 13 | is because such reentrancy frequently happens for | ||
| 14 | qemu_flush_queued_packets() and is insignificant. | ||
| 15 | |||
| 16 | Fixes: CVE-2023-3019 | ||
| 17 | Reported-by: Alexander Bulekov <alxndr@bu.edu> | ||
| 18 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
| 19 | Acked-by: Alexander Bulekov <alxndr@bu.edu> | ||
| 20 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
| 21 | (cherry picked from commit 9050f976e447444ea6ee2ba12c9f77e4b0dc54bc) | ||
| 22 | Signed-off-by: Michael Tokarev <mjt@tls.msk.ru> | ||
| 23 | |||
| 24 | CVE: CVE-2023-3019 | ||
| 25 | Upstream-Status: Backport [https://github.com/qemu/qemu/commit/3c0463a650008aec7de29cf84540652730510921] | ||
| 26 | |||
| 27 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
| 28 | --- | ||
| 29 | include/net/net.h | 1 + | ||
| 30 | net/net.c | 14 ++++++++++++++ | ||
| 31 | 2 files changed, 15 insertions(+) | ||
| 32 | |||
| 33 | diff --git a/include/net/net.h b/include/net/net.h | ||
| 34 | index 1457b6c01..11d4564ea 100644 | ||
| 35 | --- a/include/net/net.h | ||
| 36 | +++ b/include/net/net.h | ||
| 37 | @@ -112,6 +112,7 @@ struct NetClientState { | ||
| 38 | typedef struct NICState { | ||
| 39 | NetClientState *ncs; | ||
| 40 | NICConf *conf; | ||
| 41 | + MemReentrancyGuard *reentrancy_guard; | ||
| 42 | void *opaque; | ||
| 43 | bool peer_deleted; | ||
| 44 | } NICState; | ||
| 45 | diff --git a/net/net.c b/net/net.c | ||
| 46 | index 669e194c4..b3008a52b 100644 | ||
| 47 | --- a/net/net.c | ||
| 48 | +++ b/net/net.c | ||
| 49 | @@ -312,6 +312,7 @@ NICState *qemu_new_nic(NetClientInfo *info, | ||
| 50 | nic = g_malloc0(info->size + sizeof(NetClientState) * queues); | ||
| 51 | nic->ncs = (void *)nic + info->size; | ||
| 52 | nic->conf = conf; | ||
| 53 | + nic->reentrancy_guard = reentrancy_guard, | ||
| 54 | nic->opaque = opaque; | ||
| 55 | |||
| 56 | for (i = 0; i < queues; i++) { | ||
| 57 | @@ -767,6 +768,7 @@ static ssize_t qemu_deliver_packet_iov(NetClientState *sender, | ||
| 58 | int iovcnt, | ||
| 59 | void *opaque) | ||
| 60 | { | ||
| 61 | + MemReentrancyGuard *owned_reentrancy_guard; | ||
| 62 | NetClientState *nc = opaque; | ||
| 63 | int ret; | ||
| 64 | |||
| 65 | @@ -779,12 +781,24 @@ static ssize_t qemu_deliver_packet_iov(NetClientState *sender, | ||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | + if (nc->info->type != NET_CLIENT_DRIVER_NIC || | ||
| 70 | + qemu_get_nic(nc)->reentrancy_guard->engaged_in_io) { | ||
| 71 | + owned_reentrancy_guard = NULL; | ||
| 72 | + } else { | ||
| 73 | + owned_reentrancy_guard = qemu_get_nic(nc)->reentrancy_guard; | ||
| 74 | + owned_reentrancy_guard->engaged_in_io = true; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | if (nc->info->receive_iov && !(flags & QEMU_NET_PACKET_FLAG_RAW)) { | ||
| 78 | ret = nc->info->receive_iov(nc, iov, iovcnt); | ||
| 79 | } else { | ||
| 80 | ret = nc_sendv_compat(nc, iov, iovcnt, flags); | ||
| 81 | } | ||
| 82 | |||
| 83 | + if (owned_reentrancy_guard) { | ||
| 84 | + owned_reentrancy_guard->engaged_in_io = false; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | if (ret == 0) { | ||
| 88 | nc->receive_disabled = 1; | ||
| 89 | } | ||
| 90 | -- | ||
| 91 | 2.40.0 | ||
