diff options
7 files changed, 948 insertions, 0 deletions
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 \ | |||
| 121 | file://CVE-2023-3019-0001.patch \ | 121 | file://CVE-2023-3019-0001.patch \ |
| 122 | file://CVE-2023-3019-0002.patch \ | 122 | file://CVE-2023-3019-0002.patch \ |
| 123 | file://CVE-2024-6505.patch \ | 123 | file://CVE-2024-6505.patch \ |
| 124 | file://CVE-2024-3446-0001.patch \ | ||
| 125 | file://CVE-2024-3446-0002.patch \ | ||
| 126 | file://CVE-2024-3446-0003.patch \ | ||
| 127 | file://CVE-2024-3446-0004.patch \ | ||
| 128 | file://CVE-2024-3446-0005.patch \ | ||
| 129 | file://CVE-2024-3446-0006.patch \ | ||
| 124 | " | 130 | " |
| 125 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" | 131 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" |
| 126 | 132 | ||
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 @@ | |||
| 1 | From 9c86c97f12c060bf7484dd931f38634e166a81f0 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Alexander Bulekov <alxndr@bu.edu> | ||
| 3 | Date: Mon, 27 May 2024 07:29:20 +0000 | ||
| 4 | Subject: [PATCH] async: Add an optional reentrancy guard to the BH API | ||
| 5 | |||
| 6 | Devices can pass their MemoryReentrancyGuard (from their DeviceState), | ||
| 7 | when creating new BHes. Then, the async API will toggle the guard | ||
| 8 | before/after calling the BH call-back. This prevents bh->mmio reentrancy | ||
| 9 | issues. | ||
| 10 | |||
| 11 | Signed-off-by: Alexander Bulekov <alxndr@bu.edu> | ||
| 12 | Reviewed-by: Darren Kenny <darren.kenny@oracle.com> | ||
| 13 | Message-Id: <20230427211013.2994127-3-alxndr@bu.edu> | ||
| 14 | [thuth: Fix "line over 90 characters" checkpatch.pl error] | ||
| 15 | Signed-off-by: Thomas Huth <thuth@redhat.com> | ||
| 16 | |||
| 17 | CVE: CVE-2024-3446 | ||
| 18 | Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/9c86c97f12c060bf7484dd931f38634e166a81f0] | ||
| 19 | |||
| 20 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
| 21 | --- | ||
| 22 | docs/devel/multiple-iothreads.txt | 7 +++++++ | ||
| 23 | include/block/aio.h | 18 ++++++++++++++++-- | ||
| 24 | include/qemu/main-loop.h | 8 +++++--- | ||
| 25 | tests/unit/ptimer-test-stubs.c | 3 ++- | ||
| 26 | util/async.c | 18 +++++++++++++++++- | ||
| 27 | util/main-loop.c | 6 ++++-- | ||
| 28 | util/trace-events | 1 + | ||
| 29 | 7 files changed, 52 insertions(+), 9 deletions(-) | ||
| 30 | |||
| 31 | diff --git a/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt | ||
| 32 | index aeb997bed..a11576bc7 100644 | ||
| 33 | --- a/docs/devel/multiple-iothreads.txt | ||
| 34 | +++ b/docs/devel/multiple-iothreads.txt | ||
| 35 | @@ -61,6 +61,7 @@ There are several old APIs that use the main loop AioContext: | ||
| 36 | * LEGACY qemu_aio_set_event_notifier() - monitor an event notifier | ||
| 37 | * LEGACY timer_new_ms() - create a timer | ||
| 38 | * LEGACY qemu_bh_new() - create a BH | ||
| 39 | + * LEGACY qemu_bh_new_guarded() - create a BH with a device re-entrancy guard | ||
| 40 | * LEGACY qemu_aio_wait() - run an event loop iteration | ||
| 41 | |||
| 42 | Since they implicitly work on the main loop they cannot be used in code that | ||
| 43 | @@ -72,8 +73,14 @@ Instead, use the AioContext functions directly (see include/block/aio.h): | ||
| 44 | * aio_set_event_notifier() - monitor an event notifier | ||
| 45 | * aio_timer_new() - create a timer | ||
| 46 | * aio_bh_new() - create a BH | ||
| 47 | + * aio_bh_new_guarded() - create a BH with a device re-entrancy guard | ||
| 48 | * aio_poll() - run an event loop iteration | ||
| 49 | |||
| 50 | +The qemu_bh_new_guarded/aio_bh_new_guarded APIs accept a "MemReentrancyGuard" | ||
| 51 | +argument, which is used to check for and prevent re-entrancy problems. For | ||
| 52 | +BHs associated with devices, the reentrancy-guard is contained in the | ||
| 53 | +corresponding DeviceState and named "mem_reentrancy_guard". | ||
| 54 | + | ||
| 55 | The AioContext can be obtained from the IOThread using | ||
| 56 | iothread_get_aio_context() or for the main loop using qemu_get_aio_context(). | ||
| 57 | Code that takes an AioContext argument works both in IOThreads or the main | ||
| 58 | diff --git a/include/block/aio.h b/include/block/aio.h | ||
| 59 | index 47fbe9d81..c7da15298 100644 | ||
| 60 | --- a/include/block/aio.h | ||
| 61 | +++ b/include/block/aio.h | ||
| 62 | @@ -22,6 +22,8 @@ | ||
| 63 | #include "qemu/event_notifier.h" | ||
| 64 | #include "qemu/thread.h" | ||
| 65 | #include "qemu/timer.h" | ||
| 66 | +#include "hw/qdev-core.h" | ||
| 67 | + | ||
| 68 | |||
| 69 | typedef struct BlockAIOCB BlockAIOCB; | ||
| 70 | typedef void BlockCompletionFunc(void *opaque, int ret); | ||
| 71 | @@ -321,9 +323,11 @@ void aio_bh_schedule_oneshot_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque, | ||
| 72 | * is opaque and must be allocated prior to its use. | ||
| 73 | * | ||
| 74 | * @name: A human-readable identifier for debugging purposes. | ||
| 75 | + * @reentrancy_guard: A guard set when entering a cb to prevent | ||
| 76 | + * device-reentrancy issues | ||
| 77 | */ | ||
| 78 | QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque, | ||
| 79 | - const char *name); | ||
| 80 | + const char *name, MemReentrancyGuard *reentrancy_guard); | ||
| 81 | |||
| 82 | /** | ||
| 83 | * aio_bh_new: Allocate a new bottom half structure | ||
| 84 | @@ -332,7 +336,17 @@ QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque, | ||
| 85 | * string. | ||
| 86 | */ | ||
| 87 | #define aio_bh_new(ctx, cb, opaque) \ | ||
| 88 | - aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb))) | ||
| 89 | + aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb)), NULL) | ||
| 90 | + | ||
| 91 | +/** | ||
| 92 | + * aio_bh_new_guarded: Allocate a new bottom half structure with a | ||
| 93 | + * reentrancy_guard | ||
| 94 | + * | ||
| 95 | + * A convenience wrapper for aio_bh_new_full() that uses the cb as the name | ||
| 96 | + * string. | ||
| 97 | + */ | ||
| 98 | +#define aio_bh_new_guarded(ctx, cb, opaque, guard) \ | ||
| 99 | + aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb)), guard) | ||
| 100 | |||
| 101 | /** | ||
| 102 | * aio_notify: Force processing of pending events. | ||
| 103 | diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h | ||
| 104 | index 8dbc6fcb8..0a8f512be 100644 | ||
| 105 | --- a/include/qemu/main-loop.h | ||
| 106 | +++ b/include/qemu/main-loop.h | ||
| 107 | @@ -293,10 +293,12 @@ void qemu_cond_timedwait_iothread(QemuCond *cond, int ms); | ||
| 108 | /* internal interfaces */ | ||
| 109 | |||
| 110 | void qemu_fd_register(int fd); | ||
| 111 | - | ||
| 112 | +#define qemu_bh_new_guarded(cb, opaque, guard) \ | ||
| 113 | + qemu_bh_new_full((cb), (opaque), (stringify(cb)), guard) | ||
| 114 | #define qemu_bh_new(cb, opaque) \ | ||
| 115 | - qemu_bh_new_full((cb), (opaque), (stringify(cb))) | ||
| 116 | -QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name); | ||
| 117 | + qemu_bh_new_full((cb), (opaque), (stringify(cb)), NULL) | ||
| 118 | +QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name, | ||
| 119 | + MemReentrancyGuard *reentrancy_guard); | ||
| 120 | void qemu_bh_schedule_idle(QEMUBH *bh); | ||
| 121 | |||
| 122 | enum { | ||
| 123 | diff --git a/tests/unit/ptimer-test-stubs.c b/tests/unit/ptimer-test-stubs.c | ||
| 124 | index 2a3ef5879..a7a2d08e7 100644 | ||
| 125 | --- a/tests/unit/ptimer-test-stubs.c | ||
| 126 | +++ b/tests/unit/ptimer-test-stubs.c | ||
| 127 | @@ -108,7 +108,8 @@ int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int attr_mask) | ||
| 128 | return deadline; | ||
| 129 | } | ||
| 130 | |||
| 131 | -QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name) | ||
| 132 | +QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name, | ||
| 133 | + MemReentrancyGuard *reentrancy_guard) | ||
| 134 | { | ||
| 135 | QEMUBH *bh = g_new(QEMUBH, 1); | ||
| 136 | |||
| 137 | diff --git a/util/async.c b/util/async.c | ||
| 138 | index 6f6717a34..3eb6b5016 100644 | ||
| 139 | --- a/util/async.c | ||
| 140 | +++ b/util/async.c | ||
| 141 | @@ -62,6 +62,7 @@ struct QEMUBH { | ||
| 142 | void *opaque; | ||
| 143 | QSLIST_ENTRY(QEMUBH) next; | ||
| 144 | unsigned flags; | ||
| 145 | + MemReentrancyGuard *reentrancy_guard; | ||
| 146 | }; | ||
| 147 | |||
| 148 | /* Called concurrently from any thread */ | ||
| 149 | @@ -123,7 +124,7 @@ void aio_bh_schedule_oneshot_full(AioContext *ctx, QEMUBHFunc *cb, | ||
| 150 | } | ||
| 151 | |||
| 152 | QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque, | ||
| 153 | - const char *name) | ||
| 154 | + const char *name, MemReentrancyGuard *reentrancy_guard) | ||
| 155 | { | ||
| 156 | QEMUBH *bh; | ||
| 157 | bh = g_new(QEMUBH, 1); | ||
| 158 | @@ -132,13 +133,28 @@ QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque, | ||
| 159 | .cb = cb, | ||
| 160 | .opaque = opaque, | ||
| 161 | .name = name, | ||
| 162 | + .reentrancy_guard = reentrancy_guard, | ||
| 163 | }; | ||
| 164 | return bh; | ||
| 165 | } | ||
| 166 | |||
| 167 | void aio_bh_call(QEMUBH *bh) | ||
| 168 | { | ||
| 169 | + bool last_engaged_in_io = false; | ||
| 170 | + | ||
| 171 | + if (bh->reentrancy_guard) { | ||
| 172 | + last_engaged_in_io = bh->reentrancy_guard->engaged_in_io; | ||
| 173 | + if (bh->reentrancy_guard->engaged_in_io) { | ||
| 174 | + trace_reentrant_aio(bh->ctx, bh->name); | ||
| 175 | + } | ||
| 176 | + bh->reentrancy_guard->engaged_in_io = true; | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | bh->cb(bh->opaque); | ||
| 180 | + | ||
| 181 | + if (bh->reentrancy_guard) { | ||
| 182 | + bh->reentrancy_guard->engaged_in_io = last_engaged_in_io; | ||
| 183 | + } | ||
| 184 | } | ||
| 185 | |||
| 186 | /* Multiple occurrences of aio_bh_poll cannot be called concurrently. */ | ||
| 187 | diff --git a/util/main-loop.c b/util/main-loop.c | ||
| 188 | index 06b18b195..1eacf0469 100644 | ||
| 189 | --- a/util/main-loop.c | ||
| 190 | +++ b/util/main-loop.c | ||
| 191 | @@ -544,9 +544,11 @@ void main_loop_wait(int nonblocking) | ||
| 192 | |||
| 193 | /* Functions to operate on the main QEMU AioContext. */ | ||
| 194 | |||
| 195 | -QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name) | ||
| 196 | +QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name, | ||
| 197 | + MemReentrancyGuard *reentrancy_guard) | ||
| 198 | { | ||
| 199 | - return aio_bh_new_full(qemu_aio_context, cb, opaque, name); | ||
| 200 | + return aio_bh_new_full(qemu_aio_context, cb, opaque, name, | ||
| 201 | + reentrancy_guard); | ||
| 202 | } | ||
| 203 | |||
| 204 | /* | ||
| 205 | diff --git a/util/trace-events b/util/trace-events | ||
| 206 | index c8f53d7d9..dc3b1eb3b 100644 | ||
| 207 | --- a/util/trace-events | ||
| 208 | +++ b/util/trace-events | ||
| 209 | @@ -11,6 +11,7 @@ poll_remove(void *ctx, void *node, int fd) "ctx %p node %p fd %d" | ||
| 210 | # async.c | ||
| 211 | aio_co_schedule(void *ctx, void *co) "ctx %p co %p" | ||
| 212 | aio_co_schedule_bh_cb(void *ctx, void *co) "ctx %p co %p" | ||
| 213 | +reentrant_aio(void *ctx, const char *name) "ctx %p name %s" | ||
| 214 | |||
| 215 | # thread-pool.c | ||
| 216 | thread_pool_submit(void *pool, void *req, void *opaque) "pool %p req %p opaque %p" | ||
| 217 | -- | ||
| 218 | 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 @@ | |||
| 1 | From f63192b0544af5d3e4d5edfd85ab520fcf671377 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Alexander Bulekov <alxndr@bu.edu> | ||
| 3 | Date: Thu, 27 Apr 2023 17:10:09 -0400 | ||
| 4 | Subject: [PATCH] hw: replace most qemu_bh_new calls with qemu_bh_new_guarded | ||
| 5 | |||
| 6 | This protects devices from bh->mmio reentrancy issues. | ||
| 7 | |||
| 8 | Thanks: Thomas Huth <thuth@redhat.com> for diagnosing OS X test failure. | ||
| 9 | Signed-off-by: Alexander Bulekov <alxndr@bu.edu> | ||
| 10 | Reviewed-by: Darren Kenny <darren.kenny@oracle.com> | ||
| 11 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
| 12 | Reviewed-by: Michael S. Tsirkin <mst@redhat.com> | ||
| 13 | Reviewed-by: Paul Durrant <paul@xen.org> | ||
| 14 | Reviewed-by: Thomas Huth <thuth@redhat.com> | ||
| 15 | Message-Id: <20230427211013.2994127-5-alxndr@bu.edu> | ||
| 16 | Signed-off-by: Thomas Huth <thuth@redhat.com> | ||
| 17 | |||
| 18 | CVE: CVE-2024-3446 | ||
| 19 | Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/f63192b0544af5d3e4d5edfd85ab520fcf671377] | ||
| 20 | |||
| 21 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
| 22 | --- | ||
| 23 | hw/9pfs/xen-9p-backend.c | 5 ++++- | ||
| 24 | hw/block/dataplane/virtio-blk.c | 3 ++- | ||
| 25 | hw/block/dataplane/xen-block.c | 5 +++-- | ||
| 26 | hw/char/virtio-serial-bus.c | 3 ++- | ||
| 27 | hw/display/qxl.c | 9 ++++++--- | ||
| 28 | hw/display/virtio-gpu.c | 6 ++++-- | ||
| 29 | hw/ide/ahci.c | 3 ++- | ||
| 30 | hw/ide/ahci_internal.h | 1 + | ||
| 31 | hw/ide/core.c | 4 +++- | ||
| 32 | hw/misc/imx_rngc.c | 6 ++++-- | ||
| 33 | hw/misc/macio/mac_dbdma.c | 2 +- | ||
| 34 | hw/net/virtio-net.c | 3 ++- | ||
| 35 | hw/scsi/mptsas.c | 3 ++- | ||
| 36 | hw/scsi/scsi-bus.c | 3 ++- | ||
| 37 | hw/scsi/vmw_pvscsi.c | 3 ++- | ||
| 38 | hw/usb/dev-uas.c | 3 ++- | ||
| 39 | hw/usb/hcd-dwc2.c | 3 ++- | ||
| 40 | hw/usb/hcd-ehci.c | 3 ++- | ||
| 41 | hw/usb/hcd-uhci.c | 2 +- | ||
| 42 | hw/usb/host-libusb.c | 6 ++++-- | ||
| 43 | hw/usb/redirect.c | 6 ++++-- | ||
| 44 | hw/usb/xen-usb.c | 3 ++- | ||
| 45 | hw/virtio/virtio-balloon.c | 5 +++-- | ||
| 46 | hw/virtio/virtio-crypto.c | 3 ++- | ||
| 47 | 24 files changed, 62 insertions(+), 31 deletions(-) | ||
| 48 | |||
| 49 | diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c | ||
| 50 | index 65c4979c3..09f7c1358 100644 | ||
| 51 | --- a/hw/9pfs/xen-9p-backend.c | ||
| 52 | +++ b/hw/9pfs/xen-9p-backend.c | ||
| 53 | @@ -60,6 +60,7 @@ typedef struct Xen9pfsDev { | ||
| 54 | |||
| 55 | int num_rings; | ||
| 56 | Xen9pfsRing *rings; | ||
| 57 | + MemReentrancyGuard mem_reentrancy_guard; | ||
| 58 | } Xen9pfsDev; | ||
| 59 | |||
| 60 | static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev); | ||
| 61 | @@ -441,7 +442,9 @@ static int xen_9pfs_connect(struct XenLegacyDevice *xendev) | ||
| 62 | xen_9pdev->rings[i].ring.out = xen_9pdev->rings[i].data + | ||
| 63 | XEN_FLEX_RING_SIZE(ring_order); | ||
| 64 | |||
| 65 | - xen_9pdev->rings[i].bh = qemu_bh_new(xen_9pfs_bh, &xen_9pdev->rings[i]); | ||
| 66 | + xen_9pdev->rings[i].bh = qemu_bh_new_guarded(xen_9pfs_bh, | ||
| 67 | + &xen_9pdev->rings[i], | ||
| 68 | + &xen_9pdev->mem_reentrancy_guard); | ||
| 69 | xen_9pdev->rings[i].out_cons = 0; | ||
| 70 | xen_9pdev->rings[i].out_size = 0; | ||
| 71 | xen_9pdev->rings[i].inprogress = false; | ||
| 72 | diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c | ||
| 73 | index ee5a5352d..5f0de7da1 100644 | ||
| 74 | --- a/hw/block/dataplane/virtio-blk.c | ||
| 75 | +++ b/hw/block/dataplane/virtio-blk.c | ||
| 76 | @@ -127,7 +127,8 @@ bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, | ||
| 77 | } else { | ||
| 78 | s->ctx = qemu_get_aio_context(); | ||
| 79 | } | ||
| 80 | - s->bh = aio_bh_new(s->ctx, notify_guest_bh, s); | ||
| 81 | + s->bh = aio_bh_new_guarded(s->ctx, notify_guest_bh, s, | ||
| 82 | + &DEVICE(vdev)->mem_reentrancy_guard); | ||
| 83 | s->batch_notify_vqs = bitmap_new(conf->num_queues); | ||
| 84 | |||
| 85 | *dataplane = s; | ||
| 86 | diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c | ||
| 87 | index 860787580..07855feea 100644 | ||
| 88 | --- a/hw/block/dataplane/xen-block.c | ||
| 89 | +++ b/hw/block/dataplane/xen-block.c | ||
| 90 | @@ -631,8 +631,9 @@ XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev, | ||
| 91 | } else { | ||
| 92 | dataplane->ctx = qemu_get_aio_context(); | ||
| 93 | } | ||
| 94 | - dataplane->bh = aio_bh_new(dataplane->ctx, xen_block_dataplane_bh, | ||
| 95 | - dataplane); | ||
| 96 | + dataplane->bh = aio_bh_new_guarded(dataplane->ctx, xen_block_dataplane_bh, | ||
| 97 | + dataplane, | ||
| 98 | + &DEVICE(xendev)->mem_reentrancy_guard); | ||
| 99 | |||
| 100 | return dataplane; | ||
| 101 | } | ||
| 102 | diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c | ||
| 103 | index f01ec2137..f18124b15 100644 | ||
| 104 | --- a/hw/char/virtio-serial-bus.c | ||
| 105 | +++ b/hw/char/virtio-serial-bus.c | ||
| 106 | @@ -985,7 +985,8 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp) | ||
| 107 | return; | ||
| 108 | } | ||
| 109 | |||
| 110 | - port->bh = qemu_bh_new(flush_queued_data_bh, port); | ||
| 111 | + port->bh = qemu_bh_new_guarded(flush_queued_data_bh, port, | ||
| 112 | + &dev->mem_reentrancy_guard); | ||
| 113 | port->elem = NULL; | ||
| 114 | } | ||
| 115 | |||
| 116 | diff --git a/hw/display/qxl.c b/hw/display/qxl.c | ||
| 117 | index 2a4b2d415..585254fc7 100644 | ||
| 118 | --- a/hw/display/qxl.c | ||
| 119 | +++ b/hw/display/qxl.c | ||
| 120 | @@ -2205,11 +2205,14 @@ static void qxl_realize_common(PCIQXLDevice *qxl, Error **errp) | ||
| 121 | |||
| 122 | qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl); | ||
| 123 | |||
| 124 | - qxl->update_irq = qemu_bh_new(qxl_update_irq_bh, qxl); | ||
| 125 | + qxl->update_irq = qemu_bh_new_guarded(qxl_update_irq_bh, qxl, | ||
| 126 | + &DEVICE(qxl)->mem_reentrancy_guard); | ||
| 127 | qxl_reset_state(qxl); | ||
| 128 | |||
| 129 | - qxl->update_area_bh = qemu_bh_new(qxl_render_update_area_bh, qxl); | ||
| 130 | - qxl->ssd.cursor_bh = qemu_bh_new(qemu_spice_cursor_refresh_bh, &qxl->ssd); | ||
| 131 | + qxl->update_area_bh = qemu_bh_new_guarded(qxl_render_update_area_bh, qxl, | ||
| 132 | + &DEVICE(qxl)->mem_reentrancy_guard); | ||
| 133 | + qxl->ssd.cursor_bh = qemu_bh_new_guarded(qemu_spice_cursor_refresh_bh, &qxl->ssd, | ||
| 134 | + &DEVICE(qxl)->mem_reentrancy_guard); | ||
| 135 | } | ||
| 136 | |||
| 137 | static void qxl_realize_primary(PCIDevice *dev, Error **errp) | ||
| 138 | diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c | ||
| 139 | index c6dc81898..316469ab7 100644 | ||
| 140 | --- a/hw/display/virtio-gpu.c | ||
| 141 | +++ b/hw/display/virtio-gpu.c | ||
| 142 | @@ -1334,8 +1334,10 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) | ||
| 143 | |||
| 144 | g->ctrl_vq = virtio_get_queue(vdev, 0); | ||
| 145 | g->cursor_vq = virtio_get_queue(vdev, 1); | ||
| 146 | - g->ctrl_bh = qemu_bh_new(virtio_gpu_ctrl_bh, g); | ||
| 147 | - g->cursor_bh = qemu_bh_new(virtio_gpu_cursor_bh, g); | ||
| 148 | + g->ctrl_bh = qemu_bh_new_guarded(virtio_gpu_ctrl_bh, g, | ||
| 149 | + &qdev->mem_reentrancy_guard); | ||
| 150 | + g->cursor_bh = qemu_bh_new_guarded(virtio_gpu_cursor_bh, g, | ||
| 151 | + &qdev->mem_reentrancy_guard); | ||
| 152 | QTAILQ_INIT(&g->reslist); | ||
| 153 | QTAILQ_INIT(&g->cmdq); | ||
| 154 | QTAILQ_INIT(&g->fenceq); | ||
| 155 | diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c | ||
| 156 | index 205dfdc66..f77d0faf0 100644 | ||
| 157 | --- a/hw/ide/ahci.c | ||
| 158 | +++ b/hw/ide/ahci.c | ||
| 159 | @@ -1508,7 +1508,8 @@ static void ahci_cmd_done(const IDEDMA *dma) | ||
| 160 | ahci_write_fis_d2h(ad); | ||
| 161 | |||
| 162 | if (ad->port_regs.cmd_issue && !ad->check_bh) { | ||
| 163 | - ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad); | ||
| 164 | + ad->check_bh = qemu_bh_new_guarded(ahci_check_cmd_bh, ad, | ||
| 165 | + &ad->mem_reentrancy_guard); | ||
| 166 | qemu_bh_schedule(ad->check_bh); | ||
| 167 | } | ||
| 168 | } | ||
| 169 | diff --git a/hw/ide/ahci_internal.h b/hw/ide/ahci_internal.h | ||
| 170 | index 109de9e2d..a7768dd69 100644 | ||
| 171 | --- a/hw/ide/ahci_internal.h | ||
| 172 | +++ b/hw/ide/ahci_internal.h | ||
| 173 | @@ -321,6 +321,7 @@ struct AHCIDevice { | ||
| 174 | bool init_d2h_sent; | ||
| 175 | AHCICmdHdr *cur_cmd; | ||
| 176 | NCQTransferState ncq_tfs[AHCI_MAX_CMDS]; | ||
| 177 | + MemReentrancyGuard mem_reentrancy_guard; | ||
| 178 | }; | ||
| 179 | |||
| 180 | struct AHCIPCIState { | ||
| 181 | diff --git a/hw/ide/core.c b/hw/ide/core.c | ||
| 182 | index 63998410a..0416f45a6 100644 | ||
| 183 | --- a/hw/ide/core.c | ||
| 184 | +++ b/hw/ide/core.c | ||
| 185 | @@ -506,11 +506,13 @@ BlockAIOCB *ide_issue_trim( | ||
| 186 | BlockCompletionFunc *cb, void *cb_opaque, void *opaque) | ||
| 187 | { | ||
| 188 | IDEState *s = opaque; | ||
| 189 | + IDEDevice *dev = s->unit ? s->bus->slave : s->bus->master; | ||
| 190 | TrimAIOCB *iocb; | ||
| 191 | |||
| 192 | iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque); | ||
| 193 | iocb->s = s; | ||
| 194 | - iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb); | ||
| 195 | + iocb->bh = qemu_bh_new_guarded(ide_trim_bh_cb, iocb, | ||
| 196 | + &DEVICE(dev)->mem_reentrancy_guard); | ||
| 197 | iocb->ret = 0; | ||
| 198 | iocb->qiov = qiov; | ||
| 199 | iocb->i = -1; | ||
| 200 | diff --git a/hw/misc/imx_rngc.c b/hw/misc/imx_rngc.c | ||
| 201 | index 632c03779..082c6980a 100644 | ||
| 202 | --- a/hw/misc/imx_rngc.c | ||
| 203 | +++ b/hw/misc/imx_rngc.c | ||
| 204 | @@ -228,8 +228,10 @@ static void imx_rngc_realize(DeviceState *dev, Error **errp) | ||
| 205 | sysbus_init_mmio(sbd, &s->iomem); | ||
| 206 | |||
| 207 | sysbus_init_irq(sbd, &s->irq); | ||
| 208 | - s->self_test_bh = qemu_bh_new(imx_rngc_self_test, s); | ||
| 209 | - s->seed_bh = qemu_bh_new(imx_rngc_seed, s); | ||
| 210 | + s->self_test_bh = qemu_bh_new_guarded(imx_rngc_self_test, s, | ||
| 211 | + &dev->mem_reentrancy_guard); | ||
| 212 | + s->seed_bh = qemu_bh_new_guarded(imx_rngc_seed, s, | ||
| 213 | + &dev->mem_reentrancy_guard); | ||
| 214 | } | ||
| 215 | |||
| 216 | static void imx_rngc_reset(DeviceState *dev) | ||
| 217 | diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c | ||
| 218 | index efcc02609..cc7e02203 100644 | ||
| 219 | --- a/hw/misc/macio/mac_dbdma.c | ||
| 220 | +++ b/hw/misc/macio/mac_dbdma.c | ||
| 221 | @@ -914,7 +914,7 @@ static void mac_dbdma_realize(DeviceState *dev, Error **errp) | ||
| 222 | { | ||
| 223 | DBDMAState *s = MAC_DBDMA(dev); | ||
| 224 | |||
| 225 | - s->bh = qemu_bh_new(DBDMA_run_bh, s); | ||
| 226 | + s->bh = qemu_bh_new_guarded(DBDMA_run_bh, s, &dev->mem_reentrancy_guard); | ||
| 227 | } | ||
| 228 | |||
| 229 | static void mac_dbdma_class_init(ObjectClass *oc, void *data) | ||
| 230 | diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c | ||
| 231 | index 9127d03db..a1d65b2f2 100644 | ||
| 232 | --- a/hw/net/virtio-net.c | ||
| 233 | +++ b/hw/net/virtio-net.c | ||
| 234 | @@ -2744,7 +2744,8 @@ static void virtio_net_add_queue(VirtIONet *n, int index) | ||
| 235 | n->vqs[index].tx_vq = | ||
| 236 | virtio_add_queue(vdev, n->net_conf.tx_queue_size, | ||
| 237 | virtio_net_handle_tx_bh); | ||
| 238 | - n->vqs[index].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[index]); | ||
| 239 | + n->vqs[index].tx_bh = qemu_bh_new_guarded(virtio_net_tx_bh, &n->vqs[index], | ||
| 240 | + &DEVICE(vdev)->mem_reentrancy_guard); | ||
| 241 | } | ||
| 242 | |||
| 243 | n->vqs[index].tx_waiting = 0; | ||
| 244 | diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c | ||
| 245 | index 5181b0c0b..8487138cb 100644 | ||
| 246 | --- a/hw/scsi/mptsas.c | ||
| 247 | +++ b/hw/scsi/mptsas.c | ||
| 248 | @@ -1321,7 +1321,8 @@ static void mptsas_scsi_realize(PCIDevice *dev, Error **errp) | ||
| 249 | } | ||
| 250 | s->max_devices = MPTSAS_NUM_PORTS; | ||
| 251 | |||
| 252 | - s->request_bh = qemu_bh_new(mptsas_fetch_requests, s); | ||
| 253 | + s->request_bh = qemu_bh_new_guarded(mptsas_fetch_requests, s, | ||
| 254 | + &DEVICE(dev)->mem_reentrancy_guard); | ||
| 255 | |||
| 256 | scsi_bus_init(&s->bus, sizeof(s->bus), &dev->qdev, &mptsas_scsi_info); | ||
| 257 | } | ||
| 258 | diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c | ||
| 259 | index 2b5e9dca3..54b9a8ce9 100644 | ||
| 260 | --- a/hw/scsi/scsi-bus.c | ||
| 261 | +++ b/hw/scsi/scsi-bus.c | ||
| 262 | @@ -192,7 +192,8 @@ static void scsi_dma_restart_cb(void *opaque, bool running, RunState state) | ||
| 263 | AioContext *ctx = blk_get_aio_context(s->conf.blk); | ||
| 264 | /* The reference is dropped in scsi_dma_restart_bh.*/ | ||
| 265 | object_ref(OBJECT(s)); | ||
| 266 | - s->bh = aio_bh_new(ctx, scsi_dma_restart_bh, s); | ||
| 267 | + s->bh = aio_bh_new_guarded(ctx, scsi_dma_restart_bh, s, | ||
| 268 | + &DEVICE(s)->mem_reentrancy_guard); | ||
| 269 | qemu_bh_schedule(s->bh); | ||
| 270 | } | ||
| 271 | } | ||
| 272 | diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c | ||
| 273 | index 4d9969f3b..d5c6293a2 100644 | ||
| 274 | --- a/hw/scsi/vmw_pvscsi.c | ||
| 275 | +++ b/hw/scsi/vmw_pvscsi.c | ||
| 276 | @@ -1184,7 +1184,8 @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp) | ||
| 277 | pcie_endpoint_cap_init(pci_dev, PVSCSI_EXP_EP_OFFSET); | ||
| 278 | } | ||
| 279 | |||
| 280 | - s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s); | ||
| 281 | + s->completion_worker = qemu_bh_new_guarded(pvscsi_process_completion_queue, s, | ||
| 282 | + &DEVICE(pci_dev)->mem_reentrancy_guard); | ||
| 283 | |||
| 284 | scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(pci_dev), &pvscsi_scsi_info); | ||
| 285 | /* override default SCSI bus hotplug-handler, with pvscsi's one */ | ||
| 286 | diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c | ||
| 287 | index 599d6b52a..a36a7c301 100644 | ||
| 288 | --- a/hw/usb/dev-uas.c | ||
| 289 | +++ b/hw/usb/dev-uas.c | ||
| 290 | @@ -935,7 +935,8 @@ static void usb_uas_realize(USBDevice *dev, Error **errp) | ||
| 291 | |||
| 292 | QTAILQ_INIT(&uas->results); | ||
| 293 | QTAILQ_INIT(&uas->requests); | ||
| 294 | - uas->status_bh = qemu_bh_new(usb_uas_send_status_bh, uas); | ||
| 295 | + uas->status_bh = qemu_bh_new_guarded(usb_uas_send_status_bh, uas, | ||
| 296 | + &d->mem_reentrancy_guard); | ||
| 297 | |||
| 298 | dev->flags |= (1 << USB_DEV_FLAG_IS_SCSI_STORAGE); | ||
| 299 | scsi_bus_init(&uas->bus, sizeof(uas->bus), DEVICE(dev), &usb_uas_scsi_info); | ||
| 300 | diff --git a/hw/usb/hcd-dwc2.c b/hw/usb/hcd-dwc2.c | ||
| 301 | index 8755e9cbb..a0c4e782b 100644 | ||
| 302 | --- a/hw/usb/hcd-dwc2.c | ||
| 303 | +++ b/hw/usb/hcd-dwc2.c | ||
| 304 | @@ -1364,7 +1364,8 @@ static void dwc2_realize(DeviceState *dev, Error **errp) | ||
| 305 | s->fi = USB_FRMINTVL - 1; | ||
| 306 | s->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_frame_boundary, s); | ||
| 307 | s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_work_timer, s); | ||
| 308 | - s->async_bh = qemu_bh_new(dwc2_work_bh, s); | ||
| 309 | + s->async_bh = qemu_bh_new_guarded(dwc2_work_bh, s, | ||
| 310 | + &dev->mem_reentrancy_guard); | ||
| 311 | |||
| 312 | sysbus_init_irq(sbd, &s->irq); | ||
| 313 | } | ||
| 314 | diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c | ||
| 315 | index 33a8a377b..7b0538810 100644 | ||
| 316 | --- a/hw/usb/hcd-ehci.c | ||
| 317 | +++ b/hw/usb/hcd-ehci.c | ||
| 318 | @@ -2530,7 +2530,8 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp) | ||
| 319 | } | ||
| 320 | |||
| 321 | s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ehci_work_timer, s); | ||
| 322 | - s->async_bh = qemu_bh_new(ehci_work_bh, s); | ||
| 323 | + s->async_bh = qemu_bh_new_guarded(ehci_work_bh, s, | ||
| 324 | + &dev->mem_reentrancy_guard); | ||
| 325 | s->device = dev; | ||
| 326 | |||
| 327 | s->vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s); | ||
| 328 | diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c | ||
| 329 | index d1b5657d7..ef967c42a 100644 | ||
| 330 | --- a/hw/usb/hcd-uhci.c | ||
| 331 | +++ b/hw/usb/hcd-uhci.c | ||
| 332 | @@ -1193,7 +1193,7 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp) | ||
| 333 | USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); | ||
| 334 | } | ||
| 335 | } | ||
| 336 | - s->bh = qemu_bh_new(uhci_bh, s); | ||
| 337 | + s->bh = qemu_bh_new_guarded(uhci_bh, s, &DEVICE(dev)->mem_reentrancy_guard); | ||
| 338 | s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, uhci_frame_timer, s); | ||
| 339 | s->num_ports_vmstate = NB_PORTS; | ||
| 340 | QTAILQ_INIT(&s->queues); | ||
| 341 | diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c | ||
| 342 | index d0d46dd0a..09b961116 100644 | ||
| 343 | --- a/hw/usb/host-libusb.c | ||
| 344 | +++ b/hw/usb/host-libusb.c | ||
| 345 | @@ -1141,7 +1141,8 @@ static void usb_host_nodev_bh(void *opaque) | ||
| 346 | static void usb_host_nodev(USBHostDevice *s) | ||
| 347 | { | ||
| 348 | if (!s->bh_nodev) { | ||
| 349 | - s->bh_nodev = qemu_bh_new(usb_host_nodev_bh, s); | ||
| 350 | + s->bh_nodev = qemu_bh_new_guarded(usb_host_nodev_bh, s, | ||
| 351 | + &DEVICE(s)->mem_reentrancy_guard); | ||
| 352 | } | ||
| 353 | qemu_bh_schedule(s->bh_nodev); | ||
| 354 | } | ||
| 355 | @@ -1739,7 +1740,8 @@ static int usb_host_post_load(void *opaque, int version_id) | ||
| 356 | USBHostDevice *dev = opaque; | ||
| 357 | |||
| 358 | if (!dev->bh_postld) { | ||
| 359 | - dev->bh_postld = qemu_bh_new(usb_host_post_load_bh, dev); | ||
| 360 | + dev->bh_postld = qemu_bh_new_guarded(usb_host_post_load_bh, dev, | ||
| 361 | + &DEVICE(dev)->mem_reentrancy_guard); | ||
| 362 | } | ||
| 363 | qemu_bh_schedule(dev->bh_postld); | ||
| 364 | dev->bh_postld_pending = true; | ||
| 365 | diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c | ||
| 366 | index 5f0ef9cb3..59cd3cd7c 100644 | ||
| 367 | --- a/hw/usb/redirect.c | ||
| 368 | +++ b/hw/usb/redirect.c | ||
| 369 | @@ -1437,8 +1437,10 @@ static void usbredir_realize(USBDevice *udev, Error **errp) | ||
| 370 | } | ||
| 371 | } | ||
| 372 | |||
| 373 | - dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev); | ||
| 374 | - dev->device_reject_bh = qemu_bh_new(usbredir_device_reject_bh, dev); | ||
| 375 | + dev->chardev_close_bh = qemu_bh_new_guarded(usbredir_chardev_close_bh, dev, | ||
| 376 | + &DEVICE(dev)->mem_reentrancy_guard); | ||
| 377 | + dev->device_reject_bh = qemu_bh_new_guarded(usbredir_device_reject_bh, dev, | ||
| 378 | + &DEVICE(dev)->mem_reentrancy_guard); | ||
| 379 | dev->attach_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, usbredir_do_attach, dev); | ||
| 380 | |||
| 381 | packet_id_queue_init(&dev->cancelled, dev, "cancelled"); | ||
| 382 | diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c | ||
| 383 | index 0f7369e7e..dec91294a 100644 | ||
| 384 | --- a/hw/usb/xen-usb.c | ||
| 385 | +++ b/hw/usb/xen-usb.c | ||
| 386 | @@ -1021,7 +1021,8 @@ static void usbback_alloc(struct XenLegacyDevice *xendev) | ||
| 387 | |||
| 388 | QTAILQ_INIT(&usbif->req_free_q); | ||
| 389 | QSIMPLEQ_INIT(&usbif->hotplug_q); | ||
| 390 | - usbif->bh = qemu_bh_new(usbback_bh, usbif); | ||
| 391 | + usbif->bh = qemu_bh_new_guarded(usbback_bh, usbif, | ||
| 392 | + &DEVICE(xendev)->mem_reentrancy_guard); | ||
| 393 | } | ||
| 394 | |||
| 395 | static int usbback_free(struct XenLegacyDevice *xendev) | ||
| 396 | diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c | ||
| 397 | index 9a4f491b5..f503572e2 100644 | ||
| 398 | --- a/hw/virtio/virtio-balloon.c | ||
| 399 | +++ b/hw/virtio/virtio-balloon.c | ||
| 400 | @@ -917,8 +917,9 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) | ||
| 401 | precopy_add_notifier(&s->free_page_hint_notify); | ||
| 402 | |||
| 403 | object_ref(OBJECT(s->iothread)); | ||
| 404 | - s->free_page_bh = aio_bh_new(iothread_get_aio_context(s->iothread), | ||
| 405 | - virtio_ballloon_get_free_page_hints, s); | ||
| 406 | + s->free_page_bh = aio_bh_new_guarded(iothread_get_aio_context(s->iothread), | ||
| 407 | + virtio_ballloon_get_free_page_hints, s, | ||
| 408 | + &dev->mem_reentrancy_guard); | ||
| 409 | } | ||
| 410 | |||
| 411 | if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_REPORTING)) { | ||
| 412 | diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c | ||
| 413 | index 274c7b4de..cb3e6ed0e 100644 | ||
| 414 | --- a/hw/virtio/virtio-crypto.c | ||
| 415 | +++ b/hw/virtio/virtio-crypto.c | ||
| 416 | @@ -822,7 +822,8 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp) | ||
| 417 | vcrypto->vqs[i].dataq = | ||
| 418 | virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh); | ||
| 419 | vcrypto->vqs[i].dataq_bh = | ||
| 420 | - qemu_bh_new(virtio_crypto_dataq_bh, &vcrypto->vqs[i]); | ||
| 421 | + qemu_bh_new_guarded(virtio_crypto_dataq_bh, &vcrypto->vqs[i], | ||
| 422 | + &dev->mem_reentrancy_guard); | ||
| 423 | vcrypto->vqs[i].vcrypto = vcrypto; | ||
| 424 | } | ||
| 425 | |||
| 426 | -- | ||
| 427 | 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 @@ | |||
| 1 | From ec0504b989ca61e03636384d3602b7bf07ffe4da Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 3 | Date: Mon, 27 May 2024 11:52:53 +0000 | ||
| 4 | Subject: [PATCH] hw/virtio: Introduce virtio_bh_new_guarded() helper | ||
| 5 | |||
| 6 | Introduce virtio_bh_new_guarded(), similar to qemu_bh_new_guarded() | ||
| 7 | but using the transport memory guard, instead of the device one | ||
| 8 | (there can only be one virtio device per virtio bus). | ||
| 9 | |||
| 10 | Inspired-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 11 | Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 12 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
| 13 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 14 | Reviewed-by: Michael S. Tsirkin <mst@redhat.com> | ||
| 15 | Message-Id: <20240409105537.18308-2-philmd@linaro.org> | ||
| 16 | |||
| 17 | CVE: CVE-2024-3446 | ||
| 18 | Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/ec0504b989ca61e03636384d3602b7bf07ffe4da] | ||
| 19 | |||
| 20 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
| 21 | --- | ||
| 22 | hw/virtio/virtio.c | 10 ++++++++++ | ||
| 23 | include/hw/virtio/virtio.h | 7 +++++++ | ||
| 24 | 2 files changed, 17 insertions(+) | ||
| 25 | |||
| 26 | diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c | ||
| 27 | index e11a8a0db..be0b3ff9d 100644 | ||
| 28 | --- a/hw/virtio/virtio.c | ||
| 29 | +++ b/hw/virtio/virtio.c | ||
| 30 | @@ -3876,3 +3876,13 @@ static void virtio_register_types(void) | ||
| 31 | } | ||
| 32 | |||
| 33 | type_init(virtio_register_types) | ||
| 34 | + | ||
| 35 | +QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev, | ||
| 36 | + QEMUBHFunc *cb, void *opaque, | ||
| 37 | + const char *name) | ||
| 38 | +{ | ||
| 39 | + DeviceState *transport = qdev_get_parent_bus(dev)->parent; | ||
| 40 | + | ||
| 41 | + return qemu_bh_new_full(cb, opaque, name, | ||
| 42 | + &transport->mem_reentrancy_guard); | ||
| 43 | +} | ||
| 44 | diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h | ||
| 45 | index 8bab9cfb7..731c631a8 100644 | ||
| 46 | --- a/include/hw/virtio/virtio.h | ||
| 47 | +++ b/include/hw/virtio/virtio.h | ||
| 48 | @@ -22,6 +22,7 @@ | ||
| 49 | #include "standard-headers/linux/virtio_config.h" | ||
| 50 | #include "standard-headers/linux/virtio_ring.h" | ||
| 51 | #include "qom/object.h" | ||
| 52 | +#include "block/aio.h" | ||
| 53 | |||
| 54 | /* A guest should never accept this. It implies negotiation is broken. */ | ||
| 55 | #define VIRTIO_F_BAD_FEATURE 30 | ||
| 56 | @@ -397,4 +398,10 @@ static inline bool virtio_device_disabled(VirtIODevice *vdev) | ||
| 57 | bool virtio_legacy_allowed(VirtIODevice *vdev); | ||
| 58 | bool virtio_legacy_check_disabled(VirtIODevice *vdev); | ||
| 59 | |||
| 60 | +QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev, | ||
| 61 | + QEMUBHFunc *cb, void *opaque, | ||
| 62 | + const char *name); | ||
| 63 | +#define virtio_bh_new_guarded(dev, cb, opaque) \ | ||
| 64 | + virtio_bh_new_guarded_full((dev), (cb), (opaque), (stringify(cb))) | ||
| 65 | + | ||
| 66 | #endif | ||
| 67 | -- | ||
| 68 | 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 @@ | |||
| 1 | From ba28e0ff4d95b56dc334aac2730ab3651ffc3132 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 3 | Date: Tue, 28 May 2024 05:50:35 +0000 | ||
| 4 | Subject: [PATCH] virtio-gpu: Protect from DMA re-entrancy bugs | ||
| 5 | |||
| 6 | Replace qemu_bh_new_guarded() by virtio_bh_new_guarded() | ||
| 7 | so the bus and device use the same guard. Otherwise the | ||
| 8 | DMA-reentrancy protection can be bypassed: | ||
| 9 | |||
| 10 | $ cat << EOF | qemu-system-i386 -display none -nodefaults \ | ||
| 11 | -machine q35,accel=qtest \ | ||
| 12 | -m 512M \ | ||
| 13 | -device virtio-gpu \ | ||
| 14 | -qtest stdio | ||
| 15 | |||
| 16 | outl 0xcf8 0x80000820 | ||
| 17 | outl 0xcfc 0xe0004000 | ||
| 18 | outl 0xcf8 0x80000804 | ||
| 19 | outw 0xcfc 0x06 | ||
| 20 | write 0xe0004030 0x4 0x024000e0 | ||
| 21 | write 0xe0004028 0x1 0xff | ||
| 22 | write 0xe0004020 0x4 0x00009300 | ||
| 23 | write 0xe000401c 0x1 0x01 | ||
| 24 | write 0x101 0x1 0x04 | ||
| 25 | write 0x103 0x1 0x1c | ||
| 26 | write 0x9301c8 0x1 0x18 | ||
| 27 | write 0x105 0x1 0x1c | ||
| 28 | write 0x107 0x1 0x1c | ||
| 29 | write 0x109 0x1 0x1c | ||
| 30 | write 0x10b 0x1 0x00 | ||
| 31 | write 0x10d 0x1 0x00 | ||
| 32 | write 0x10f 0x1 0x00 | ||
| 33 | write 0x111 0x1 0x00 | ||
| 34 | write 0x113 0x1 0x00 | ||
| 35 | write 0x115 0x1 0x00 | ||
| 36 | write 0x117 0x1 0x00 | ||
| 37 | write 0x119 0x1 0x00 | ||
| 38 | write 0x11b 0x1 0x00 | ||
| 39 | write 0x11d 0x1 0x00 | ||
| 40 | write 0x11f 0x1 0x00 | ||
| 41 | write 0x121 0x1 0x00 | ||
| 42 | write 0x123 0x1 0x00 | ||
| 43 | write 0x125 0x1 0x00 | ||
| 44 | write 0x127 0x1 0x00 | ||
| 45 | write 0x129 0x1 0x00 | ||
| 46 | write 0x12b 0x1 0x00 | ||
| 47 | write 0x12d 0x1 0x00 | ||
| 48 | write 0x12f 0x1 0x00 | ||
| 49 | write 0x131 0x1 0x00 | ||
| 50 | write 0x133 0x1 0x00 | ||
| 51 | write 0x135 0x1 0x00 | ||
| 52 | write 0x137 0x1 0x00 | ||
| 53 | write 0x139 0x1 0x00 | ||
| 54 | write 0xe0007003 0x1 0x00 | ||
| 55 | EOF | ||
| 56 | ... | ||
| 57 | ================================================================= | ||
| 58 | ==276099==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d000011178 | ||
| 59 | at pc 0x562cc3b736c7 bp 0x7ffed49dee60 sp 0x7ffed49dee58 | ||
| 60 | READ of size 8 at 0x60d000011178 thread T0 | ||
| 61 | #0 0x562cc3b736c6 in virtio_gpu_ctrl_response hw/display/virtio-gpu.c:180:42 | ||
| 62 | #1 0x562cc3b7c40b in virtio_gpu_ctrl_response_nodata hw/display/virtio-gpu.c:192:5 | ||
| 63 | #2 0x562cc3b7c40b in virtio_gpu_simple_process_cmd hw/display/virtio-gpu.c:1015:13 | ||
| 64 | #3 0x562cc3b82873 in virtio_gpu_process_cmdq hw/display/virtio-gpu.c:1050:9 | ||
| 65 | #4 0x562cc4a85514 in aio_bh_call util/async.c:169:5 | ||
| 66 | #5 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13 | ||
| 67 | #6 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5 | ||
| 68 | #7 0x562cc4a8a2da in aio_ctx_dispatch util/async.c:358:5 | ||
| 69 | #8 0x7f36840547a8 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x547a8) | ||
| 70 | #9 0x562cc4a8b753 in glib_pollfds_poll util/main-loop.c:290:9 | ||
| 71 | #10 0x562cc4a8b753 in os_host_main_loop_wait util/main-loop.c:313:5 | ||
| 72 | #11 0x562cc4a8b753 in main_loop_wait util/main-loop.c:592:11 | ||
| 73 | #12 0x562cc3938186 in qemu_main_loop system/runstate.c:782:9 | ||
| 74 | #13 0x562cc43b7af5 in qemu_default_main system/main.c:37:14 | ||
| 75 | #14 0x7f3683a6c189 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 | ||
| 76 | #15 0x7f3683a6c244 in __libc_start_main csu/../csu/libc-start.c:381:3 | ||
| 77 | #16 0x562cc2a58ac0 in _start (qemu-system-i386+0x231bac0) | ||
| 78 | |||
| 79 | 0x60d000011178 is located 56 bytes inside of 136-byte region [0x60d000011140,0x60d0000111c8) | ||
| 80 | freed by thread T0 here: | ||
| 81 | #0 0x562cc2adb662 in __interceptor_free (qemu-system-i386+0x239e662) | ||
| 82 | #1 0x562cc3b86b21 in virtio_gpu_reset hw/display/virtio-gpu.c:1524:9 | ||
| 83 | #2 0x562cc416e20e in virtio_reset hw/virtio/virtio.c:2145:9 | ||
| 84 | #3 0x562cc37c5644 in virtio_pci_reset hw/virtio/virtio-pci.c:2249:5 | ||
| 85 | #4 0x562cc4233758 in memory_region_write_accessor system/memory.c:497:5 | ||
| 86 | #5 0x562cc4232eea in access_with_adjusted_size system/memory.c:573:18 | ||
| 87 | |||
| 88 | previously allocated by thread T0 here: | ||
| 89 | #0 0x562cc2adb90e in malloc (qemu-system-i386+0x239e90e) | ||
| 90 | #1 0x7f368405a678 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5a678) | ||
| 91 | #2 0x562cc4163ffc in virtqueue_split_pop hw/virtio/virtio.c:1612:12 | ||
| 92 | #3 0x562cc4163ffc in virtqueue_pop hw/virtio/virtio.c:1783:16 | ||
| 93 | #4 0x562cc3b91a95 in virtio_gpu_handle_ctrl hw/display/virtio-gpu.c:1112:15 | ||
| 94 | #5 0x562cc4a85514 in aio_bh_call util/async.c:169:5 | ||
| 95 | #6 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13 | ||
| 96 | #7 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5 | ||
| 97 | |||
| 98 | SUMMARY: AddressSanitizer: heap-use-after-free hw/display/virtio-gpu.c:180:42 in virtio_gpu_ctrl_response | ||
| 99 | |||
| 100 | With this change, the same reproducer triggers: | ||
| 101 | |||
| 102 | qemu-system-i386: warning: Blocked re-entrant IO on MemoryRegion: virtio-pci-common-virtio-gpu at addr: 0x6 | ||
| 103 | |||
| 104 | Fixes: CVE-2024-3446 | ||
| 105 | Cc: qemu-stable@nongnu.org | ||
| 106 | Reported-by: Alexander Bulekov <alxndr@bu.edu> | ||
| 107 | Reported-by: Yongkang Jia <kangel@zju.edu.cn> | ||
| 108 | Reported-by: Xiao Lei <nop.leixiao@gmail.com> | ||
| 109 | Reported-by: Yiming Tao <taoym@zju.edu.cn> | ||
| 110 | Buglink: https://bugs.launchpad.net/qemu/+bug/1888606 | ||
| 111 | |||
| 112 | Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 113 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
| 114 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 115 | Reviewed-by: Michael S. Tsirkin <mst@redhat.com> | ||
| 116 | Message-Id: <20240409105537.18308-3-philmd@linaro.org> | ||
| 117 | |||
| 118 | CVE: CVE-2024-3446 | ||
| 119 | Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/ba28e0ff4d95b56dc334aac2730ab3651ffc3132] | ||
| 120 | |||
| 121 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
| 122 | --- | ||
| 123 | hw/display/virtio-gpu.c | 6 ++---- | ||
| 124 | 1 file changed, 2 insertions(+), 4 deletions(-) | ||
| 125 | |||
| 126 | diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c | ||
| 127 | index 316469ab7..5719ef6f1 100644 | ||
| 128 | --- a/hw/display/virtio-gpu.c | ||
| 129 | +++ b/hw/display/virtio-gpu.c | ||
| 130 | @@ -1334,10 +1334,8 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) | ||
| 131 | |||
| 132 | g->ctrl_vq = virtio_get_queue(vdev, 0); | ||
| 133 | g->cursor_vq = virtio_get_queue(vdev, 1); | ||
| 134 | - g->ctrl_bh = qemu_bh_new_guarded(virtio_gpu_ctrl_bh, g, | ||
| 135 | - &qdev->mem_reentrancy_guard); | ||
| 136 | - g->cursor_bh = qemu_bh_new_guarded(virtio_gpu_cursor_bh, g, | ||
| 137 | - &qdev->mem_reentrancy_guard); | ||
| 138 | + g->ctrl_bh = virtio_bh_new_guarded(qdev, virtio_gpu_ctrl_bh, g); | ||
| 139 | + g->cursor_bh = virtio_bh_new_guarded(qdev, virtio_gpu_cursor_bh, g); | ||
| 140 | QTAILQ_INIT(&g->reslist); | ||
| 141 | QTAILQ_INIT(&g->cmdq); | ||
| 142 | QTAILQ_INIT(&g->fenceq); | ||
| 143 | -- | ||
| 144 | 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 @@ | |||
| 1 | From b4295bff25f7b50de1d9cc94a9c6effd40056bca Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 3 | Date: Tue, 28 May 2024 06:55:51 +0000 | ||
| 4 | Subject: [PATCH] hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs | ||
| 5 | |||
| 6 | Replace qemu_bh_new_guarded() by virtio_bh_new_guarded() | ||
| 7 | so the bus and device use the same guard. Otherwise the | ||
| 8 | DMA-reentrancy protection can be bypassed. | ||
| 9 | |||
| 10 | Fixes: CVE-2024-3446 | ||
| 11 | Cc: qemu-stable@nongnu.org | ||
| 12 | Suggested-by: Alexander Bulekov <alxndr@bu.edu> | ||
| 13 | Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 14 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
| 15 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 16 | Reviewed-by: Michael S. Tsirkin <mst@redhat.com> | ||
| 17 | Message-Id: <20240409105537.18308-4-philmd@linaro.org> | ||
| 18 | |||
| 19 | CVE: CVE-2024-3446 | ||
| 20 | Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/b4295bff25f7b50de1d9cc94a9c6effd40056bca] | ||
| 21 | |||
| 22 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
| 23 | --- | ||
| 24 | hw/char/virtio-serial-bus.c | 3 +-- | ||
| 25 | 1 file changed, 1 insertion(+), 2 deletions(-) | ||
| 26 | |||
| 27 | diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c | ||
| 28 | index f18124b15..791b7ac59 100644 | ||
| 29 | --- a/hw/char/virtio-serial-bus.c | ||
| 30 | +++ b/hw/char/virtio-serial-bus.c | ||
| 31 | @@ -985,8 +985,7 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp) | ||
| 32 | return; | ||
| 33 | } | ||
| 34 | |||
| 35 | - port->bh = qemu_bh_new_guarded(flush_queued_data_bh, port, | ||
| 36 | - &dev->mem_reentrancy_guard); | ||
| 37 | + port->bh = virtio_bh_new_guarded(dev, flush_queued_data_bh, port); | ||
| 38 | port->elem = NULL; | ||
| 39 | } | ||
| 40 | |||
| 41 | -- | ||
| 42 | 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 @@ | |||
| 1 | From f4729ec39ad97a42ceaa7b5697f84f440ea6e5dc Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 3 | Date: Tue, 28 May 2024 09:22:58 +0000 | ||
| 4 | Subject: [PATCH] hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs | ||
| 5 | |||
| 6 | Replace qemu_bh_new_guarded() by virtio_bh_new_guarded() | ||
| 7 | so the bus and device use the same guard. Otherwise the | ||
| 8 | DMA-reentrancy protection can be bypassed. | ||
| 9 | |||
| 10 | Fixes: CVE-2024-3446 | ||
| 11 | Cc: qemu-stable@nongnu.org | ||
| 12 | Suggested-by: Alexander Bulekov <alxndr@bu.edu> | ||
| 13 | Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 14 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
| 15 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 16 | Reviewed-by: Michael S. Tsirkin <mst@redhat.com> | ||
| 17 | Message-Id: <20240409105537.18308-5-philmd@linaro.org> | ||
| 18 | |||
| 19 | CVE: CVE-2024-3446 | ||
| 20 | Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/f4729ec39ad97a42ceaa7b5697f84f440ea6e5dc] | ||
| 21 | |||
| 22 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
| 23 | --- | ||
| 24 | hw/virtio/virtio-crypto.c | 4 ++-- | ||
| 25 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
| 26 | |||
| 27 | diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c | ||
| 28 | index cb3e6ed0e..930a8418f 100644 | ||
| 29 | --- a/hw/virtio/virtio-crypto.c | ||
| 30 | +++ b/hw/virtio/virtio-crypto.c | ||
| 31 | @@ -822,8 +822,8 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp) | ||
| 32 | vcrypto->vqs[i].dataq = | ||
| 33 | virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh); | ||
| 34 | vcrypto->vqs[i].dataq_bh = | ||
| 35 | - qemu_bh_new_guarded(virtio_crypto_dataq_bh, &vcrypto->vqs[i], | ||
| 36 | - &dev->mem_reentrancy_guard); | ||
| 37 | + virtio_bh_new_guarded(dev, virtio_crypto_dataq_bh, | ||
| 38 | + &vcrypto->vqs[i]); | ||
| 39 | vcrypto->vqs[i].vcrypto = vcrypto; | ||
| 40 | } | ||
| 41 | |||
| 42 | -- | ||
| 43 | 2.40.0 | ||
