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;