hw/virtio-rng: Fix host use-after-free (CVE-2026-50624)
Fix a heap-use-after-free in the virtio-rng frontend when a delayed rng-random backend completion arrives after the virtio-rng device has been hot-unplugged. Fixes: CVE-2026-50624 Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3917 Reported-by: Jia Jia <physicalmtea@gmail.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Signed-off-by: Laurent Vivier <lvivier@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-ID: <20260724094931.3005968-1-lvivier@redhat.com>
Laurent Vivier committed
Jul 24, 2026 at 11:49 UTC
0be94d8d9c28e6b7235b34133d057090fe93be6c
3 files changed
+32
backends/rng.c
+16
@@ -68,6 +68,22 @@ static void rng_backend_free_request(RngRequest *req)
68
g_free(req);
69
}
70
71
+void rng_backend_cancel_requests(RngBackend *s,
72
+ EntropyReceiveFunc *receive_entropy,
73
+ const void *opaque)
74
+{
75
+ RngRequest *req, *next;
76
+
77
+ QSIMPLEQ_FOREACH_SAFE(req, &s->requests, next, next) {
78
+ if (req->receive_entropy != receive_entropy ||
79
+ req->opaque != opaque) {
80
+ continue;
81
+ }
82
+ QSIMPLEQ_REMOVE(&s->requests, req, RngRequest, next);
83
+ rng_backend_free_request(req);
84
+ }
85
+}
86
+
87
static void rng_backend_free_requests(RngBackend *s)
88
{
89
RngRequest *req, *next;
hw/virtio/virtio-rng.c
+2
@@ -234,6 +234,8 @@ static void virtio_rng_device_unrealize(DeviceState *dev)
234
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
235
VirtIORNG *vrng = VIRTIO_RNG(dev);
236
237
+ rng_backend_cancel_requests(vrng->rng, chr_read, vrng);
238
+
239
qemu_del_vm_change_state_handler(vrng->vmstate);
240
timer_free(vrng->rate_limit_timer);
241
virtio_del_queue(vdev, 0);
include/system/rng.h
+14
@@ -86,4 +86,18 @@ void rng_backend_request_entropy(RngBackend *s, size_t size,
86
* deleted.
87
*/
88
void rng_backend_finalize_request(RngBackend *s, RngRequest *req);
89
+
90
+/**
91
+ * rng_backend_cancel_requests:
92
+ * @s: the backend that created the request
93
+ * @receive_entropy: the function invoked when entropy is available
94
+ * @opaque: data passed to @receive_entropy
95
+ *
96
+ * This function is used by the front-end to cancel all requests to a
97
+ * given backend. Requests to cancel are identified by the receive_entropy
98
+ * function and the data passed to the function.
99
+ */
100
+void rng_backend_cancel_requests(RngBackend *s,
101
+ EntropyReceiveFunc *receive_entropy,
102
+ const void *opaque);
103
#endif