qemu/hw/ide
Igor Mammedov 955f5c7ba1 ide: ahci: unparent children buses before freeing their memory
Fixes read after freeing error reported
  https://lists.gnu.org/archive/html/qemu-devel/2017-08/msg04243.html
  Message-Id: <59a56959-ca12-ea75-33fa-ff07eba1b090@redhat.com>

ich9-ahci device creates ide buses and attaches them as QOM children
at realize time, however it forgets to properly clean them up
at unrealize time and frees memory containing these children,
with following call-chain:

   qdev_device_add()
     object_property_set_bool('realized', true)
       device_set_realized()
          ...
          pci_qdev_realize() -> pci_ich9_ahci_realize() -> ahci_realize()
               ...
               s->dev = g_new0(AHCIDevice, ports);
               ...
                  AHCIDevice *ad = &s->dev[i];
                  ide_bus_new(&ad->port, sizeof(ad->port), qdev, i, 1);
                  ^^^ creates bus in memory allocated by above gnew()
                      and adds it as child propety to ahci device
          ...
          hotplug_handler_plug(); -> goto post_realize_fail;
          pci_qdev_unrealize() -> pci_ich9_uninit() -> ahci_uninit()
              ...
               g_free(s->dev);
               ^^^ free memory that holds children busses

          return with error from device_set_realized()

As result later when qdev_device_add() tries to unparent ich9-ahci
after failed device_set_realized(),
    object_unparent() -> object_property_del_child()
iterates over existing QOM children including buses added by
ide_bus_new() and tries to unparent them, which causes access to
freed memory where they where located.

Reported-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 1503938085-169486-1-git-send-email-imammedo@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
2017-09-18 15:01:25 -04:00
..
ahci_internal.h ahci: split public and private interface 2017-07-18 11:47:57 -04:00
ahci.c ide: ahci: unparent children buses before freeing their memory 2017-09-18 15:01:25 -04:00
atapi.c atapi: classify read_cd as conditionally returning data 2016-11-14 11:15:54 -05:00
cmd646.c Use #include "..." for our own headers, <...> for others 2016-07-12 16:19:16 +02:00
core.c IDE: Do not flush empty CDROM drives 2017-08-10 14:33:43 +01:00
ich.c ahci: split public and private interface 2017-07-18 11:47:57 -04:00
isa.c Use #include "..." for our own headers, <...> for others 2016-07-12 16:19:16 +02:00
macio.c macio: switch over to new byte-aligned DMA helpers 2016-10-27 16:29:13 -04:00
Makefile.objs hw: make all of hw/ide/ configurable via default-configs/ 2013-04-08 18:13:12 +02:00
microdrive.c Use #include "..." for our own headers, <...> for others 2016-07-12 16:19:16 +02:00
mmio.c Use #include "..." for our own headers, <...> for others 2016-07-12 16:19:16 +02:00
pci.c Use #include "..." for our own headers, <...> for others 2016-07-12 16:19:16 +02:00
piix.c xen-platform: add missing disk unplug option 2017-01-27 15:23:29 -08:00
qdev.c ide: bdrv_attach_dev() for empty CD-ROM 2017-07-18 15:14:36 +02:00
via.c Use #include "..." for our own headers, <...> for others 2016-07-12 16:19:16 +02:00