diff options
author | Peter Lieven <pl@kamp.de> | 2014-06-24 11:32:36 +0200 |
---|---|---|
committer | Juan Quintela <quintela@trasno.org> | 2014-10-14 11:24:20 +0200 |
commit | 5b0e9dd46fbda5152566a4a26fd96bc0d0452bf7 (patch) | |
tree | 3e91d626e3758daae94dfd94a05c7ff8c9e2218a | |
parent | c54d1c067080ca18b50b593dcc935365387e11b6 (diff) |
migration: catch unknown flag combinations in ram_load
this patch extends commit db80fac by not only checking
for unknown flags, but also filtering out unknown flag
combinations.
Suggested-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Juan Quintela <quintela@redhat.com>
-rw-r--r-- | arch_init.c | 62 |
1 files changed, 32 insertions, 30 deletions
diff --git a/arch_init.c b/arch_init.c index 9b3e25d805..88a5ba0837 100644 --- a/arch_init.c +++ b/arch_init.c @@ -1040,8 +1040,7 @@ void ram_handle_compressed(void *host, uint8_t ch, uint64_t size) static int ram_load(QEMUFile *f, void *opaque, int version_id) { - ram_addr_t addr; - int flags, ret = 0; + int flags = 0, ret = 0; static uint64_t seq_iter; seq_iter++; @@ -1050,21 +1049,24 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) ret = -EINVAL; } - while (!ret) { - addr = qemu_get_be64(f); + while (!ret && !(flags & RAM_SAVE_FLAG_EOS)) { + ram_addr_t addr, total_ram_bytes; + void *host; + uint8_t ch; + addr = qemu_get_be64(f); flags = addr & ~TARGET_PAGE_MASK; addr &= TARGET_PAGE_MASK; - if (flags & RAM_SAVE_FLAG_MEM_SIZE) { + switch (flags & ~RAM_SAVE_FLAG_CONTINUE) { + case RAM_SAVE_FLAG_MEM_SIZE: /* Synchronize RAM block list */ - char id[256]; - ram_addr_t length; - ram_addr_t total_ram_bytes = addr; - - while (total_ram_bytes) { + total_ram_bytes = addr; + while (!ret && total_ram_bytes) { RAMBlock *block; uint8_t len; + char id[256]; + ram_addr_t length; len = qemu_get_byte(f); qemu_get_buffer(f, (uint8_t *)id, len); @@ -1088,16 +1090,11 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) "accept migration", id); ret = -EINVAL; } - if (ret) { - break; - } total_ram_bytes -= length; } - } else if (flags & RAM_SAVE_FLAG_COMPRESS) { - void *host; - uint8_t ch; - + break; + case RAM_SAVE_FLAG_COMPRESS: host = host_from_stream_offset(f, addr, flags); if (!host) { error_report("Illegal RAM offset " RAM_ADDR_FMT, addr); @@ -1107,9 +1104,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) ch = qemu_get_byte(f); ram_handle_compressed(host, ch, TARGET_PAGE_SIZE); - } else if (flags & RAM_SAVE_FLAG_PAGE) { - void *host; - + break; + case RAM_SAVE_FLAG_PAGE: host = host_from_stream_offset(f, addr, flags); if (!host) { error_report("Illegal RAM offset " RAM_ADDR_FMT, addr); @@ -1118,8 +1114,9 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) } qemu_get_buffer(f, host, TARGET_PAGE_SIZE); - } else if (flags & RAM_SAVE_FLAG_XBZRLE) { - void *host = host_from_stream_offset(f, addr, flags); + break; + case RAM_SAVE_FLAG_XBZRLE: + host = host_from_stream_offset(f, addr, flags); if (!host) { error_report("Illegal RAM offset " RAM_ADDR_FMT, addr); ret = -EINVAL; @@ -1132,17 +1129,22 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) ret = -EINVAL; break; } - } else if (flags & RAM_SAVE_FLAG_HOOK) { - ram_control_load_hook(f, flags); - } else if (flags & RAM_SAVE_FLAG_EOS) { - /* normal exit */ break; - } else { - error_report("Unknown migration flags: %#x", flags); - ret = -EINVAL; + case RAM_SAVE_FLAG_EOS: + /* normal exit */ break; + default: + if (flags & RAM_SAVE_FLAG_HOOK) { + ram_control_load_hook(f, flags); + } else { + error_report("Unknown combination of migration flags: %#x", + flags); + ret = -EINVAL; + } + } + if (!ret) { + ret = qemu_file_get_error(f); } - ret = qemu_file_get_error(f); } DPRINTF("Completed load of VM with exit code %d seq iteration " |