Skip to content

Commit

Permalink
migration: catch unknown flag combinations in ram_load
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
plieven authored and juanquintela committed Oct 14, 2014
1 parent c54d1c0 commit 5b0e9dd
Showing 1 changed file with 32 additions and 30 deletions.
62 changes: 32 additions & 30 deletions arch_init.c
Expand Up @@ -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++;
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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 "
Expand Down

0 comments on commit 5b0e9dd

Please sign in to comment.