On an SCLP deconfigure we don't clean up the FMB timer. If there is a
pending unplug request then we can destroy the S390PCIBusDevice object
without correctly cleaning up the timer. So fmb_update() will then run on
freed memory. Clean up the FMB timer before we destroy the S390PCIBusDevice
object to prevent this use after free.

When FMB was introduced with commit 6e92c70c37 ("s390x/pci: add common
function measurement block") we originally cleaned up the FMB timer in
s390_pcihost_unplug(). This behavior was changed in the re-work done with
commit e0998fe89104 ("s390x/pci: Introduce unplug requests and split unplug
handler").

Fixes: e0998fe89104 ("s390x/pci: Introduce unplug requests and split unplug 
handler")
Cc: [email protected]
Signed-off-by: Farhan Ali <[email protected]>
---
 hw/s390x/s390-pci-bus.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index cdd75cdfd2..32f78a1f21 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1400,6 +1400,7 @@ static void s390_pcihost_unplug(const HotplugHandler 
*hotplug_dev, DeviceState *
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
         pbdev = S390_PCI_DEVICE(dev);
         pbdev->fid = 0;
+        fmb_timer_free(pbdev);
         QTAILQ_REMOVE(&s->zpci_devs, pbdev, link);
         g_hash_table_remove(s->zpci_table, &pbdev->idx);
         if (pbdev->dma_limit) {
-- 
2.43.0


Reply via email to