From: Divya Chellam <[email protected]>

A double free vulnerability was found in QEMU virtio devices
(virtio-gpu, virtio-serial-bus, virtio-crypto), where the
mem_reentrancy_guard flag insufficiently protects against DMA
reentrancy issues. This issue could allow a malicious privileged
guest to crash the QEMU process on the host, resulting in a d
enial of service or allow arbitrary code execution within the
context of the QEMU process on the host.

CVE-2024-3446-0004, CVE-2024-3446-0005, CVE-2024-3446-0006
are CVE fix and CVE-2024-3446-0001, CVE-2024-3446-0002,
CVE-2024-3446-0003 are dependent commits to fix the CVE.

References:
https://nvd.nist.gov/vuln/detail/CVE-2024-3446

Upstream patches:
https://gitlab.com/qemu-project/qemu/-/commit/9c86c97f12c060bf7484dd931f38634e166a81f0
https://gitlab.com/qemu-project/qemu/-/commit/f63192b0544af5d3e4d5edfd85ab520fcf671377
https://gitlab.com/qemu-project/qemu/-/commit/ec0504b989ca61e03636384d3602b7bf07ffe4da
https://gitlab.com/qemu-project/qemu/-/commit/ba28e0ff4d95b56dc334aac2730ab3651ffc3132
https://gitlab.com/qemu-project/qemu/-/commit/b4295bff25f7b50de1d9cc94a9c6effd40056bca
https://gitlab.com/qemu-project/qemu/-/commit/f4729ec39ad97a42ceaa7b5697f84f440ea6e5dc

Signed-off-by: Yogita Urade <[email protected]>
Signed-off-by: Steve Sakoman <[email protected]>
---
 meta/recipes-devtools/qemu/qemu.inc           |   6 +
 .../qemu/qemu/CVE-2024-3446-0001.patch        | 218 +++++++++
 .../qemu/qemu/CVE-2024-3446-0002.patch        | 427 ++++++++++++++++++
 .../qemu/qemu/CVE-2024-3446-0003.patch        |  68 +++
 .../qemu/qemu/CVE-2024-3446-0004.patch        | 144 ++++++
 .../qemu/qemu/CVE-2024-3446-0005.patch        |  42 ++
 .../qemu/qemu/CVE-2024-3446-0006.patch        |  43 ++
 7 files changed, 948 insertions(+)
 create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0001.patch
 create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0002.patch
 create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0003.patch
 create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0004.patch
 create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0005.patch
 create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0006.patch

diff --git a/meta/recipes-devtools/qemu/qemu.inc 
b/meta/recipes-devtools/qemu/qemu.inc
index a43785c79d..16eb30e572 100644
--- a/meta/recipes-devtools/qemu/qemu.inc
+++ b/meta/recipes-devtools/qemu/qemu.inc
@@ -121,6 +121,12 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
            file://CVE-2023-3019-0001.patch \
            file://CVE-2023-3019-0002.patch \
            file://CVE-2024-6505.patch \
+           file://CVE-2024-3446-0001.patch \
+           file://CVE-2024-3446-0002.patch \
+           file://CVE-2024-3446-0003.patch \
+           file://CVE-2024-3446-0004.patch \
+           file://CVE-2024-3446-0005.patch \
+           file://CVE-2024-3446-0006.patch \
            "
 UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
 
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0001.patch 
b/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0001.patch
new file mode 100644
index 0000000000..f33934bf85
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0001.patch
@@ -0,0 +1,218 @@
+From 9c86c97f12c060bf7484dd931f38634e166a81f0 Mon Sep 17 00:00:00 2001
+From: Alexander Bulekov <[email protected]>
+Date: Mon, 27 May 2024 07:29:20 +0000
+Subject: [PATCH] async: Add an optional reentrancy guard to the BH API
+
+Devices can pass their MemoryReentrancyGuard (from their DeviceState),
+when creating new BHes. Then, the async API will toggle the guard
+before/after calling the BH call-back. This prevents bh->mmio reentrancy
+issues.
+
+Signed-off-by: Alexander Bulekov <[email protected]>
+Reviewed-by: Darren Kenny <[email protected]>
+Message-Id: <[email protected]>
+[thuth: Fix "line over 90 characters" checkpatch.pl error]
+Signed-off-by: Thomas Huth <[email protected]>
+
+CVE: CVE-2024-3446
+Upstream-Status: Backport 
[https://gitlab.com/qemu-project/qemu/-/commit/9c86c97f12c060bf7484dd931f38634e166a81f0]
+
+Signed-off-by: Yogita Urade <[email protected]>
+---
+ docs/devel/multiple-iothreads.txt |  7 +++++++
+ include/block/aio.h               | 18 ++++++++++++++++--
+ include/qemu/main-loop.h          |  8 +++++---
+ tests/unit/ptimer-test-stubs.c    |  3 ++-
+ util/async.c                      | 18 +++++++++++++++++-
+ util/main-loop.c                  |  6 ++++--
+ util/trace-events                 |  1 +
+ 7 files changed, 52 insertions(+), 9 deletions(-)
+
+diff --git a/docs/devel/multiple-iothreads.txt 
b/docs/devel/multiple-iothreads.txt
+index aeb997bed..a11576bc7 100644
+--- a/docs/devel/multiple-iothreads.txt
++++ b/docs/devel/multiple-iothreads.txt
+@@ -61,6 +61,7 @@ There are several old APIs that use the main loop AioContext:
+  * LEGACY qemu_aio_set_event_notifier() - monitor an event notifier
+  * LEGACY timer_new_ms() - create a timer
+  * LEGACY qemu_bh_new() - create a BH
++ * LEGACY qemu_bh_new_guarded() - create a BH with a device re-entrancy guard
+  * LEGACY qemu_aio_wait() - run an event loop iteration
+
+ Since they implicitly work on the main loop they cannot be used in code that
+@@ -72,8 +73,14 @@ Instead, use the AioContext functions directly (see 
include/block/aio.h):
+  * aio_set_event_notifier() - monitor an event notifier
+  * aio_timer_new() - create a timer
+  * aio_bh_new() - create a BH
++ * aio_bh_new_guarded() - create a BH with a device re-entrancy guard
+  * aio_poll() - run an event loop iteration
+
++The qemu_bh_new_guarded/aio_bh_new_guarded APIs accept a "MemReentrancyGuard"
++argument, which is used to check for and prevent re-entrancy problems. For
++BHs associated with devices, the reentrancy-guard is contained in the
++corresponding DeviceState and named "mem_reentrancy_guard".
++
+ The AioContext can be obtained from the IOThread using
+ iothread_get_aio_context() or for the main loop using qemu_get_aio_context().
+ Code that takes an AioContext argument works both in IOThreads or the main
+diff --git a/include/block/aio.h b/include/block/aio.h
+index 47fbe9d81..c7da15298 100644
+--- a/include/block/aio.h
++++ b/include/block/aio.h
+@@ -22,6 +22,8 @@
+ #include "qemu/event_notifier.h"
+ #include "qemu/thread.h"
+ #include "qemu/timer.h"
++#include "hw/qdev-core.h"
++
+
+ typedef struct BlockAIOCB BlockAIOCB;
+ typedef void BlockCompletionFunc(void *opaque, int ret);
+@@ -321,9 +323,11 @@ void aio_bh_schedule_oneshot_full(AioContext *ctx, 
QEMUBHFunc *cb, void *opaque,
+  * is opaque and must be allocated prior to its use.
+  *
+  * @name: A human-readable identifier for debugging purposes.
++ * @reentrancy_guard: A guard set when entering a cb to prevent
++ * device-reentrancy issues
+  */
+ QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque,
+-                        const char *name);
++                        const char *name, MemReentrancyGuard 
*reentrancy_guard);
+
+ /**
+  * aio_bh_new: Allocate a new bottom half structure
+@@ -332,7 +336,17 @@ QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, 
void *opaque,
+  * string.
+  */
+ #define aio_bh_new(ctx, cb, opaque) \
+-    aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb)))
++    aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb)), NULL)
++
++/**
++ * aio_bh_new_guarded: Allocate a new bottom half structure with a
++ * reentrancy_guard
++ *
++ * A convenience wrapper for aio_bh_new_full() that uses the cb as the name
++ * string.
++ */
++#define aio_bh_new_guarded(ctx, cb, opaque, guard) \
++    aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb)), guard)
+
+ /**
+  * aio_notify: Force processing of pending events.
+diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
+index 8dbc6fcb8..0a8f512be 100644
+--- a/include/qemu/main-loop.h
++++ b/include/qemu/main-loop.h
+@@ -293,10 +293,12 @@ void qemu_cond_timedwait_iothread(QemuCond *cond, int 
ms);
+ /* internal interfaces */
+
+ void qemu_fd_register(int fd);
+-
++#define qemu_bh_new_guarded(cb, opaque, guard) \
++    qemu_bh_new_full((cb), (opaque), (stringify(cb)), guard)
+ #define qemu_bh_new(cb, opaque) \
+-    qemu_bh_new_full((cb), (opaque), (stringify(cb)))
+-QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name);
++    qemu_bh_new_full((cb), (opaque), (stringify(cb)), NULL)
++QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name,
++                         MemReentrancyGuard *reentrancy_guard);
+ void qemu_bh_schedule_idle(QEMUBH *bh);
+
+ enum {
+diff --git a/tests/unit/ptimer-test-stubs.c b/tests/unit/ptimer-test-stubs.c
+index 2a3ef5879..a7a2d08e7 100644
+--- a/tests/unit/ptimer-test-stubs.c
++++ b/tests/unit/ptimer-test-stubs.c
+@@ -108,7 +108,8 @@ int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int 
attr_mask)
+     return deadline;
+ }
+
+-QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name)
++QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name,
++                         MemReentrancyGuard *reentrancy_guard)
+ {
+     QEMUBH *bh = g_new(QEMUBH, 1);
+
+diff --git a/util/async.c b/util/async.c
+index 6f6717a34..3eb6b5016 100644
+--- a/util/async.c
++++ b/util/async.c
+@@ -62,6 +62,7 @@ struct QEMUBH {
+     void *opaque;
+     QSLIST_ENTRY(QEMUBH) next;
+     unsigned flags;
++    MemReentrancyGuard *reentrancy_guard;
+ };
+
+ /* Called concurrently from any thread */
+@@ -123,7 +124,7 @@ void aio_bh_schedule_oneshot_full(AioContext *ctx, 
QEMUBHFunc *cb,
+ }
+
+ QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque,
+-                        const char *name)
++                        const char *name, MemReentrancyGuard 
*reentrancy_guard)
+ {
+     QEMUBH *bh;
+     bh = g_new(QEMUBH, 1);
+@@ -132,13 +133,28 @@ QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, 
void *opaque,
+         .cb = cb,
+         .opaque = opaque,
+         .name = name,
++        .reentrancy_guard = reentrancy_guard,
+     };
+     return bh;
+ }
+
+ void aio_bh_call(QEMUBH *bh)
+ {
++    bool last_engaged_in_io = false;
++
++    if (bh->reentrancy_guard) {
++        last_engaged_in_io = bh->reentrancy_guard->engaged_in_io;
++        if (bh->reentrancy_guard->engaged_in_io) {
++            trace_reentrant_aio(bh->ctx, bh->name);
++        }
++        bh->reentrancy_guard->engaged_in_io = true;
++    }
++
+     bh->cb(bh->opaque);
++
++    if (bh->reentrancy_guard) {
++        bh->reentrancy_guard->engaged_in_io = last_engaged_in_io;
++    }
+ }
+
+ /* Multiple occurrences of aio_bh_poll cannot be called concurrently. */
+diff --git a/util/main-loop.c b/util/main-loop.c
+index 06b18b195..1eacf0469 100644
+--- a/util/main-loop.c
++++ b/util/main-loop.c
+@@ -544,9 +544,11 @@ void main_loop_wait(int nonblocking)
+
+ /* Functions to operate on the main QEMU AioContext.  */
+
+-QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name)
++QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name,
++                         MemReentrancyGuard *reentrancy_guard)
+ {
+-    return aio_bh_new_full(qemu_aio_context, cb, opaque, name);
++    return aio_bh_new_full(qemu_aio_context, cb, opaque, name,
++                           reentrancy_guard);
+ }
+
+ /*
+diff --git a/util/trace-events b/util/trace-events
+index c8f53d7d9..dc3b1eb3b 100644
+--- a/util/trace-events
++++ b/util/trace-events
+@@ -11,6 +11,7 @@ poll_remove(void *ctx, void *node, int fd) "ctx %p node %p 
fd %d"
+ # async.c
+ aio_co_schedule(void *ctx, void *co) "ctx %p co %p"
+ aio_co_schedule_bh_cb(void *ctx, void *co) "ctx %p co %p"
++reentrant_aio(void *ctx, const char *name) "ctx %p name %s"
+
+ # thread-pool.c
+ thread_pool_submit(void *pool, void *req, void *opaque) "pool %p req %p 
opaque %p"
+--
+2.40.0
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0002.patch 
b/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0002.patch
new file mode 100644
index 0000000000..68a6e737da
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0002.patch
@@ -0,0 +1,427 @@
+From f63192b0544af5d3e4d5edfd85ab520fcf671377 Mon Sep 17 00:00:00 2001
+From: Alexander Bulekov <[email protected]>
+Date: Thu, 27 Apr 2023 17:10:09 -0400
+Subject: [PATCH] hw: replace most qemu_bh_new calls with qemu_bh_new_guarded
+
+This protects devices from bh->mmio reentrancy issues.
+
+Thanks: Thomas Huth <[email protected]> for diagnosing OS X test failure.
+Signed-off-by: Alexander Bulekov <[email protected]>
+Reviewed-by: Darren Kenny <[email protected]>
+Reviewed-by: Stefan Hajnoczi <[email protected]>
+Reviewed-by: Michael S. Tsirkin <[email protected]>
+Reviewed-by: Paul Durrant <[email protected]>
+Reviewed-by: Thomas Huth <[email protected]>
+Message-Id: <[email protected]>
+Signed-off-by: Thomas Huth <[email protected]>
+
+CVE: CVE-2024-3446
+Upstream-Status: Backport 
[https://gitlab.com/qemu-project/qemu/-/commit/f63192b0544af5d3e4d5edfd85ab520fcf671377]
+
+Signed-off-by: Yogita Urade <[email protected]>
+---
+ hw/9pfs/xen-9p-backend.c        | 5 ++++-
+ hw/block/dataplane/virtio-blk.c | 3 ++-
+ hw/block/dataplane/xen-block.c  | 5 +++--
+ hw/char/virtio-serial-bus.c     | 3 ++-
+ hw/display/qxl.c                | 9 ++++++---
+ hw/display/virtio-gpu.c         | 6 ++++--
+ hw/ide/ahci.c                   | 3 ++-
+ hw/ide/ahci_internal.h          | 1 +
+ hw/ide/core.c                   | 4 +++-
+ hw/misc/imx_rngc.c              | 6 ++++--
+ hw/misc/macio/mac_dbdma.c       | 2 +-
+ hw/net/virtio-net.c             | 3 ++-
+ hw/scsi/mptsas.c                | 3 ++-
+ hw/scsi/scsi-bus.c              | 3 ++-
+ hw/scsi/vmw_pvscsi.c            | 3 ++-
+ hw/usb/dev-uas.c                | 3 ++-
+ hw/usb/hcd-dwc2.c               | 3 ++-
+ hw/usb/hcd-ehci.c               | 3 ++-
+ hw/usb/hcd-uhci.c               | 2 +-
+ hw/usb/host-libusb.c            | 6 ++++--
+ hw/usb/redirect.c               | 6 ++++--
+ hw/usb/xen-usb.c                | 3 ++-
+ hw/virtio/virtio-balloon.c      | 5 +++--
+ hw/virtio/virtio-crypto.c       | 3 ++-
+ 24 files changed, 62 insertions(+), 31 deletions(-)
+
+diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c
+index 65c4979c3..09f7c1358 100644
+--- a/hw/9pfs/xen-9p-backend.c
++++ b/hw/9pfs/xen-9p-backend.c
+@@ -60,6 +60,7 @@ typedef struct Xen9pfsDev {
+
+     int num_rings;
+     Xen9pfsRing *rings;
++    MemReentrancyGuard mem_reentrancy_guard;
+ } Xen9pfsDev;
+
+ static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev);
+@@ -441,7 +442,9 @@ static int xen_9pfs_connect(struct XenLegacyDevice *xendev)
+         xen_9pdev->rings[i].ring.out = xen_9pdev->rings[i].data +
+                                        XEN_FLEX_RING_SIZE(ring_order);
+
+-        xen_9pdev->rings[i].bh = qemu_bh_new(xen_9pfs_bh, 
&xen_9pdev->rings[i]);
++        xen_9pdev->rings[i].bh = qemu_bh_new_guarded(xen_9pfs_bh,
++                                                     &xen_9pdev->rings[i],
++                                                     
&xen_9pdev->mem_reentrancy_guard);
+         xen_9pdev->rings[i].out_cons = 0;
+         xen_9pdev->rings[i].out_size = 0;
+         xen_9pdev->rings[i].inprogress = false;
+diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
+index ee5a5352d..5f0de7da1 100644
+--- a/hw/block/dataplane/virtio-blk.c
++++ b/hw/block/dataplane/virtio-blk.c
+@@ -127,7 +127,8 @@ bool virtio_blk_data_plane_create(VirtIODevice *vdev, 
VirtIOBlkConf *conf,
+     } else {
+         s->ctx = qemu_get_aio_context();
+     }
+-    s->bh = aio_bh_new(s->ctx, notify_guest_bh, s);
++    s->bh = aio_bh_new_guarded(s->ctx, notify_guest_bh, s,
++                               &DEVICE(vdev)->mem_reentrancy_guard);
+     s->batch_notify_vqs = bitmap_new(conf->num_queues);
+
+     *dataplane = s;
+diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c
+index 860787580..07855feea 100644
+--- a/hw/block/dataplane/xen-block.c
++++ b/hw/block/dataplane/xen-block.c
+@@ -631,8 +631,9 @@ XenBlockDataPlane *xen_block_dataplane_create(XenDevice 
*xendev,
+     } else {
+         dataplane->ctx = qemu_get_aio_context();
+     }
+-    dataplane->bh = aio_bh_new(dataplane->ctx, xen_block_dataplane_bh,
+-                               dataplane);
++    dataplane->bh = aio_bh_new_guarded(dataplane->ctx, xen_block_dataplane_bh,
++                                       dataplane,
++                                       &DEVICE(xendev)->mem_reentrancy_guard);
+
+     return dataplane;
+ }
+diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
+index f01ec2137..f18124b15 100644
+--- a/hw/char/virtio-serial-bus.c
++++ b/hw/char/virtio-serial-bus.c
+@@ -985,7 +985,8 @@ static void virtser_port_device_realize(DeviceState *dev, 
Error **errp)
+         return;
+     }
+
+-    port->bh = qemu_bh_new(flush_queued_data_bh, port);
++    port->bh = qemu_bh_new_guarded(flush_queued_data_bh, port,
++                                   &dev->mem_reentrancy_guard);
+     port->elem = NULL;
+ }
+
+diff --git a/hw/display/qxl.c b/hw/display/qxl.c
+index 2a4b2d415..585254fc7 100644
+--- a/hw/display/qxl.c
++++ b/hw/display/qxl.c
+@@ -2205,11 +2205,14 @@ static void qxl_realize_common(PCIQXLDevice *qxl, 
Error **errp)
+
+     qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl);
+
+-    qxl->update_irq = qemu_bh_new(qxl_update_irq_bh, qxl);
++    qxl->update_irq = qemu_bh_new_guarded(qxl_update_irq_bh, qxl,
++                                          &DEVICE(qxl)->mem_reentrancy_guard);
+     qxl_reset_state(qxl);
+
+-    qxl->update_area_bh = qemu_bh_new(qxl_render_update_area_bh, qxl);
+-    qxl->ssd.cursor_bh = qemu_bh_new(qemu_spice_cursor_refresh_bh, &qxl->ssd);
++    qxl->update_area_bh = qemu_bh_new_guarded(qxl_render_update_area_bh, qxl,
++                                              
&DEVICE(qxl)->mem_reentrancy_guard);
++    qxl->ssd.cursor_bh = qemu_bh_new_guarded(qemu_spice_cursor_refresh_bh, 
&qxl->ssd,
++                                             
&DEVICE(qxl)->mem_reentrancy_guard);
+ }
+
+ static void qxl_realize_primary(PCIDevice *dev, Error **errp)
+diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
+index c6dc81898..316469ab7 100644
+--- a/hw/display/virtio-gpu.c
++++ b/hw/display/virtio-gpu.c
+@@ -1334,8 +1334,10 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error 
**errp)
+
+     g->ctrl_vq = virtio_get_queue(vdev, 0);
+     g->cursor_vq = virtio_get_queue(vdev, 1);
+-    g->ctrl_bh = qemu_bh_new(virtio_gpu_ctrl_bh, g);
+-    g->cursor_bh = qemu_bh_new(virtio_gpu_cursor_bh, g);
++    g->ctrl_bh = qemu_bh_new_guarded(virtio_gpu_ctrl_bh, g,
++                                     &qdev->mem_reentrancy_guard);
++    g->cursor_bh = qemu_bh_new_guarded(virtio_gpu_cursor_bh, g,
++                                       &qdev->mem_reentrancy_guard);
+     QTAILQ_INIT(&g->reslist);
+     QTAILQ_INIT(&g->cmdq);
+     QTAILQ_INIT(&g->fenceq);
+diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
+index 205dfdc66..f77d0faf0 100644
+--- a/hw/ide/ahci.c
++++ b/hw/ide/ahci.c
+@@ -1508,7 +1508,8 @@ static void ahci_cmd_done(const IDEDMA *dma)
+     ahci_write_fis_d2h(ad);
+
+     if (ad->port_regs.cmd_issue && !ad->check_bh) {
+-        ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
++        ad->check_bh = qemu_bh_new_guarded(ahci_check_cmd_bh, ad,
++                                           &ad->mem_reentrancy_guard);
+         qemu_bh_schedule(ad->check_bh);
+     }
+ }
+diff --git a/hw/ide/ahci_internal.h b/hw/ide/ahci_internal.h
+index 109de9e2d..a7768dd69 100644
+--- a/hw/ide/ahci_internal.h
++++ b/hw/ide/ahci_internal.h
+@@ -321,6 +321,7 @@ struct AHCIDevice {
+     bool init_d2h_sent;
+     AHCICmdHdr *cur_cmd;
+     NCQTransferState ncq_tfs[AHCI_MAX_CMDS];
++    MemReentrancyGuard mem_reentrancy_guard;
+ };
+
+ struct AHCIPCIState {
+diff --git a/hw/ide/core.c b/hw/ide/core.c
+index 63998410a..0416f45a6 100644
+--- a/hw/ide/core.c
++++ b/hw/ide/core.c
+@@ -506,11 +506,13 @@ BlockAIOCB *ide_issue_trim(
+         BlockCompletionFunc *cb, void *cb_opaque, void *opaque)
+ {
+     IDEState *s = opaque;
++    IDEDevice *dev = s->unit ? s->bus->slave : s->bus->master;
+     TrimAIOCB *iocb;
+
+     iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque);
+     iocb->s = s;
+-    iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
++    iocb->bh = qemu_bh_new_guarded(ide_trim_bh_cb, iocb,
++                                   &DEVICE(dev)->mem_reentrancy_guard);
+     iocb->ret = 0;
+     iocb->qiov = qiov;
+     iocb->i = -1;
+diff --git a/hw/misc/imx_rngc.c b/hw/misc/imx_rngc.c
+index 632c03779..082c6980a 100644
+--- a/hw/misc/imx_rngc.c
++++ b/hw/misc/imx_rngc.c
+@@ -228,8 +228,10 @@ static void imx_rngc_realize(DeviceState *dev, Error 
**errp)
+     sysbus_init_mmio(sbd, &s->iomem);
+
+     sysbus_init_irq(sbd, &s->irq);
+-    s->self_test_bh = qemu_bh_new(imx_rngc_self_test, s);
+-    s->seed_bh = qemu_bh_new(imx_rngc_seed, s);
++    s->self_test_bh = qemu_bh_new_guarded(imx_rngc_self_test, s,
++                                          &dev->mem_reentrancy_guard);
++    s->seed_bh = qemu_bh_new_guarded(imx_rngc_seed, s,
++                                     &dev->mem_reentrancy_guard);
+ }
+
+ static void imx_rngc_reset(DeviceState *dev)
+diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c
+index efcc02609..cc7e02203 100644
+--- a/hw/misc/macio/mac_dbdma.c
++++ b/hw/misc/macio/mac_dbdma.c
+@@ -914,7 +914,7 @@ static void mac_dbdma_realize(DeviceState *dev, Error 
**errp)
+ {
+     DBDMAState *s = MAC_DBDMA(dev);
+
+-    s->bh = qemu_bh_new(DBDMA_run_bh, s);
++    s->bh = qemu_bh_new_guarded(DBDMA_run_bh, s, &dev->mem_reentrancy_guard);
+ }
+
+ static void mac_dbdma_class_init(ObjectClass *oc, void *data)
+diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
+index 9127d03db..a1d65b2f2 100644
+--- a/hw/net/virtio-net.c
++++ b/hw/net/virtio-net.c
+@@ -2744,7 +2744,8 @@ static void virtio_net_add_queue(VirtIONet *n, int index)
+         n->vqs[index].tx_vq =
+             virtio_add_queue(vdev, n->net_conf.tx_queue_size,
+                              virtio_net_handle_tx_bh);
+-        n->vqs[index].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[index]);
++        n->vqs[index].tx_bh = qemu_bh_new_guarded(virtio_net_tx_bh, 
&n->vqs[index],
++                                                  
&DEVICE(vdev)->mem_reentrancy_guard);
+     }
+
+     n->vqs[index].tx_waiting = 0;
+diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
+index 5181b0c0b..8487138cb 100644
+--- a/hw/scsi/mptsas.c
++++ b/hw/scsi/mptsas.c
+@@ -1321,7 +1321,8 @@ static void mptsas_scsi_realize(PCIDevice *dev, Error 
**errp)
+     }
+     s->max_devices = MPTSAS_NUM_PORTS;
+
+-    s->request_bh = qemu_bh_new(mptsas_fetch_requests, s);
++    s->request_bh = qemu_bh_new_guarded(mptsas_fetch_requests, s,
++                                        &DEVICE(dev)->mem_reentrancy_guard);
+
+     scsi_bus_init(&s->bus, sizeof(s->bus), &dev->qdev, &mptsas_scsi_info);
+ }
+diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
+index 2b5e9dca3..54b9a8ce9 100644
+--- a/hw/scsi/scsi-bus.c
++++ b/hw/scsi/scsi-bus.c
+@@ -192,7 +192,8 @@ static void scsi_dma_restart_cb(void *opaque, bool 
running, RunState state)
+         AioContext *ctx = blk_get_aio_context(s->conf.blk);
+         /* The reference is dropped in scsi_dma_restart_bh.*/
+         object_ref(OBJECT(s));
+-        s->bh = aio_bh_new(ctx, scsi_dma_restart_bh, s);
++        s->bh = aio_bh_new_guarded(ctx, scsi_dma_restart_bh, s,
++                                   &DEVICE(s)->mem_reentrancy_guard);
+         qemu_bh_schedule(s->bh);
+     }
+ }
+diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
+index 4d9969f3b..d5c6293a2 100644
+--- a/hw/scsi/vmw_pvscsi.c
++++ b/hw/scsi/vmw_pvscsi.c
+@@ -1184,7 +1184,8 @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp)
+         pcie_endpoint_cap_init(pci_dev, PVSCSI_EXP_EP_OFFSET);
+     }
+
+-    s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s);
++    s->completion_worker = 
qemu_bh_new_guarded(pvscsi_process_completion_queue, s,
++                                               
&DEVICE(pci_dev)->mem_reentrancy_guard);
+
+     scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(pci_dev), 
&pvscsi_scsi_info);
+     /* override default SCSI bus hotplug-handler, with pvscsi's one */
+diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
+index 599d6b52a..a36a7c301 100644
+--- a/hw/usb/dev-uas.c
++++ b/hw/usb/dev-uas.c
+@@ -935,7 +935,8 @@ static void usb_uas_realize(USBDevice *dev, Error **errp)
+
+     QTAILQ_INIT(&uas->results);
+     QTAILQ_INIT(&uas->requests);
+-    uas->status_bh = qemu_bh_new(usb_uas_send_status_bh, uas);
++    uas->status_bh = qemu_bh_new_guarded(usb_uas_send_status_bh, uas,
++                                         &d->mem_reentrancy_guard);
+
+     dev->flags |= (1 << USB_DEV_FLAG_IS_SCSI_STORAGE);
+     scsi_bus_init(&uas->bus, sizeof(uas->bus), DEVICE(dev), 
&usb_uas_scsi_info);
+diff --git a/hw/usb/hcd-dwc2.c b/hw/usb/hcd-dwc2.c
+index 8755e9cbb..a0c4e782b 100644
+--- a/hw/usb/hcd-dwc2.c
++++ b/hw/usb/hcd-dwc2.c
+@@ -1364,7 +1364,8 @@ static void dwc2_realize(DeviceState *dev, Error **errp)
+     s->fi = USB_FRMINTVL - 1;
+     s->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_frame_boundary, s);
+     s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_work_timer, s);
+-    s->async_bh = qemu_bh_new(dwc2_work_bh, s);
++    s->async_bh = qemu_bh_new_guarded(dwc2_work_bh, s,
++                                      &dev->mem_reentrancy_guard);
+
+     sysbus_init_irq(sbd, &s->irq);
+ }
+diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
+index 33a8a377b..7b0538810 100644
+--- a/hw/usb/hcd-ehci.c
++++ b/hw/usb/hcd-ehci.c
+@@ -2530,7 +2530,8 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, 
Error **errp)
+     }
+
+     s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ehci_work_timer, s);
+-    s->async_bh = qemu_bh_new(ehci_work_bh, s);
++    s->async_bh = qemu_bh_new_guarded(ehci_work_bh, s,
++                                      &dev->mem_reentrancy_guard);
+     s->device = dev;
+
+     s->vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, 
s);
+diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
+index d1b5657d7..ef967c42a 100644
+--- a/hw/usb/hcd-uhci.c
++++ b/hw/usb/hcd-uhci.c
+@@ -1193,7 +1193,7 @@ void usb_uhci_common_realize(PCIDevice *dev, Error 
**errp)
+                               USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
+         }
+     }
+-    s->bh = qemu_bh_new(uhci_bh, s);
++    s->bh = qemu_bh_new_guarded(uhci_bh, s, 
&DEVICE(dev)->mem_reentrancy_guard);
+     s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, uhci_frame_timer, s);
+     s->num_ports_vmstate = NB_PORTS;
+     QTAILQ_INIT(&s->queues);
+diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
+index d0d46dd0a..09b961116 100644
+--- a/hw/usb/host-libusb.c
++++ b/hw/usb/host-libusb.c
+@@ -1141,7 +1141,8 @@ static void usb_host_nodev_bh(void *opaque)
+ static void usb_host_nodev(USBHostDevice *s)
+ {
+     if (!s->bh_nodev) {
+-        s->bh_nodev = qemu_bh_new(usb_host_nodev_bh, s);
++        s->bh_nodev = qemu_bh_new_guarded(usb_host_nodev_bh, s,
++                                          &DEVICE(s)->mem_reentrancy_guard);
+     }
+     qemu_bh_schedule(s->bh_nodev);
+ }
+@@ -1739,7 +1740,8 @@ static int usb_host_post_load(void *opaque, int 
version_id)
+     USBHostDevice *dev = opaque;
+
+     if (!dev->bh_postld) {
+-        dev->bh_postld = qemu_bh_new(usb_host_post_load_bh, dev);
++        dev->bh_postld = qemu_bh_new_guarded(usb_host_post_load_bh, dev,
++                                             
&DEVICE(dev)->mem_reentrancy_guard);
+     }
+     qemu_bh_schedule(dev->bh_postld);
+     dev->bh_postld_pending = true;
+diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
+index 5f0ef9cb3..59cd3cd7c 100644
+--- a/hw/usb/redirect.c
++++ b/hw/usb/redirect.c
+@@ -1437,8 +1437,10 @@ static void usbredir_realize(USBDevice *udev, Error 
**errp)
+         }
+     }
+
+-    dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
+-    dev->device_reject_bh = qemu_bh_new(usbredir_device_reject_bh, dev);
++    dev->chardev_close_bh = qemu_bh_new_guarded(usbredir_chardev_close_bh, 
dev,
++                                                
&DEVICE(dev)->mem_reentrancy_guard);
++    dev->device_reject_bh = qemu_bh_new_guarded(usbredir_device_reject_bh, 
dev,
++                                                
&DEVICE(dev)->mem_reentrancy_guard);
+     dev->attach_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, usbredir_do_attach, 
dev);
+
+     packet_id_queue_init(&dev->cancelled, dev, "cancelled");
+diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
+index 0f7369e7e..dec91294a 100644
+--- a/hw/usb/xen-usb.c
++++ b/hw/usb/xen-usb.c
+@@ -1021,7 +1021,8 @@ static void usbback_alloc(struct XenLegacyDevice *xendev)
+
+     QTAILQ_INIT(&usbif->req_free_q);
+     QSIMPLEQ_INIT(&usbif->hotplug_q);
+-    usbif->bh = qemu_bh_new(usbback_bh, usbif);
++    usbif->bh = qemu_bh_new_guarded(usbback_bh, usbif,
++                                    &DEVICE(xendev)->mem_reentrancy_guard);
+ }
+
+ static int usbback_free(struct XenLegacyDevice *xendev)
+diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
+index 9a4f491b5..f503572e2 100644
+--- a/hw/virtio/virtio-balloon.c
++++ b/hw/virtio/virtio-balloon.c
+@@ -917,8 +917,9 @@ static void virtio_balloon_device_realize(DeviceState 
*dev, Error **errp)
+         precopy_add_notifier(&s->free_page_hint_notify);
+
+         object_ref(OBJECT(s->iothread));
+-        s->free_page_bh = aio_bh_new(iothread_get_aio_context(s->iothread),
+-                                     virtio_ballloon_get_free_page_hints, s);
++        s->free_page_bh = 
aio_bh_new_guarded(iothread_get_aio_context(s->iothread),
++                                             
virtio_ballloon_get_free_page_hints, s,
++                                             &dev->mem_reentrancy_guard);
+     }
+
+     if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_REPORTING)) {
+diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
+index 274c7b4de..cb3e6ed0e 100644
+--- a/hw/virtio/virtio-crypto.c
++++ b/hw/virtio/virtio-crypto.c
+@@ -822,7 +822,8 @@ static void virtio_crypto_device_realize(DeviceState *dev, 
Error **errp)
+         vcrypto->vqs[i].dataq =
+                  virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh);
+         vcrypto->vqs[i].dataq_bh =
+-                 qemu_bh_new(virtio_crypto_dataq_bh, &vcrypto->vqs[i]);
++                 qemu_bh_new_guarded(virtio_crypto_dataq_bh, &vcrypto->vqs[i],
++                                     &dev->mem_reentrancy_guard);
+         vcrypto->vqs[i].vcrypto = vcrypto;
+     }
+
+--
+2.40.0
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0003.patch 
b/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0003.patch
new file mode 100644
index 0000000000..8f7fa1a569
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0003.patch
@@ -0,0 +1,68 @@
+From ec0504b989ca61e03636384d3602b7bf07ffe4da Mon Sep 17 00:00:00 2001
+From: Philippe Mathieu-Daudé <[email protected]>
+Date: Mon, 27 May 2024 11:52:53 +0000
+Subject: [PATCH] hw/virtio: Introduce virtio_bh_new_guarded() helper
+
+Introduce virtio_bh_new_guarded(), similar to qemu_bh_new_guarded()
+but using the transport memory guard, instead of the device one
+(there can only be one virtio device per virtio bus).
+
+Inspired-by: Gerd Hoffmann <[email protected]>
+Reviewed-by: Gerd Hoffmann <[email protected]>
+Acked-by: Michael S. Tsirkin <[email protected]>
+Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
+Reviewed-by: Michael S. Tsirkin <[email protected]>
+Message-Id: <[email protected]>
+
+CVE: CVE-2024-3446
+Upstream-Status: Backport 
[https://gitlab.com/qemu-project/qemu/-/commit/ec0504b989ca61e03636384d3602b7bf07ffe4da]
+
+Signed-off-by: Yogita Urade <[email protected]>
+---
+ hw/virtio/virtio.c         | 10 ++++++++++
+ include/hw/virtio/virtio.h |  7 +++++++
+ 2 files changed, 17 insertions(+)
+
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index e11a8a0db..be0b3ff9d 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -3876,3 +3876,13 @@ static void virtio_register_types(void)
+ }
+
+ type_init(virtio_register_types)
++
++QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev,
++                                   QEMUBHFunc *cb, void *opaque,
++                                   const char *name)
++{
++    DeviceState *transport = qdev_get_parent_bus(dev)->parent;
++
++    return qemu_bh_new_full(cb, opaque, name,
++                            &transport->mem_reentrancy_guard);
++}
+diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
+index 8bab9cfb7..731c631a8 100644
+--- a/include/hw/virtio/virtio.h
++++ b/include/hw/virtio/virtio.h
+@@ -22,6 +22,7 @@
+ #include "standard-headers/linux/virtio_config.h"
+ #include "standard-headers/linux/virtio_ring.h"
+ #include "qom/object.h"
++#include "block/aio.h"
+
+ /* A guest should never accept this.  It implies negotiation is broken. */
+ #define VIRTIO_F_BAD_FEATURE          30
+@@ -397,4 +398,10 @@ static inline bool virtio_device_disabled(VirtIODevice 
*vdev)
+ bool virtio_legacy_allowed(VirtIODevice *vdev);
+ bool virtio_legacy_check_disabled(VirtIODevice *vdev);
+
++QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev,
++                                   QEMUBHFunc *cb, void *opaque,
++                                   const char *name);
++#define virtio_bh_new_guarded(dev, cb, opaque) \
++    virtio_bh_new_guarded_full((dev), (cb), (opaque), (stringify(cb)))
++
+ #endif
+--
+2.40.0
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0004.patch 
b/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0004.patch
new file mode 100644
index 0000000000..d833b8b1e1
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0004.patch
@@ -0,0 +1,144 @@
+From ba28e0ff4d95b56dc334aac2730ab3651ffc3132 Mon Sep 17 00:00:00 2001
+From: Philippe Mathieu-Daudé <[email protected]>
+Date: Tue, 28 May 2024 05:50:35 +0000
+Subject: [PATCH] virtio-gpu: Protect from DMA re-entrancy bugs
+
+Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
+so the bus and device use the same guard. Otherwise the
+DMA-reentrancy protection can be bypassed:
+
+  $ cat << EOF | qemu-system-i386 -display none -nodefaults \
+                                  -machine q35,accel=qtest \
+                                  -m 512M \
+                                  -device virtio-gpu \
+                                  -qtest stdio
+
+  outl 0xcf8 0x80000820
+  outl 0xcfc 0xe0004000
+  outl 0xcf8 0x80000804
+  outw 0xcfc 0x06
+  write 0xe0004030 0x4 0x024000e0
+  write 0xe0004028 0x1 0xff
+  write 0xe0004020 0x4 0x00009300
+  write 0xe000401c 0x1 0x01
+  write 0x101 0x1 0x04
+  write 0x103 0x1 0x1c
+  write 0x9301c8 0x1 0x18
+  write 0x105 0x1 0x1c
+  write 0x107 0x1 0x1c
+  write 0x109 0x1 0x1c
+  write 0x10b 0x1 0x00
+  write 0x10d 0x1 0x00
+  write 0x10f 0x1 0x00
+  write 0x111 0x1 0x00
+  write 0x113 0x1 0x00
+  write 0x115 0x1 0x00
+  write 0x117 0x1 0x00
+  write 0x119 0x1 0x00
+  write 0x11b 0x1 0x00
+  write 0x11d 0x1 0x00
+  write 0x11f 0x1 0x00
+  write 0x121 0x1 0x00
+  write 0x123 0x1 0x00
+  write 0x125 0x1 0x00
+  write 0x127 0x1 0x00
+  write 0x129 0x1 0x00
+  write 0x12b 0x1 0x00
+  write 0x12d 0x1 0x00
+  write 0x12f 0x1 0x00
+  write 0x131 0x1 0x00
+  write 0x133 0x1 0x00
+  write 0x135 0x1 0x00
+  write 0x137 0x1 0x00
+  write 0x139 0x1 0x00
+  write 0xe0007003 0x1 0x00
+  EOF
+  ...
+  =================================================================
+  ==276099==ERROR: AddressSanitizer: heap-use-after-free on address 
0x60d000011178
+  at pc 0x562cc3b736c7 bp 0x7ffed49dee60 sp 0x7ffed49dee58
+  READ of size 8 at 0x60d000011178 thread T0
+      #0 0x562cc3b736c6 in virtio_gpu_ctrl_response 
hw/display/virtio-gpu.c:180:42
+      #1 0x562cc3b7c40b in virtio_gpu_ctrl_response_nodata 
hw/display/virtio-gpu.c:192:5
+      #2 0x562cc3b7c40b in virtio_gpu_simple_process_cmd 
hw/display/virtio-gpu.c:1015:13
+      #3 0x562cc3b82873 in virtio_gpu_process_cmdq 
hw/display/virtio-gpu.c:1050:9
+      #4 0x562cc4a85514 in aio_bh_call util/async.c:169:5
+      #5 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13
+      #6 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5
+      #7 0x562cc4a8a2da in aio_ctx_dispatch util/async.c:358:5
+      #8 0x7f36840547a8 in g_main_context_dispatch 
(/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x547a8)
+      #9 0x562cc4a8b753 in glib_pollfds_poll util/main-loop.c:290:9
+      #10 0x562cc4a8b753 in os_host_main_loop_wait util/main-loop.c:313:5
+      #11 0x562cc4a8b753 in main_loop_wait util/main-loop.c:592:11
+      #12 0x562cc3938186 in qemu_main_loop system/runstate.c:782:9
+      #13 0x562cc43b7af5 in qemu_default_main system/main.c:37:14
+      #14 0x7f3683a6c189 in __libc_start_call_main 
csu/../sysdeps/nptl/libc_start_call_main.h:58:16
+      #15 0x7f3683a6c244 in __libc_start_main csu/../csu/libc-start.c:381:3
+      #16 0x562cc2a58ac0 in _start (qemu-system-i386+0x231bac0)
+
+  0x60d000011178 is located 56 bytes inside of 136-byte region 
[0x60d000011140,0x60d0000111c8)
+  freed by thread T0 here:
+      #0 0x562cc2adb662 in __interceptor_free (qemu-system-i386+0x239e662)
+      #1 0x562cc3b86b21 in virtio_gpu_reset hw/display/virtio-gpu.c:1524:9
+      #2 0x562cc416e20e in virtio_reset hw/virtio/virtio.c:2145:9
+      #3 0x562cc37c5644 in virtio_pci_reset hw/virtio/virtio-pci.c:2249:5
+      #4 0x562cc4233758 in memory_region_write_accessor system/memory.c:497:5
+      #5 0x562cc4232eea in access_with_adjusted_size system/memory.c:573:18
+
+  previously allocated by thread T0 here:
+      #0 0x562cc2adb90e in malloc (qemu-system-i386+0x239e90e)
+      #1 0x7f368405a678 in g_malloc 
(/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5a678)
+      #2 0x562cc4163ffc in virtqueue_split_pop hw/virtio/virtio.c:1612:12
+      #3 0x562cc4163ffc in virtqueue_pop hw/virtio/virtio.c:1783:16
+      #4 0x562cc3b91a95 in virtio_gpu_handle_ctrl 
hw/display/virtio-gpu.c:1112:15
+      #5 0x562cc4a85514 in aio_bh_call util/async.c:169:5
+      #6 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13
+      #7 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5
+
+  SUMMARY: AddressSanitizer: heap-use-after-free 
hw/display/virtio-gpu.c:180:42 in virtio_gpu_ctrl_response
+
+With this change, the same reproducer triggers:
+
+  qemu-system-i386: warning: Blocked re-entrant IO on MemoryRegion: 
virtio-pci-common-virtio-gpu at addr: 0x6
+
+Fixes: CVE-2024-3446
+Cc: [email protected]
+Reported-by: Alexander Bulekov <[email protected]>
+Reported-by: Yongkang Jia <[email protected]>
+Reported-by: Xiao Lei <[email protected]>
+Reported-by: Yiming Tao <[email protected]>
+Buglink: https://bugs.launchpad.net/qemu/+bug/1888606
+
+Reviewed-by: Gerd Hoffmann <[email protected]>
+Acked-by: Michael S. Tsirkin <[email protected]>
+Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
+Reviewed-by: Michael S. Tsirkin <[email protected]>
+Message-Id: <[email protected]>
+
+CVE: CVE-2024-3446
+Upstream-Status: Backport 
[https://gitlab.com/qemu-project/qemu/-/commit/ba28e0ff4d95b56dc334aac2730ab3651ffc3132]
+
+Signed-off-by: Yogita Urade <[email protected]>
+---
+ hw/display/virtio-gpu.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
+index 316469ab7..5719ef6f1 100644
+--- a/hw/display/virtio-gpu.c
++++ b/hw/display/virtio-gpu.c
+@@ -1334,10 +1334,8 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error 
**errp)
+
+     g->ctrl_vq = virtio_get_queue(vdev, 0);
+     g->cursor_vq = virtio_get_queue(vdev, 1);
+-    g->ctrl_bh = qemu_bh_new_guarded(virtio_gpu_ctrl_bh, g,
+-                                     &qdev->mem_reentrancy_guard);
+-    g->cursor_bh = qemu_bh_new_guarded(virtio_gpu_cursor_bh, g,
+-                                       &qdev->mem_reentrancy_guard);
++    g->ctrl_bh = virtio_bh_new_guarded(qdev, virtio_gpu_ctrl_bh, g);
++    g->cursor_bh = virtio_bh_new_guarded(qdev, virtio_gpu_cursor_bh, g);
+     QTAILQ_INIT(&g->reslist);
+     QTAILQ_INIT(&g->cmdq);
+     QTAILQ_INIT(&g->fenceq);
+--
+2.40.0
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0005.patch 
b/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0005.patch
new file mode 100644
index 0000000000..51aa8a4038
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0005.patch
@@ -0,0 +1,42 @@
+From b4295bff25f7b50de1d9cc94a9c6effd40056bca Mon Sep 17 00:00:00 2001
+From: Philippe Mathieu-Daudé <[email protected]>
+Date: Tue, 28 May 2024 06:55:51 +0000
+Subject: [PATCH] hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs
+
+Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
+so the bus and device use the same guard. Otherwise the
+DMA-reentrancy protection can be bypassed.
+
+Fixes: CVE-2024-3446
+Cc: [email protected]
+Suggested-by: Alexander Bulekov <[email protected]>
+Reviewed-by: Gerd Hoffmann <[email protected]>
+Acked-by: Michael S. Tsirkin <[email protected]>
+Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
+Reviewed-by: Michael S. Tsirkin <[email protected]>
+Message-Id: <[email protected]>
+
+CVE: CVE-2024-3446
+Upstream-Status: Backport 
[https://gitlab.com/qemu-project/qemu/-/commit/b4295bff25f7b50de1d9cc94a9c6effd40056bca]
+
+Signed-off-by: Yogita Urade <[email protected]>
+---
+ hw/char/virtio-serial-bus.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
+index f18124b15..791b7ac59 100644
+--- a/hw/char/virtio-serial-bus.c
++++ b/hw/char/virtio-serial-bus.c
+@@ -985,8 +985,7 @@ static void virtser_port_device_realize(DeviceState *dev, 
Error **errp)
+         return;
+     }
+
+-    port->bh = qemu_bh_new_guarded(flush_queued_data_bh, port,
+-                                   &dev->mem_reentrancy_guard);
++    port->bh = virtio_bh_new_guarded(dev, flush_queued_data_bh, port);
+     port->elem = NULL;
+ }
+
+--
+2.40.0
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0006.patch 
b/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0006.patch
new file mode 100644
index 0000000000..c7f19f45e7
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2024-3446-0006.patch
@@ -0,0 +1,43 @@
+From f4729ec39ad97a42ceaa7b5697f84f440ea6e5dc Mon Sep 17 00:00:00 2001
+From: Philippe Mathieu-Daudé <[email protected]>
+Date: Tue, 28 May 2024 09:22:58 +0000
+Subject: [PATCH] hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs
+
+Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
+so the bus and device use the same guard. Otherwise the
+DMA-reentrancy protection can be bypassed.
+
+Fixes: CVE-2024-3446
+Cc: [email protected]
+Suggested-by: Alexander Bulekov <[email protected]>
+Reviewed-by: Gerd Hoffmann <[email protected]>
+Acked-by: Michael S. Tsirkin <[email protected]>
+Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
+Reviewed-by: Michael S. Tsirkin <[email protected]>
+Message-Id: <[email protected]>
+
+CVE: CVE-2024-3446
+Upstream-Status: Backport 
[https://gitlab.com/qemu-project/qemu/-/commit/f4729ec39ad97a42ceaa7b5697f84f440ea6e5dc]
+
+Signed-off-by: Yogita Urade <[email protected]>
+---
+ hw/virtio/virtio-crypto.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
+index cb3e6ed0e..930a8418f 100644
+--- a/hw/virtio/virtio-crypto.c
++++ b/hw/virtio/virtio-crypto.c
+@@ -822,8 +822,8 @@ static void virtio_crypto_device_realize(DeviceState *dev, 
Error **errp)
+         vcrypto->vqs[i].dataq =
+                  virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh);
+         vcrypto->vqs[i].dataq_bh =
+-                 qemu_bh_new_guarded(virtio_crypto_dataq_bh, &vcrypto->vqs[i],
+-                                     &dev->mem_reentrancy_guard);
++                 virtio_bh_new_guarded(dev, virtio_crypto_dataq_bh,
++                                     &vcrypto->vqs[i]);
+         vcrypto->vqs[i].vcrypto = vcrypto;
+     }
+
+--
+2.40.0
-- 
2.34.1

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#208306): 
https://lists.openembedded.org/g/openembedded-core/message/208306
Mute This Topic: https://lists.openembedded.org/mt/109924665/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to