diff options
author | Thomas Huth <thuth@redhat.com> | 2018-06-26 11:35:40 +0200 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2018-07-02 10:37:38 +0200 |
commit | 0f0f8b611eeea663c8d3b6021918033e257411a1 (patch) | |
tree | 69faeb3be924514248d41a232bf82e439c1da734 /hw/mips | |
parent | 76ed4b18debfe597329d1f6a9eb2ec9ffa751ecd (diff) |
loader: Check access size when calling rom_ptr() to avoid crashes
The rom_ptr() function allows direct access to the ROM blobs that we
load during startup. However, there are currently no checks for the
size of the accesses, so it's currently possible to crash QEMU for
example with:
$ echo "Insane in the mainframe" > /tmp/test.txt
$ s390x-softmmu/qemu-system-s390x -kernel /tmp/test.txt -append xyz
Segmentation fault (core dumped)
$ s390x-softmmu/qemu-system-s390x -kernel /tmp/test.txt -initrd /tmp/test.txt
Segmentation fault (core dumped)
$ echo -n HdrS > /tmp/hdr.txt
$ sparc64-softmmu/qemu-system-sparc64 -kernel /tmp/hdr.txt -initrd /tmp/hdr.txt
Segmentation fault (core dumped)
We need a possibility to check the size of the ROM area that we want
to access, thus let's add a size parameter to the rom_ptr() function
to avoid these problems.
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1530005740-25254-1-git-send-email-thuth@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'hw/mips')
-rw-r--r-- | hw/mips/mips_malta.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index b9d92bf47e..1b4e32e58e 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -1133,11 +1133,13 @@ void mips_malta_init(MachineState *machine) a neat trick which allows bi-endian firmware. */ #ifndef TARGET_WORDS_BIGENDIAN { - uint32_t *end, *addr = rom_ptr(FLASH_ADDRESS); + uint32_t *end, *addr; + const size_t swapsize = MIN(bios_size, 0x3e0000); + addr = rom_ptr(FLASH_ADDRESS, swapsize); if (!addr) { addr = memory_region_get_ram_ptr(bios); } - end = (void *)addr + MIN(bios_size, 0x3e0000); + end = (void *)addr + swapsize; while (addr < end) { bswap32s(addr); addr++; |