From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51476) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WteHV-0008L7-Gs for qemu-devel@nongnu.org; Sun, 08 Jun 2014 10:41:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WteHM-0006Kn-Fk for qemu-devel@nongnu.org; Sun, 08 Jun 2014 10:41:09 -0400 Received: from mail-wg0-x230.google.com ([2a00:1450:400c:c00::230]:56106) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WteHM-0006Ka-8i for qemu-devel@nongnu.org; Sun, 08 Jun 2014 10:41:00 -0400 Received: by mail-wg0-f48.google.com with SMTP id n12so4450636wgh.31 for ; Sun, 08 Jun 2014 07:40:58 -0700 (PDT) Sender: Paolo Bonzini Message-ID: <539475F8.3060200@redhat.com> Date: Sun, 08 Jun 2014 16:40:56 +0200 From: Paolo Bonzini MIME-Version: 1.0 References: <20140605161803.GB11292@redhat.com> <53918F6E.1020406@redhat.com> <20140608104626.GA26245@redhat.com> In-Reply-To: <20140608104626.GA26245@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] Use-after-free during unrealize in system_reset List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Michael S. Tsirkin" Cc: peter.maydell@linaro.org, bsd@redhat.com, qemu-devel , =?ISO-8859-1?Q?Andre?= =?ISO-8859-1?Q?as_F=E4rber?= , Stefan Hajnoczi Il 08/06/2014 12:46, Michael S. Tsirkin ha scritto: > Tested-by: Michael S. Tsirkin You probably tested the reversal, actually. :) Actually, there is a reason for it. "Unassembling" the device (unparent) should come after "powering it down" (unrealize). However, the bus is missing a recursive unrealization of the devices below it prior to calling bc->unrealize: diff --git a/hw/core/qdev.c b/hw/core/qdev.c index e65a5aa..4282491 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -567,32 +567,35 @@ static void bus_set_realized(Object *obj, bool value, Error **errp) { BusState *bus = BUS(obj); BusClass *bc = BUS_GET_CLASS(bus); + BusChild *kid; Error *local_err = NULL; if (value && !bus->realized) { if (bc->realize) { bc->realize(bus, &local_err); - - if (local_err != NULL) { - goto error; - } - } + + /* TODO: recursive realization */ } else if (!value && bus->realized) { - if (bc->unrealize) { + QTAILQ_FOREACH(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; + object_property_set_bool(OBJECT(dev), false, "realized", + &local_err); + if (local_err != NULL) { + break; + } + } + if (bc->unrealize && local_err == NULL) { bc->unrealize(bus, &local_err); - - if (local_err != NULL) { - goto error; - } } } + if (local_err != NULL) { + error_propagate(errp, local_err); + return; + } + bus->realized = value; - return; - -error: - error_propagate(errp, local_err); } void qbus_create_inplace(void *bus, size_t size, const char *typename, This seems to fix the bug too. Paolo