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>
This commit is contained in:
parent
c54d1c0670
commit
5b0e9dd46f
56
arch_init.c
56
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)
|
static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
||||||
{
|
{
|
||||||
ram_addr_t addr;
|
int flags = 0, ret = 0;
|
||||||
int flags, ret = 0;
|
|
||||||
static uint64_t seq_iter;
|
static uint64_t seq_iter;
|
||||||
|
|
||||||
seq_iter++;
|
seq_iter++;
|
||||||
|
@ -1050,21 +1049,24 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!ret) {
|
while (!ret && !(flags & RAM_SAVE_FLAG_EOS)) {
|
||||||
addr = qemu_get_be64(f);
|
ram_addr_t addr, total_ram_bytes;
|
||||||
|
void *host;
|
||||||
|
uint8_t ch;
|
||||||
|
|
||||||
|
addr = qemu_get_be64(f);
|
||||||
flags = addr & ~TARGET_PAGE_MASK;
|
flags = addr & ~TARGET_PAGE_MASK;
|
||||||
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 */
|
/* Synchronize RAM block list */
|
||||||
char id[256];
|
total_ram_bytes = addr;
|
||||||
ram_addr_t length;
|
while (!ret && total_ram_bytes) {
|
||||||
ram_addr_t total_ram_bytes = addr;
|
|
||||||
|
|
||||||
while (total_ram_bytes) {
|
|
||||||
RAMBlock *block;
|
RAMBlock *block;
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
|
char id[256];
|
||||||
|
ram_addr_t length;
|
||||||
|
|
||||||
len = qemu_get_byte(f);
|
len = qemu_get_byte(f);
|
||||||
qemu_get_buffer(f, (uint8_t *)id, len);
|
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);
|
"accept migration", id);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
if (ret) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_ram_bytes -= length;
|
total_ram_bytes -= length;
|
||||||
}
|
}
|
||||||
} else if (flags & RAM_SAVE_FLAG_COMPRESS) {
|
break;
|
||||||
void *host;
|
case RAM_SAVE_FLAG_COMPRESS:
|
||||||
uint8_t ch;
|
|
||||||
|
|
||||||
host = host_from_stream_offset(f, addr, flags);
|
host = host_from_stream_offset(f, addr, flags);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
|
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);
|
ch = qemu_get_byte(f);
|
||||||
ram_handle_compressed(host, ch, TARGET_PAGE_SIZE);
|
ram_handle_compressed(host, ch, TARGET_PAGE_SIZE);
|
||||||
} else if (flags & RAM_SAVE_FLAG_PAGE) {
|
break;
|
||||||
void *host;
|
case RAM_SAVE_FLAG_PAGE:
|
||||||
|
|
||||||
host = host_from_stream_offset(f, addr, flags);
|
host = host_from_stream_offset(f, addr, flags);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
|
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);
|
qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
|
||||||
} else if (flags & RAM_SAVE_FLAG_XBZRLE) {
|
break;
|
||||||
void *host = host_from_stream_offset(f, addr, flags);
|
case RAM_SAVE_FLAG_XBZRLE:
|
||||||
|
host = host_from_stream_offset(f, addr, flags);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
|
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -1132,18 +1129,23 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (flags & RAM_SAVE_FLAG_HOOK) {
|
break;
|
||||||
ram_control_load_hook(f, flags);
|
case RAM_SAVE_FLAG_EOS:
|
||||||
} else if (flags & RAM_SAVE_FLAG_EOS) {
|
|
||||||
/* normal exit */
|
/* normal exit */
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
if (flags & RAM_SAVE_FLAG_HOOK) {
|
||||||
|
ram_control_load_hook(f, flags);
|
||||||
} else {
|
} else {
|
||||||
error_report("Unknown migration flags: %#x", flags);
|
error_report("Unknown combination of migration flags: %#x",
|
||||||
|
flags);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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 "
|
DPRINTF("Completed load of VM with exit code %d seq iteration "
|
||||||
"%" PRIu64 "\n", ret, seq_iter);
|
"%" PRIu64 "\n", ret, seq_iter);
|
||||||
|
|
Loading…
Reference in a new issue