[PATCH] migration: validate page_size in mapped-ram header before use

Trieu Huynh posted 1 patch 5 days, 5 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260328072424.10611-1-vikingtc4@gmail.com
Maintainers: Peter Xu <peterx@redhat.com>, Fabiano Rosas <farosas@suse.de>
migration/ram.c | 5 +++++
1 file changed, 5 insertions(+)
[PATCH] migration: validate page_size in mapped-ram header before use
Posted by Trieu Huynh 5 days, 5 hours ago
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 page_size = 0,
QEMU unexpectedly crashes.

Add validation in mapped_ram_read_header() to reject zero 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 0.
Restore the snapshot:
(qemu) migrate_set_capability mapped-ram on
(qemu) migrate_incoming file:/tmp/qemu-bug-test/snapshot.bin

As-is: qemu crashes immediately
(qemu) Floating point exception (core dumped)
To-be: qemu continue running
(qemu) qemu-system-x86_64: Migration mapped-ram header has invalid
page_size of 0

Signed-off-by: Trieu Huynh <vikingtc4@gmail.com>
---
 migration/ram.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/migration/ram.c b/migration/ram.c
index 979751f61b..2a7e958e87 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3088,6 +3088,11 @@ static bool mapped_ram_read_header(QEMUFile *file, MappedRamHeader *header,
     }
 
     header->page_size = be64_to_cpu(header->page_size);
+    if (header->page_size == 0) {
+        error_setg(errp, "Migration mapped-ram header has invalid "
+                   "page_size of 0");
+        return false;
+    }
     header->bitmap_offset = be64_to_cpu(header->bitmap_offset);
     header->pages_offset = be64_to_cpu(header->pages_offset);
 
-- 
2.43.0
Re: [PATCH] migration: validate page_size in mapped-ram header before use
Posted by Peter Xu 2 days, 19 hours ago
On Sat, Mar 28, 2026 at 04:24:24PM +0900, Trieu Huynh wrote:
> 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 page_size = 0,
> QEMU unexpectedly crashes.
> 
> Add validation in mapped_ram_read_header() to reject zero 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 0.
> Restore the snapshot:
> (qemu) migrate_set_capability mapped-ram on
> (qemu) migrate_incoming file:/tmp/qemu-bug-test/snapshot.bin
> 
> As-is: qemu crashes immediately
> (qemu) Floating point exception (core dumped)
> To-be: qemu continue running
> (qemu) qemu-system-x86_64: Migration mapped-ram header has invalid
> page_size of 0
> 
> Signed-off-by: Trieu Huynh <vikingtc4@gmail.com>
> ---
>  migration/ram.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/migration/ram.c b/migration/ram.c
> index 979751f61b..2a7e958e87 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -3088,6 +3088,11 @@ static bool mapped_ram_read_header(QEMUFile *file, MappedRamHeader *header,
>      }
>  
>      header->page_size = be64_to_cpu(header->page_size);
> +    if (header->page_size == 0) {
> +        error_setg(errp, "Migration mapped-ram header has invalid "
> +                   "page_size of 0");
> +        return false;
> +    }

Thanks for the patch.

When at this, one more thing we could do is verify the value is exactly
target psize; afaict that's the assumption across the whole mapped-ram
feature.

>      header->bitmap_offset = be64_to_cpu(header->bitmap_offset);
>      header->pages_offset = be64_to_cpu(header->pages_offset);
>  
> -- 
> 2.43.0
> 

-- 
Peter Xu
Re: [PATCH] migration: validate page_size in mapped-ram header before use
Posted by Trieu Huynh 16 hours ago
On Mon, Mar 30, 2026 at 01:30:34PM -0400, Peter Xu wrote:
> On Sat, Mar 28, 2026 at 04:24:24PM +0900, Trieu Huynh wrote:
> > 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 page_size = 0,
> > QEMU unexpectedly crashes.
> > 
> > Add validation in mapped_ram_read_header() to reject zero 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 0.
> > Restore the snapshot:
> > (qemu) migrate_set_capability mapped-ram on
> > (qemu) migrate_incoming file:/tmp/qemu-bug-test/snapshot.bin
> > 
> > As-is: qemu crashes immediately
> > (qemu) Floating point exception (core dumped)
> > To-be: qemu continue running
> > (qemu) qemu-system-x86_64: Migration mapped-ram header has invalid
> > page_size of 0
> > 
> > Signed-off-by: Trieu Huynh <vikingtc4@gmail.com>
> > ---
> >  migration/ram.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/migration/ram.c b/migration/ram.c
> > index 979751f61b..2a7e958e87 100644
> > --- a/migration/ram.c
> > +++ b/migration/ram.c
> > @@ -3088,6 +3088,11 @@ static bool mapped_ram_read_header(QEMUFile *file, MappedRamHeader *header,
> >      }
> >  
> >      header->page_size = be64_to_cpu(header->page_size);
> > +    if (header->page_size == 0) {
> > +        error_setg(errp, "Migration mapped-ram header has invalid "
> > +                   "page_size of 0");
> > +        return false;
> > +    }
> 
> Thanks for the patch.
> 
> When at this, one more thing we could do is verify the value is exactly
> target psize; afaict that's the assumption across the whole mapped-ram
> feature.
> 
ack, will add it in v2. Thank you.
> >      header->bitmap_offset = be64_to_cpu(header->bitmap_offset);
> >      header->pages_offset = be64_to_cpu(header->pages_offset);
> >  
> > -- 
> > 2.43.0
> > 
> 
> -- 
> Peter Xu
>