@samitouri / QOSamiQemu / commits / 10dd206e92

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>

Peter Xu committed Jul 28, 2026 at 17:04 UTC 10dd206e92e0f688b7aa411e57533448c56ab6b8
1 file changed +11 -4
migration/ram.c
+11 -4
@@ -4263,15 +4263,15 @@ static int parse_ramblock(QEMUFile *f, RAMBlock *block, ram_addr_t length)
4263 return ret;
4264 }
4265
4266 -static int parse_ramblocks(QEMUFile *f, ram_addr_t total_ram_bytes)
4266 +static int parse_ramblocks(QEMUFile *f, uint64_t total_ram_bytes)
4267 {
4268 int ret = 0;
4269
4270 /* Synchronize RAM block list */
4271 - while (!ret && total_ram_bytes) {
4271 + while (total_ram_bytes) {
4272 RAMBlock *block;
4273 char id[256];
4274 - ram_addr_t length;
4274 + uint64_t length;
4275 int len = qemu_get_byte(f);
4276
4277 qemu_get_buffer(f, (uint8_t *)id, len);
@@ -4285,8 +4285,15 @@ static int parse_ramblocks(QEMUFile *f, ram_addr_t total_ram_bytes)
4285 error_report("Unknown ramblock \"%s\", cannot accept "
4286 "migration", id);
4287 ret = -EINVAL;
4288 + break;
4289 + }
4290 +
4291 + if (usub64_overflow(total_ram_bytes, length, &total_ram_bytes)) {
4292 + error_report("%s: RAMBlock '%s' size underflow total RAM size",
4293 + __func__, block->idstr);
4294 + ret = -EFAULT;
4295 + break;
4296 }
4289 - total_ram_bytes -= length;
4297 }
4298
4299 return ret;