All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH for-2.11] ide: ahci: unparent children buses before freeing their memory
@ 2017-08-28 16:34 Igor Mammedov
  2017-08-28 16:59 ` Philippe Mathieu-Daudé
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Igor Mammedov @ 2017-08-28 16:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: jsnow, qemu-block, thuth, f4bug, mst

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>
---
 hw/ide/ahci.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 406a1b5..ccbe091 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1495,6 +1495,7 @@ void ahci_uninit(AHCIState *s)
 
             ide_exit(s);
         }
+        object_unparent(OBJECT(&ad->port));
     }
 
     g_free(s->dev);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.11] ide: ahci: unparent children buses before freeing their memory
  2017-08-28 16:34 [Qemu-devel] [PATCH for-2.11] ide: ahci: unparent children buses before freeing their memory Igor Mammedov
@ 2017-08-28 16:59 ` Philippe Mathieu-Daudé
  2017-08-28 17:56 ` Thomas Huth
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-08-28 16:59 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel; +Cc: jsnow, qemu-block, thuth, mst

On 08/28/2017 01:34 PM, Igor Mammedov wrote:
> 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>

> ---
>   hw/ide/ahci.c | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 406a1b5..ccbe091 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -1495,6 +1495,7 @@ void ahci_uninit(AHCIState *s)
>   
>               ide_exit(s);
>           }
> +        object_unparent(OBJECT(&ad->port));
>       }
>   
>       g_free(s->dev);
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.11] ide: ahci: unparent children buses before freeing their memory
  2017-08-28 16:34 [Qemu-devel] [PATCH for-2.11] ide: ahci: unparent children buses before freeing their memory Igor Mammedov
  2017-08-28 16:59 ` Philippe Mathieu-Daudé
@ 2017-08-28 17:56 ` Thomas Huth
  2017-08-28 18:08 ` Michael S. Tsirkin
  2017-08-28 22:41 ` John Snow
  3 siblings, 0 replies; 5+ messages in thread
From: Thomas Huth @ 2017-08-28 17:56 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel; +Cc: jsnow, qemu-block, f4bug, mst

On 28.08.2017 18:34, Igor Mammedov wrote:
> 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>
> ---
>  hw/ide/ahci.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 406a1b5..ccbe091 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -1495,6 +1495,7 @@ void ahci_uninit(AHCIState *s)
>  
>              ide_exit(s);
>          }
> +        object_unparent(OBJECT(&ad->port));
>      }
>  
>      g_free(s->dev);
> 

Thanks, this fixes the problem for me with both, x86_64 and mips64el!

Tested-by: Thomas Huth <thuth@redhat.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.11] ide: ahci: unparent children buses before freeing their memory
  2017-08-28 16:34 [Qemu-devel] [PATCH for-2.11] ide: ahci: unparent children buses before freeing their memory Igor Mammedov
  2017-08-28 16:59 ` Philippe Mathieu-Daudé
  2017-08-28 17:56 ` Thomas Huth
@ 2017-08-28 18:08 ` Michael S. Tsirkin
  2017-08-28 22:41 ` John Snow
  3 siblings, 0 replies; 5+ messages in thread
From: Michael S. Tsirkin @ 2017-08-28 18:08 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel, jsnow, qemu-block, thuth, f4bug

On Mon, Aug 28, 2017 at 06:34:45PM +0200, Igor Mammedov wrote:
> 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: Michael S. Tsirkin <mst@redhat.com>

Pls merge through ide tree.

> ---
>  hw/ide/ahci.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 406a1b5..ccbe091 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -1495,6 +1495,7 @@ void ahci_uninit(AHCIState *s)
>  
>              ide_exit(s);
>          }
> +        object_unparent(OBJECT(&ad->port));
>      }
>  
>      g_free(s->dev);
> -- 
> 2.7.4

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.11] ide: ahci: unparent children buses before freeing their memory
  2017-08-28 16:34 [Qemu-devel] [PATCH for-2.11] ide: ahci: unparent children buses before freeing their memory Igor Mammedov
                   ` (2 preceding siblings ...)
  2017-08-28 18:08 ` Michael S. Tsirkin
@ 2017-08-28 22:41 ` John Snow
  3 siblings, 0 replies; 5+ messages in thread
From: John Snow @ 2017-08-28 22:41 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel; +Cc: thuth, f4bug, qemu-block, mst



On 08/28/2017 12:34 PM, Igor Mammedov wrote:
> 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>
> ---
>  hw/ide/ahci.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 406a1b5..ccbe091 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -1495,6 +1495,7 @@ void ahci_uninit(AHCIState *s)
>  
>              ide_exit(s);
>          }
> +        object_unparent(OBJECT(&ad->port));
>      }
>  
>      g_free(s->dev);
> 

Nice, Thank you.

Reviewed-by: John Snow <jsnow@redhat.com>

Thanks, applied to my IDE tree:

https://github.com/jnsnow/qemu/commits/ide
https://github.com/jnsnow/qemu.git

--js

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-08-28 22:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-28 16:34 [Qemu-devel] [PATCH for-2.11] ide: ahci: unparent children buses before freeing their memory Igor Mammedov
2017-08-28 16:59 ` Philippe Mathieu-Daudé
2017-08-28 17:56 ` Thomas Huth
2017-08-28 18:08 ` Michael S. Tsirkin
2017-08-28 22:41 ` John Snow

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.