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 | ||