Commit 70074cc48f for qemu.org

commit 70074cc48f450e6c95881ac534e67013c8773cb2
Author: Laurent Vivier <lvivier@redhat.com>
Date:   Wed Jul 15 16:13:00 2026 +0200

    backends/rng: cap request size to avoid oversized allocation

    rng_backend_request_entropy() uses the requested size to allocate
    a buffer with g_malloc(). With virtio-rng, this size comes from
    guest-supplied descriptor lengths. A malicious guest can set a very
    large descriptor length, causing QEMU to attempt a multi-gigabyte
    allocation and abort.

    Cap the allocation to 64 KiB. The virtio-rng queue size is
    hardcoded to 8 entries, the EGD backend protocol limits requests
    to 255 bytes, the Linux kernel hwrng framework requests at most
    SMP_CACHE_BYTES per call (64 bytes on x86_64), and the Windows
    viorng driver uses a 4 KiB buffer. The worst legitimate case is
    8 x 4 KiB = 32 KiB, so 64 KiB is well above any legitimate use.

    Fixes: 14417039653d ("virtio-rng: use virtqueue_get_avail_bytes, fix migration")
    Cc: qemu-stable@nongnu.org
    Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3983
    Reported-by: dong ling <dongling226655@outlook.com>
    Signed-off-by: Laurent Vivier <lvivier@redhat.com>
    Reviewed-by: Thomas Huth <thuth@redhat.com>
    Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
    Message-ID: <20260715141300.2295392-1-lvivier@redhat.com>

diff --git a/backends/rng.c b/backends/rng.c
index 7bed62616a..bc9c7a5ab3 100644
--- a/backends/rng.c
+++ b/backends/rng.c
@@ -11,11 +11,14 @@
  */

 #include "qemu/osdep.h"
+#include "qemu/units.h"
 #include "system/rng.h"
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "qom/object_interfaces.h"

+#define RNG_MAX_REQUEST_SIZE (64 * KiB)
+
 void rng_backend_request_entropy(RngBackend *s, size_t size,
                                  EntropyReceiveFunc *receive_entropy,
                                  void *opaque)
@@ -27,7 +30,7 @@ void rng_backend_request_entropy(RngBackend *s, size_t size,
         req = g_malloc(sizeof(*req));

         req->offset = 0;
-        req->size = size;
+        req->size = MIN(size, RNG_MAX_REQUEST_SIZE);
         req->receive_entropy = receive_entropy;
         req->opaque = opaque;
         req->data = g_malloc(req->size);