@samitouri / QOSamiQemu / commits / 03b7c2369c

migration: validate page_size in mapped-ram header before use

mapped_ram_read_header() reads page_size from the migration stream and stores it in MappedRamHeader, but does not validate that the value is non-zero before it is later used in parse_ramblock_mapped_ram(): num_pages = length / header.page_size; If a corrupted or malformed migration stream provides invalid, guest resumes either with corrupted memory or crashes unexpectedly (eg. page_size = 0) Add validation in mapped_ram_read_header() to reject invalid page_size values early and return an error instead of continuing with an invalid header. Steps to reproduce: Create a migration snapshot with mapped-ram enabled: (qemu) migrate_set_capability mapped-ram on (qemu) migrate file:/tmp/qemu-snapshots/snapshot.bin Modify the snapshot so that MappedRamHeader.page_size becomes diff with target psize. (0/512/8192/1GB). Restore the snapshot: (qemu) migrate_set_capability mapped-ram on (qemu) migrate_incoming file:/tmp/qemu-snapshots/snapshot.bin As-is: * [0]: Floating point exception (core dumped) * [512/8192]: Silent corruption * [1GB]: "post load hook failed for: kvm-tpr-opt" (EPERM) To-be: * All: qemu-system-x86_64: Migration mapped-ram header has invalid page_size [val] (expected 4096) Signed-off-by: Trieu Huynh <vikingtc4@gmail.com> Reviewed-by: Fabiano Rosas <farosas@suse.de> Reviewed-by: Peter Xu <peterx@redhat.com> Link: https://lore.kernel.org/qemu-devel/20260405094447.11347-1-viking4@gmail.com Signed-off-by: Fabiano Rosas <farosas@suse.de>

Trieu Huynh committed Apr 5, 2026 at 16:44 UTC 03b7c2369ce6081072da88b589e5e5349f2dea50
1 file changed +6
migration/ram.c
+6
@@ -3088,6 +3088,12 @@ static bool mapped_ram_read_header(QEMUFile *file, MappedRamHeader *header,
3088 }
3089
3090 header->page_size = be64_to_cpu(header->page_size);
3091 + if (header->page_size != TARGET_PAGE_SIZE) {
3092 + error_setg(errp, "Migration mapped-ram header has invalid "
3093 + "page_size %" PRIu64 " (expected %d)",
3094 + header->page_size, TARGET_PAGE_SIZE);
3095 + return false;
3096 + }
3097 header->bitmap_offset = be64_to_cpu(header->bitmap_offset);
3098 header->pages_offset = be64_to_cpu(header->pages_offset);
3099