The DO_OBJECT_DEFINE_TYPE_EXTENDED macro requires callers to manually append a NULL sentinel to the interfaces list. Forgetting it causes out-of-bounds reads during type registration, leading to run-time crashes.
Append an empty initializer in the base macro so the sentinel is always present, and drop the now-redundant manual terminators from all callers. Signed-off-by: Marc-André Lureau <[email protected]> --- backends/igvm-cfg.c | 3 +-- hw/acpi/pci.c | 6 ++---- hw/core/reset.c | 4 +++- hw/core/resetcontainer.c | 5 ++++- hw/hyperv/hv-balloon.c | 2 +- hw/ppc/pef.c | 3 +-- hw/virtio/virtio-mem.c | 6 +++++- include/qom/object.h | 6 +++--- system/ram-block-attributes.c | 3 +-- target/i386/kvm/tdx.c | 3 +-- target/s390x/kvm/pv.c | 3 +-- 11 files changed, 23 insertions(+), 21 deletions(-) diff --git a/backends/igvm-cfg.c b/backends/igvm-cfg.c index 935ba54f54f3..8ec7d4ab6174 100644 --- a/backends/igvm-cfg.c +++ b/backends/igvm-cfg.c @@ -72,8 +72,7 @@ static void igvm_complete(UserCreatable *uc, Error **errp) OBJECT_DEFINE_TYPE_WITH_INTERFACES(IgvmCfg, igvm_cfg, IGVM_CFG, OBJECT, { TYPE_USER_CREATABLE }, - { TYPE_RESETTABLE_INTERFACE }, - { NULL }) + { TYPE_RESETTABLE_INTERFACE }) static void igvm_cfg_class_init(ObjectClass *oc, const void *data) { diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c index c82924be8620..5a96c0e77817 100644 --- a/hw/acpi/pci.c +++ b/hw/acpi/pci.c @@ -83,8 +83,7 @@ typedef struct AcpiGenericInitiatorClass { OBJECT_DEFINE_TYPE_WITH_INTERFACES(AcpiGenericInitiator, acpi_generic_initiator, ACPI_GENERIC_INITIATOR, OBJECT, - { TYPE_USER_CREATABLE }, - { NULL }) + { TYPE_USER_CREATABLE }) OBJECT_DECLARE_SIMPLE_TYPE(AcpiGenericInitiator, ACPI_GENERIC_INITIATOR) @@ -199,8 +198,7 @@ typedef struct AcpiGenericPortClass { OBJECT_DEFINE_TYPE_WITH_INTERFACES(AcpiGenericPort, acpi_generic_port, ACPI_GENERIC_PORT, OBJECT, - { TYPE_USER_CREATABLE }, - { NULL }) + { TYPE_USER_CREATABLE }) OBJECT_DECLARE_SIMPLE_TYPE(AcpiGenericPort, ACPI_GENERIC_PORT) diff --git a/hw/core/reset.c b/hw/core/reset.c index e7230b49b704..c35ac9b9c9a7 100644 --- a/hw/core/reset.c +++ b/hw/core/reset.c @@ -58,7 +58,9 @@ struct LegacyReset { bool skip_on_snapshot_load; }; -OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(LegacyReset, legacy_reset, LEGACY_RESET, OBJECT, { TYPE_RESETTABLE_INTERFACE }, { }) +OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(LegacyReset, legacy_reset, + LEGACY_RESET, OBJECT, + { TYPE_RESETTABLE_INTERFACE }) static ResettableState *legacy_reset_get_state(Object *obj) { diff --git a/hw/core/resetcontainer.c b/hw/core/resetcontainer.c index a4a6476a0363..cc46a1c62b82 100644 --- a/hw/core/resetcontainer.c +++ b/hw/core/resetcontainer.c @@ -24,7 +24,10 @@ struct ResettableContainer { GPtrArray *children; }; -OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(ResettableContainer, resettable_container, RESETTABLE_CONTAINER, OBJECT, { TYPE_RESETTABLE_INTERFACE }, { }) +OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(ResettableContainer, + resettable_container, + RESETTABLE_CONTAINER, OBJECT, + { TYPE_RESETTABLE_INTERFACE }) void resettable_container_add(ResettableContainer *rc, Object *obj) { diff --git a/hw/hyperv/hv-balloon.c b/hw/hyperv/hv-balloon.c index b8664a246b47..36e54c6a4c26 100644 --- a/hw/hyperv/hv-balloon.c +++ b/hw/hyperv/hv-balloon.c @@ -160,7 +160,7 @@ typedef struct HvBalloon { OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(HvBalloon, hv_balloon, \ HV_BALLOON, VMBUS_DEVICE, \ - { TYPE_MEMORY_DEVICE }, { }) + { TYPE_MEMORY_DEVICE }) #define HV_BALLOON_SET_STATE(hvb, news) \ do { \ diff --git a/hw/ppc/pef.c b/hw/ppc/pef.c index 39b4ce94f10b..a055774caebc 100644 --- a/hw/ppc/pef.c +++ b/hw/ppc/pef.c @@ -124,8 +124,7 @@ OBJECT_DEFINE_TYPE_WITH_INTERFACES(PefGuest, pef_guest, PEF_GUEST, CONFIDENTIAL_GUEST_SUPPORT, - { TYPE_USER_CREATABLE }, - { NULL }) + { TYPE_USER_CREATABLE }) static void pef_guest_class_init(ObjectClass *oc, const void *data) { diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c index 7130ed852d9c..488ee25dec53 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -1681,7 +1681,11 @@ static void virtio_register_types(void) type_init(virtio_register_types) -OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(VirtioMemSystemReset, virtio_mem_system_reset, VIRTIO_MEM_SYSTEM_RESET, OBJECT, { TYPE_RESETTABLE_INTERFACE }, { }) +OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(VirtioMemSystemReset, + virtio_mem_system_reset, + VIRTIO_MEM_SYSTEM_RESET, + OBJECT, + { TYPE_RESETTABLE_INTERFACE }) static void virtio_mem_system_reset_init(Object *obj) { diff --git a/include/qom/object.h b/include/qom/object.h index 328521866463..24727906ec02 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -294,7 +294,7 @@ struct Object .class_size = CLASS_SIZE, \ .class_init = module_obj_name##_class_init, \ .abstract = ABSTRACT, \ - .interfaces = (const InterfaceInfo[]) { __VA_ARGS__ } , \ + .interfaces = (const InterfaceInfo[]) { __VA_ARGS__, { } } , \ }; \ \ static void \ @@ -365,8 +365,8 @@ struct Object * for the common case of a non-abstract type, with one or more implemented * interfaces. * - * Note when passing the list of interfaces, be sure to include the final - * NULL entry, e.g. { TYPE_USER_CREATABLE }, { NULL } + * The NULL terminator is added automatically by the macro, so only + * the actual interfaces need to be listed, e.g. { TYPE_USER_CREATABLE } */ #define OBJECT_DEFINE_TYPE_WITH_INTERFACES(ModuleObjName, module_obj_name, \ MODULE_OBJ_NAME, \ diff --git a/system/ram-block-attributes.c b/system/ram-block-attributes.c index 59ec7a28eb05..4ef70b5a4082 100644 --- a/system/ram-block-attributes.c +++ b/system/ram-block-attributes.c @@ -18,8 +18,7 @@ OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(RamBlockAttributes, ram_block_attributes, RAM_BLOCK_ATTRIBUTES, OBJECT, - { TYPE_RAM_DISCARD_SOURCE }, - { }) + { TYPE_RAM_DISCARD_SOURCE }) static size_t ram_block_attributes_get_block_size(void) diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c index 8294dbde3aa8..f1fa9e7ffe2b 100644 --- a/target/i386/kvm/tdx.c +++ b/target/i386/kvm/tdx.c @@ -1559,8 +1559,7 @@ OBJECT_DEFINE_TYPE_WITH_INTERFACES(TdxGuest, TDX_GUEST, X86_CONFIDENTIAL_GUEST, { TYPE_USER_CREATABLE }, - { TYPE_RESETTABLE_INTERFACE }, - { NULL }) + { TYPE_RESETTABLE_INTERFACE }) static void tdx_guest_init(Object *obj) { diff --git a/target/s390x/kvm/pv.c b/target/s390x/kvm/pv.c index 3d508165f348..8d4a7b5275e1 100644 --- a/target/s390x/kvm/pv.c +++ b/target/s390x/kvm/pv.c @@ -402,8 +402,7 @@ OBJECT_DEFINE_TYPE_WITH_INTERFACES(S390PVGuest, s390_pv_guest, S390_PV_GUEST, CONFIDENTIAL_GUEST_SUPPORT, - { TYPE_USER_CREATABLE }, - { NULL }) + { TYPE_USER_CREATABLE }) static void s390_pv_guest_class_init(ObjectClass *oc, const void *data) { -- 2.56.0.rc0.29.g47ce80527c56
