Re: [PATCH] hw/virtio-rng: Fix host use-after-free (CVE-2026-50624)

2026-07-24 Thread Laurent Vivier

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 
Signed-off-by: Laurent Vivier 
---
  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é 



Thanks,
Laurent




Re: [PATCH] hw/virtio-rng: Fix host use-after-free (CVE-2026-50624)

2026-07-24 Thread Philippe Mathieu-Daudé

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 
Signed-off-by: Laurent Vivier 
---
  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é 




Re: [PATCH] hw/virtio-rng: Fix host use-after-free (CVE-2026-50624)

2026-07-24 Thread Laurent Vivier



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 
Signed-off-by: Laurent Vivier 
---
  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





[PATCH] hw/virtio-rng: Fix host use-after-free (CVE-2026-50624)

2026-07-07 Thread Laurent Vivier
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 
Signed-off-by: Laurent Vivier 
---
 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