Commit 10dd206e92 for qemu.org

commit 10dd206e92e0f688b7aa411e57533448c56ab6b8
Author: Peter Xu <peterx@redhat.com>
Date:   Tue Jul 28 17:04:17 2026 -0400

    migration/ram: Check for RAMBlock size mismatch when parsing

    Add an underflow check for the subtract of total RAMBlock size to make sure
    it won't underflow.  It should not happen in production systems but only if
    the migration stream was hijacked, which is not a real concern since
    migration channel is trusted.  Still protect against it.

    Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4013
    Reported-by: Tristan Madani <tristan@talencesecurity.com>
    Reviewed-by: Fabiano Rosas <farosas@suse.de>
    Link: https://lore.kernel.org/r/20260728210417.1925078-6-peterx@redhat.com
    Signed-off-by: Peter Xu <peterx@redhat.com>

diff --git a/migration/ram.c b/migration/ram.c
index 8918b2f03b..b6eb842746 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4263,15 +4263,15 @@ static int parse_ramblock(QEMUFile *f, RAMBlock *block, ram_addr_t length)
     return ret;
 }

-static int parse_ramblocks(QEMUFile *f, ram_addr_t total_ram_bytes)
+static int parse_ramblocks(QEMUFile *f, uint64_t total_ram_bytes)
 {
     int ret = 0;

     /* Synchronize RAM block list */
-    while (!ret && total_ram_bytes) {
+    while (total_ram_bytes) {
         RAMBlock *block;
         char id[256];
-        ram_addr_t length;
+        uint64_t length;
         int len = qemu_get_byte(f);

         qemu_get_buffer(f, (uint8_t *)id, len);
@@ -4285,8 +4285,15 @@ static int parse_ramblocks(QEMUFile *f, ram_addr_t total_ram_bytes)
             error_report("Unknown ramblock \"%s\", cannot accept "
                          "migration", id);
             ret = -EINVAL;
+            break;
+        }
+
+        if (usub64_overflow(total_ram_bytes, length, &total_ram_bytes)) {
+            error_report("%s: RAMBlock '%s' size underflow total RAM size",
+                         __func__, block->idstr);
+            ret = -EFAULT;
+            break;
         }
-        total_ram_bytes -= length;
     }

     return ret;