From: Marc-André Lureau <[email protected]>
The OPBus instance_init initializes an AddressSpace, registering it in
the global address_spaces list. When a bare OPBus object is created
and destroyed (e.g. by qom-tests), there is no finalize to remove the
stale entry, leading to a heap-use-after-free when a subsequent
flatviews_reset iterates the list.
Move address_space_init to the bus realize callback and add the
corresponding address_space_destroy in unrealize, following the
NubusBus pattern. Also fix the memory_region_init owner from NULL to
the OPBus object, so the MR is properly parented instead of dangling
under the "unattached" container.
Fixes: eb04c35da2c0 ("hw/fsi: Aspeed APB2OPB & On-chip peripheral bus")
Reviewed-by: Cédric Le Goater <[email protected]>
Signed-off-by: Marc-André Lureau <[email protected]>
---
hw/fsi/aspeed_apb2opb.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/hw/fsi/aspeed_apb2opb.c b/hw/fsi/aspeed_apb2opb.c
index b9d72f3ecf6..36092468391 100644
--- a/hw/fsi/aspeed_apb2opb.c
+++ b/hw/fsi/aspeed_apb2opb.c
@@ -348,15 +348,37 @@ static void fsi_opb_init(Object *o)
{
OPBus *opb = OP_BUS(o);
- memory_region_init(&opb->mr, 0, TYPE_FSI_OPB, UINT32_MAX);
+ memory_region_init(&opb->mr, o, TYPE_FSI_OPB, UINT32_MAX);
+}
+
+static void fsi_opb_realize(BusState *bus, Error **errp)
+{
+ OPBus *opb = OP_BUS(bus);
+
address_space_init(&opb->as, &opb->mr, TYPE_FSI_OPB);
}
+static void fsi_opb_unrealize(BusState *bus)
+{
+ OPBus *opb = OP_BUS(bus);
+
+ address_space_destroy(&opb->as);
+}
+
+static void fsi_opb_class_init(ObjectClass *klass, const void *data)
+{
+ BusClass *bc = BUS_CLASS(klass);
+
+ bc->realize = fsi_opb_realize;
+ bc->unrealize = fsi_opb_unrealize;
+}
+
static const TypeInfo opb_info = {
.name = TYPE_OP_BUS,
.parent = TYPE_BUS,
.instance_init = fsi_opb_init,
.instance_size = sizeof(OPBus),
+ .class_init = fsi_opb_class_init,
};
static void fsi_opb_register_types(void)
--
2.54.0