All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] hw/virtio-rng: Fix host use-after-free (CVE-2026-50624)
@ 2026-07-08  6:39 Laurent Vivier
  2026-07-24  7:43 ` Laurent Vivier
  2026-07-24  8:31 ` Philippe Mathieu-Daudé
  0 siblings, 2 replies; 4+ messages in thread
From: Laurent Vivier @ 2026-07-08  6:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael S. Tsirkin, Amit Shah, Laurent Vivier, Jia Jia

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>
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 backends/rng.c         | 16 ++++++++++++++++
 hw/virtio/virtio-rng.c |  2 ++
 include/system/rng.h   | 14 ++++++++++++++
 3 files changed, 32 insertions(+)

diff --git a/backends/rng.c b/backends/rng.c
index ab94dfea850a..182269be4a83 100644
--- a/backends/rng.c
+++ b/backends/rng.c
@@ -68,6 +68,22 @@ static void rng_backend_free_request(RngRequest *req)
     g_free(req);
 }
 
+void rng_backend_cancel_request_entropy(RngBackend *s,
+                                        EntropyReceiveFunc *receive_entropy,
+                                        void *opaque)
+{
+    RngRequest *req, *next;
+
+    QSIMPLEQ_FOREACH_SAFE(req, &s->requests, next, next) {
+        if (req->receive_entropy != receive_entropy ||
+            req->opaque != opaque) {
+            continue;
+        }
+        QSIMPLEQ_REMOVE(&s->requests, req, RngRequest, next);
+        rng_backend_free_request(req);
+    }
+}
+
 static void rng_backend_free_requests(RngBackend *s)
 {
     RngRequest *req, *next;
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index 66690a34dc97..a77ea5ab1385 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -234,6 +234,8 @@ static void virtio_rng_device_unrealize(DeviceState *dev)
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
     VirtIORNG *vrng = VIRTIO_RNG(dev);
 
+    rng_backend_cancel_request_entropy(vrng->rng, chr_read, vrng);
+
     qemu_del_vm_change_state_handler(vrng->vmstate);
     timer_free(vrng->rate_limit_timer);
     virtio_del_queue(vdev, 0);
diff --git a/include/system/rng.h b/include/system/rng.h
index e383f87d20b2..5b0893eb2bd5 100644
--- a/include/system/rng.h
+++ b/include/system/rng.h
@@ -86,4 +86,18 @@ void rng_backend_request_entropy(RngBackend *s, size_t size,
  * deleted.
  */
 void rng_backend_finalize_request(RngBackend *s, RngRequest *req);
+
+/**
+ * rng_backend_cancel_request_entropy:
+ * @s: the backend that created the request
+ * @receive_entropy: the function invoked when entropy is available
+ * @opaque: data passed to @receive_entropy
+ *
+ * This function is used by the front-end to cancel all requests to a
+ * given backend. Requests to cancel are identified by the receive_entropy
+ * function and the data passed to the function.
+ */
+void rng_backend_cancel_request_entropy(RngBackend *s,
+                                        EntropyReceiveFunc *receive_entropy,
+                                        void *opaque);
 #endif
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] hw/virtio-rng: Fix host use-after-free (CVE-2026-50624)
  2026-07-08  6:39 [PATCH] hw/virtio-rng: Fix host use-after-free (CVE-2026-50624) Laurent Vivier
@ 2026-07-24  7:43 ` Laurent Vivier
  2026-07-24  8:31 ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 4+ messages in thread
From: Laurent Vivier @ 2026-07-24  7:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael S. Tsirkin, Amit Shah, Jia Jia


Ping

On 7/8/26 08:39, Laurent Vivier wrote:
> 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>
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---
>   backends/rng.c         | 16 ++++++++++++++++
>   hw/virtio/virtio-rng.c |  2 ++
>   include/system/rng.h   | 14 ++++++++++++++
>   3 files changed, 32 insertions(+)
> 
> diff --git a/backends/rng.c b/backends/rng.c
> index ab94dfea850a..182269be4a83 100644
> --- a/backends/rng.c
> +++ b/backends/rng.c
> @@ -68,6 +68,22 @@ static void rng_backend_free_request(RngRequest *req)
>       g_free(req);
>   }
>   
> +void rng_backend_cancel_request_entropy(RngBackend *s,
> +                                        EntropyReceiveFunc *receive_entropy,
> +                                        void *opaque)
> +{
> +    RngRequest *req, *next;
> +
> +    QSIMPLEQ_FOREACH_SAFE(req, &s->requests, next, next) {
> +        if (req->receive_entropy != receive_entropy ||
> +            req->opaque != opaque) {
> +            continue;
> +        }
> +        QSIMPLEQ_REMOVE(&s->requests, req, RngRequest, next);
> +        rng_backend_free_request(req);
> +    }
> +}
> +
>   static void rng_backend_free_requests(RngBackend *s)
>   {
>       RngRequest *req, *next;
> diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
> index 66690a34dc97..a77ea5ab1385 100644
> --- a/hw/virtio/virtio-rng.c
> +++ b/hw/virtio/virtio-rng.c
> @@ -234,6 +234,8 @@ static void virtio_rng_device_unrealize(DeviceState *dev)
>       VirtIODevice *vdev = VIRTIO_DEVICE(dev);
>       VirtIORNG *vrng = VIRTIO_RNG(dev);
>   
> +    rng_backend_cancel_request_entropy(vrng->rng, chr_read, vrng);
> +
>       qemu_del_vm_change_state_handler(vrng->vmstate);
>       timer_free(vrng->rate_limit_timer);
>       virtio_del_queue(vdev, 0);
> diff --git a/include/system/rng.h b/include/system/rng.h
> index e383f87d20b2..5b0893eb2bd5 100644
> --- a/include/system/rng.h
> +++ b/include/system/rng.h
> @@ -86,4 +86,18 @@ void rng_backend_request_entropy(RngBackend *s, size_t size,
>    * deleted.
>    */
>   void rng_backend_finalize_request(RngBackend *s, RngRequest *req);
> +
> +/**
> + * rng_backend_cancel_request_entropy:
> + * @s: the backend that created the request
> + * @receive_entropy: the function invoked when entropy is available
> + * @opaque: data passed to @receive_entropy
> + *
> + * This function is used by the front-end to cancel all requests to a
> + * given backend. Requests to cancel are identified by the receive_entropy
> + * function and the data passed to the function.
> + */
> +void rng_backend_cancel_request_entropy(RngBackend *s,
> +                                        EntropyReceiveFunc *receive_entropy,
> +                                        void *opaque);
>   #endif



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] hw/virtio-rng: Fix host use-after-free (CVE-2026-50624)
  2026-07-08  6:39 [PATCH] hw/virtio-rng: Fix host use-after-free (CVE-2026-50624) Laurent Vivier
  2026-07-24  7:43 ` Laurent Vivier
@ 2026-07-24  8:31 ` Philippe Mathieu-Daudé
  2026-07-24  9:29   ` Laurent Vivier
  1 sibling, 1 reply; 4+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-24  8:31 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel
  Cc: Michael S. Tsirkin, Amit Shah, Jia Jia, qemu-ppc

On 8/7/26 08:39, Laurent Vivier wrote:
> 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>
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---
>   backends/rng.c         | 16 ++++++++++++++++
>   hw/virtio/virtio-rng.c |  2 ++
>   include/system/rng.h   | 14 ++++++++++++++
>   3 files changed, 32 insertions(+)
> 
> diff --git a/backends/rng.c b/backends/rng.c
> index ab94dfea850a..182269be4a83 100644
> --- a/backends/rng.c
> +++ b/backends/rng.c
> @@ -68,6 +68,22 @@ static void rng_backend_free_request(RngRequest *req)
>       g_free(req);
>   }
>   
> +void rng_backend_cancel_request_entropy(RngBackend *s,
> +                                        EntropyReceiveFunc *receive_entropy,
> +                                        void *opaque)
> +{
> +    RngRequest *req, *next;
> +
> +    QSIMPLEQ_FOREACH_SAFE(req, &s->requests, next, next) {
> +        if (req->receive_entropy != receive_entropy ||
> +            req->opaque != opaque) {
> +            continue;
> +        }
> +        QSIMPLEQ_REMOVE(&s->requests, req, RngRequest, next);
> +        rng_backend_free_request(req);
> +    }
> +}
> +
>   static void rng_backend_free_requests(RngBackend *s)
>   {
>       RngRequest *req, *next;
> diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
> index 66690a34dc97..a77ea5ab1385 100644
> --- a/hw/virtio/virtio-rng.c
> +++ b/hw/virtio/virtio-rng.c
> @@ -234,6 +234,8 @@ static void virtio_rng_device_unrealize(DeviceState *dev)
>       VirtIODevice *vdev = VIRTIO_DEVICE(dev);
>       VirtIORNG *vrng = VIRTIO_RNG(dev);
>   
> +    rng_backend_cancel_request_entropy(vrng->rng, chr_read, vrng);
> +
>       qemu_del_vm_change_state_handler(vrng->vmstate);
>       timer_free(vrng->rate_limit_timer);
>       virtio_del_queue(vdev, 0);
> diff --git a/include/system/rng.h b/include/system/rng.h
> index e383f87d20b2..5b0893eb2bd5 100644
> --- a/include/system/rng.h
> +++ b/include/system/rng.h
> @@ -86,4 +86,18 @@ void rng_backend_request_entropy(RngBackend *s, size_t size,
>    * deleted.
>    */
>   void rng_backend_finalize_request(RngBackend *s, RngRequest *req);
> +
> +/**
> + * rng_backend_cancel_request_entropy:
> + * @s: the backend that created the request
> + * @receive_entropy: the function invoked when entropy is available
> + * @opaque: data passed to @receive_entropy
> + *
> + * This function is used by the front-end to cancel all requests to a
> + * given backend. Requests to cancel are identified by the receive_entropy
> + * function and the data passed to the function.
> + */
> +void rng_backend_cancel_request_entropy(RngBackend *s,
> +                                        EntropyReceiveFunc *receive_entropy,
> +                                        void *opaque);

I'd simply name it rng_backend_cancel_requests(), and make the argument 
const:

   void rng_backend_cancel_requests(RngBackend *s,
                                    const EntropyReceiveFunc 
*receive_entropy,
                                    const void *opaque);

I suppose we should implement spapr_rng_unrealize() calling this helper.

For this patch (preferably renamed):
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] hw/virtio-rng: Fix host use-after-free (CVE-2026-50624)
  2026-07-24  8:31 ` Philippe Mathieu-Daudé
@ 2026-07-24  9:29   ` Laurent Vivier
  0 siblings, 0 replies; 4+ messages in thread
From: Laurent Vivier @ 2026-07-24  9:29 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: Michael S. Tsirkin, Amit Shah, Jia Jia, qemu-ppc

On 7/24/26 10:31, Philippe Mathieu-Daudé wrote:
> On 8/7/26 08:39, Laurent Vivier wrote:
>> 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>
>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>> ---
>>   backends/rng.c         | 16 ++++++++++++++++
>>   hw/virtio/virtio-rng.c |  2 ++
>>   include/system/rng.h   | 14 ++++++++++++++
>>   3 files changed, 32 insertions(+)
>>
>> diff --git a/backends/rng.c b/backends/rng.c
>> index ab94dfea850a..182269be4a83 100644
>> --- a/backends/rng.c
>> +++ b/backends/rng.c
>> @@ -68,6 +68,22 @@ static void rng_backend_free_request(RngRequest *req)
>>       g_free(req);
>>   }
>> +void rng_backend_cancel_request_entropy(RngBackend *s,
>> +                                        EntropyReceiveFunc *receive_entropy,
>> +                                        void *opaque)
>> +{
>> +    RngRequest *req, *next;
>> +
>> +    QSIMPLEQ_FOREACH_SAFE(req, &s->requests, next, next) {
>> +        if (req->receive_entropy != receive_entropy ||
>> +            req->opaque != opaque) {
>> +            continue;
>> +        }
>> +        QSIMPLEQ_REMOVE(&s->requests, req, RngRequest, next);
>> +        rng_backend_free_request(req);
>> +    }
>> +}
>> +
>>   static void rng_backend_free_requests(RngBackend *s)
>>   {
>>       RngRequest *req, *next;
>> diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
>> index 66690a34dc97..a77ea5ab1385 100644
>> --- a/hw/virtio/virtio-rng.c
>> +++ b/hw/virtio/virtio-rng.c
>> @@ -234,6 +234,8 @@ static void virtio_rng_device_unrealize(DeviceState *dev)
>>       VirtIODevice *vdev = VIRTIO_DEVICE(dev);
>>       VirtIORNG *vrng = VIRTIO_RNG(dev);
>> +    rng_backend_cancel_request_entropy(vrng->rng, chr_read, vrng);
>> +
>>       qemu_del_vm_change_state_handler(vrng->vmstate);
>>       timer_free(vrng->rate_limit_timer);
>>       virtio_del_queue(vdev, 0);
>> diff --git a/include/system/rng.h b/include/system/rng.h
>> index e383f87d20b2..5b0893eb2bd5 100644
>> --- a/include/system/rng.h
>> +++ b/include/system/rng.h
>> @@ -86,4 +86,18 @@ void rng_backend_request_entropy(RngBackend *s, size_t size,
>>    * deleted.
>>    */
>>   void rng_backend_finalize_request(RngBackend *s, RngRequest *req);
>> +
>> +/**
>> + * rng_backend_cancel_request_entropy:
>> + * @s: the backend that created the request
>> + * @receive_entropy: the function invoked when entropy is available
>> + * @opaque: data passed to @receive_entropy
>> + *
>> + * This function is used by the front-end to cancel all requests to a
>> + * given backend. Requests to cancel are identified by the receive_entropy
>> + * function and the data passed to the function.
>> + */
>> +void rng_backend_cancel_request_entropy(RngBackend *s,
>> +                                        EntropyReceiveFunc *receive_entropy,
>> +                                        void *opaque);
> 
> I'd simply name it rng_backend_cancel_requests(), and make the argument const:
> 
>    void rng_backend_cancel_requests(RngBackend *s,
>                                     const EntropyReceiveFunc *receive_entropy,
>                                     const void *opaque);

I agree

> 
> I suppose we should implement spapr_rng_unrealize() calling this helper.

I don't think this is needed (at least for the CVE case) as rng_backend_request_entropy() 
here is synchronous and spapr_rng is not hotpluggable.

> 
> For this patch (preferably renamed):
> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> 

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-07-24  9:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-08  6:39 [PATCH] hw/virtio-rng: Fix host use-after-free (CVE-2026-50624) Laurent Vivier
2026-07-24  7:43 ` Laurent Vivier
2026-07-24  8:31 ` Philippe Mathieu-Daudé
2026-07-24  9:29   ` Laurent Vivier

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.