diff options
author | Thomas Huth <thuth@redhat.com> | 2016-04-21 12:08:58 +0200 |
---|---|---|
committer | Timothy Pearson <tpearson@raptorengineering.com> | 2019-11-29 20:03:50 -0600 |
commit | 52fdcb0052f3e773654d35811b6873c29a105462 (patch) | |
tree | bf02dd48ca26cddd9eab88184bcf55fd7bcd483b | |
parent | 72f8ddc790c3e72da1a07eca0333c15bb7d96586 (diff) | |
download | hqemu-52fdcb0052f3e773654d35811b6873c29a105462.zip hqemu-52fdcb0052f3e773654d35811b6873c29a105462.tar.gz |
hw/ppc/spapr: Fix crash when specifying bad parameters to spapr-pci-host-bridge
QEMU currently crashes when using bad parameters for the
spapr-pci-host-bridge device:
$ qemu-system-ppc64 -device spapr-pci-host-bridge,buid=0x123,liobn=0x321,mem_win_addr=0x1,io_win_addr=0x10
Segmentation fault
The problem is that spapr_tce_find_by_liobn() might return NULL, but
the code in spapr_populate_pci_dt() does not check for this condition
and then tries to dereference this NULL pointer.
Apart from that, the return value of spapr_populate_pci_dt() also
has to be checked for all PCI buses, not only for the last one, to
make sure we catch all errors.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r-- | hw/ppc/spapr.c | 9 | ||||
-rw-r--r-- | hw/ppc/spapr_pci.c | 3 |
2 files changed, 7 insertions, 5 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index feaab08..b69995e 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -940,11 +940,10 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr, QLIST_FOREACH(phb, &spapr->phbs, list) { ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt); - } - - if (ret < 0) { - fprintf(stderr, "couldn't setup PCI devices in fdt\n"); - exit(1); + if (ret < 0) { + error_report("couldn't setup PCI devices in fdt"); + exit(1); + } } /* RTAS */ diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 8c20d34..573e635 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1816,6 +1816,9 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, sizeof(interrupt_map))); tcet = spapr_tce_find_by_liobn(SPAPR_PCI_LIOBN(phb->index, 0)); + if (!tcet) { + return -1; + } spapr_dma_dt(fdt, bus_off, "ibm,dma-window", tcet->liobn, tcet->bus_offset, tcet->nb_table << tcet->page_shift); |