Commit 68f1fc4551 for qemu.org

commit 68f1fc45512a642234ca97361a822071867653e1
Author: Peter Xu <peterx@redhat.com>
Date:   Thu Aug 20 16:03:20 2026 -0400

    migration/rdma: Sanity check RDMA_CONTROL_REGISTER_REQUEST chunks

    The value received on wire for head.chunks when registering new RDMA
    regions is not correctly checked.  Logically the value can still make
    ram_chunk_start() (of ram_chunk_end()) to overflow, having a result pointer
    very small, smaller than RDMALocalBlock.local_host_addr.

    Add the sanity check.

    Reported-by: Tristan (@TristanInSec)
    Closes: https://gitlab.com/qemu-project/qemu/-/work_items/4011
    Reviewed-by: Jinpu Wang <jinpu.wang@cloud.ionos.com>
    Signed-off-by: Peter Xu <peterx@redhat.com>
    Reviewed-by: Fabiano Rosas <farosas@suse.de>
    Signed-off-by: Fabiano Rosas <farosas@suse.de>

diff --git a/migration/rdma.c b/migration/rdma.c
index f7356e759f..cf6688a4bc 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -3369,7 +3369,7 @@ int rdma_registration_handle(QEMUFile *f)
             }

             for (int count = 0; count < head.repeat; count++) {
-                uint64_t chunk;
+                uint64_t chunk, chunk_sum;
                 uint8_t *chunk_start, *chunk_end;

                 reg = &registers[count];
@@ -3399,6 +3399,14 @@ int rdma_registration_handle(QEMUFile *f)
                 chunk = ram_chunk_index(block->local_host_addr,
                                         (uint8_t *) host_addr);
                 chunk_start = ram_chunk_start(block, chunk);
+                if (uadd64_overflow(chunk, reg->chunks, &chunk_sum) ||
+                    chunk_sum >= block->nb_chunks) {
+                    error_report("%s: head.chunks contains illegal value"
+                                 " (chunk=%"PRIu64", chunks=%"PRIu64", "
+                                 "nb_chunks=%d)", __func__, chunk,
+                                 reg->chunks, block->nb_chunks);
+                    goto err;
+                }
                 chunk_end = ram_chunk_end(block, chunk + reg->chunks);
                 /* avoid "-Waddress-of-packed-member" warning */
                 uint32_t tmp_rkey = 0;