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;