Commit 5b0e9dd4 authored by Peter Lieven's avatar Peter Lieven Committed by Juan Quintela

migration: catch unknown flag combinations in ram_load

this patch extends commit db80face by not only checking
for unknown flags, but also filtering out unknown flag
combinations.
Suggested-by: default avatarEric Blake <eblake@redhat.com>
Signed-off-by: default avatarPeter Lieven <pl@kamp.de>
Signed-off-by: default avatarJuan Quintela <quintela@redhat.com>
parent c54d1c06
......@@ -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 "
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment