@samitouri / QOSamiQemu / commits / 0be94d8d9c

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