aboutsummaryrefslogtreecommitdiff
path: root/hw/mips
diff options
context:
space:
mode:
authorThomas Huth <thuth@redhat.com>2018-06-26 11:35:40 +0200
committerCornelia Huck <cohuck@redhat.com>2018-07-02 10:37:38 +0200
commit0f0f8b611eeea663c8d3b6021918033e257411a1 (patch)
tree69faeb3be924514248d41a232bf82e439c1da734 /hw/mips
parent76ed4b18debfe597329d1f6a9eb2ec9ffa751ecd (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.c6
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++;