kvmvapic: Catch invalid ROM size

If not caught early, a zero-length ROM will cause a NULL-pointer access
later on in patch_hypercalls when allocating a zero-length ROM copy and
trying to read from it.

CC: qemu-stable@nongnu.org
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Jan Kiszka 2013-09-03 18:08:50 +02:00 committed by Paolo Bonzini
parent 76fe21deda
commit 18e5eec4db
1 changed files with 9 additions and 2 deletions

View File

@ -578,7 +578,7 @@ static int patch_hypercalls(VAPICROMState *s)
* enable write access to the option ROM so that variables can be updated by * enable write access to the option ROM so that variables can be updated by
* the guest. * the guest.
*/ */
static void vapic_map_rom_writable(VAPICROMState *s) static int vapic_map_rom_writable(VAPICROMState *s)
{ {
hwaddr rom_paddr = s->rom_state_paddr & ROM_BLOCK_MASK; hwaddr rom_paddr = s->rom_state_paddr & ROM_BLOCK_MASK;
MemoryRegionSection section; MemoryRegionSection section;
@ -599,6 +599,9 @@ static void vapic_map_rom_writable(VAPICROMState *s)
/* read ROM size from RAM region */ /* read ROM size from RAM region */
ram = memory_region_get_ram_ptr(section.mr); ram = memory_region_get_ram_ptr(section.mr);
rom_size = ram[rom_paddr + 2] * ROM_BLOCK_SIZE; rom_size = ram[rom_paddr + 2] * ROM_BLOCK_SIZE;
if (rom_size == 0) {
return -1;
}
s->rom_size = rom_size; s->rom_size = rom_size;
/* We need to round to avoid creating subpages /* We need to round to avoid creating subpages
@ -612,11 +615,15 @@ static void vapic_map_rom_writable(VAPICROMState *s)
memory_region_add_subregion_overlap(as, rom_paddr, &s->rom, 1000); memory_region_add_subregion_overlap(as, rom_paddr, &s->rom, 1000);
s->rom_mapped_writable = true; s->rom_mapped_writable = true;
memory_region_unref(section.mr); memory_region_unref(section.mr);
return 0;
} }
static int vapic_prepare(VAPICROMState *s) static int vapic_prepare(VAPICROMState *s)
{ {
vapic_map_rom_writable(s); if (vapic_map_rom_writable(s) < 0) {
return -1;
}
if (patch_hypercalls(s) < 0) { if (patch_hypercalls(s) < 0) {
return -1; return -1;