* [Qemu-devel] [PATCH 1.3 0/2] "drive_add NN if=scsi" fixes @ 2012-11-23 15:56 Paolo Bonzini 2012-11-23 15:56 ` [Qemu-devel] [PATCH 1.3 1/2] qom: dynamic_cast of NULL is always NULL Paolo Bonzini ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Paolo Bonzini @ 2012-11-23 15:56 UTC (permalink / raw) To: qemu-devel; +Cc: aliguori, armbru, lcapitulino Reported by Markus, and a regression from 1.1. Not really SCSI stuff, just happens to have it in the name, so I'm not sending it through my tree. Paolo Bonzini (2): qom: dynamic_cast of NULL is always NULL hmp: do not crash on invalid SCSI hotplug hw/pci-hotplug.c | 8 +++++++- qom/object.c | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) -- 1.8.0 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 1.3 1/2] qom: dynamic_cast of NULL is always NULL 2012-11-23 15:56 [Qemu-devel] [PATCH 1.3 0/2] "drive_add NN if=scsi" fixes Paolo Bonzini @ 2012-11-23 15:56 ` Paolo Bonzini 2012-11-23 16:16 ` Andreas Färber 2012-11-23 15:56 ` [Qemu-devel] [PATCH 1.3 2/2] hmp: do not crash on invalid SCSI hotplug Paolo Bonzini 2012-11-26 21:48 ` [Qemu-devel] [PATCH 1.3 0/2] "drive_add NN if=scsi" fixes Anthony Liguori 2 siblings, 1 reply; 9+ messages in thread From: Paolo Bonzini @ 2012-11-23 15:56 UTC (permalink / raw) To: qemu-devel; +Cc: aliguori, armbru, lcapitulino Trying to cast a NULL value will cause a crash. Returning NULL is also sensible, and it is also what the type-unsafe DO_UPCAST macro does. Reported-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- qom/object.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qom/object.c b/qom/object.c index d7092b0..2e18c9a 100644 --- a/qom/object.c +++ b/qom/object.c @@ -417,7 +417,7 @@ void object_delete(Object *obj) Object *object_dynamic_cast(Object *obj, const char *typename) { - if (object_class_dynamic_cast(object_get_class(obj), typename)) { + if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) { return obj; } @@ -430,7 +430,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename) inst = object_dynamic_cast(obj, typename); - if (!inst) { + if (!inst && obj) { fprintf(stderr, "Object %p is not an instance of type %s\n", obj, typename); abort(); -- 1.8.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1.3 1/2] qom: dynamic_cast of NULL is always NULL 2012-11-23 15:56 ` [Qemu-devel] [PATCH 1.3 1/2] qom: dynamic_cast of NULL is always NULL Paolo Bonzini @ 2012-11-23 16:16 ` Andreas Färber 2012-11-23 16:25 ` Paolo Bonzini 0 siblings, 1 reply; 9+ messages in thread From: Andreas Färber @ 2012-11-23 16:16 UTC (permalink / raw) To: Paolo Bonzini; +Cc: aliguori, lcapitulino, qemu-devel, armbru Am 23.11.2012 16:56, schrieb Paolo Bonzini: > Trying to cast a NULL value will cause a crash. Returning > NULL is also sensible, and it is also what the type-unsafe > DO_UPCAST macro does. > > Reported-by: Markus Armbruster <armbru@redhat.com> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> I believe we had a lengthy discussion of where to place the NULL checks... seems that was never followed up with a v2 then. In practice however most of NULL assertions stem from misuses of the cast macros, i.e. using them before qdev_create() or so, which we should not hide because they lead to segfaults later. > --- > qom/object.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/qom/object.c b/qom/object.c > index d7092b0..2e18c9a 100644 > --- a/qom/object.c > +++ b/qom/object.c > @@ -417,7 +417,7 @@ void object_delete(Object *obj) > > Object *object_dynamic_cast(Object *obj, const char *typename) > { > - if (object_class_dynamic_cast(object_get_class(obj), typename)) { > + if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) { > return obj; > } > This is followed by return NULL; Ack on this part. > @@ -430,7 +430,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename) > > inst = object_dynamic_cast(obj, typename); > > - if (!inst) { > + if (!inst && obj) { > fprintf(stderr, "Object %p is not an instance of type %s\n", > obj, typename); > abort(); This is followed by return inst; Since this function clearly has assert in the name I don't think this is right. I would expect %p to print 0x0 and the function to abort. Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1.3 1/2] qom: dynamic_cast of NULL is always NULL 2012-11-23 16:16 ` Andreas Färber @ 2012-11-23 16:25 ` Paolo Bonzini 2012-11-23 16:30 ` Andreas Färber 0 siblings, 1 reply; 9+ messages in thread From: Paolo Bonzini @ 2012-11-23 16:25 UTC (permalink / raw) To: Andreas Färber; +Cc: aliguori, lcapitulino, qemu-devel, armbru Il 23/11/2012 17:16, Andreas Färber ha scritto: >> > @@ -430,7 +430,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename) >> > >> > inst = object_dynamic_cast(obj, typename); >> > >> > - if (!inst) { >> > + if (!inst && obj) { >> > fprintf(stderr, "Object %p is not an instance of type %s\n", >> > obj, typename); >> > abort(); > This is followed by return inst; > > Since this function clearly has assert in the name I don't think this is > right. I would expect %p to print 0x0 and the function to abort. I think it's okay to segfault in this case. Otherwise you need to replace this simple cast+check pair: SCSIDevice *s = SCSI_DEVICE(some->long.expressio[n]); if (!s) { return; } with something that is more complex: DeviceState *d = some->long.expressio[n]; SCSIDevice *s; if (!d) { return; } s = SCSI_DEVICE(d); Paolo ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1.3 1/2] qom: dynamic_cast of NULL is always NULL 2012-11-23 16:25 ` Paolo Bonzini @ 2012-11-23 16:30 ` Andreas Färber 2012-11-23 16:51 ` Paolo Bonzini 0 siblings, 1 reply; 9+ messages in thread From: Andreas Färber @ 2012-11-23 16:30 UTC (permalink / raw) To: Paolo Bonzini; +Cc: aliguori, lcapitulino, qemu-devel, armbru Am 23.11.2012 17:25, schrieb Paolo Bonzini: > Il 23/11/2012 17:16, Andreas Färber ha scritto: >>>> @@ -430,7 +430,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename) >>>> >>>> inst = object_dynamic_cast(obj, typename); >>>> >>>> - if (!inst) { >>>> + if (!inst && obj) { >>>> fprintf(stderr, "Object %p is not an instance of type %s\n", >>>> obj, typename); >>>> abort(); >> This is followed by return inst; >> >> Since this function clearly has assert in the name I don't think this is >> right. I would expect %p to print 0x0 and the function to abort. > > I think it's okay to segfault in this case. > > Otherwise you need to replace this simple cast+check pair: > > SCSIDevice *s = SCSI_DEVICE(some->long.expressio[n]); > if (!s) { > return; > } > > with something that is more complex: > > DeviceState *d = some->long.expressio[n]; > SCSIDevice *s; > > if (!d) { > return; > } > s = SCSI_DEVICE(d); Right now our use of those macros guarantees that the result is never NULL, so there are no such checks! That expectation is broken by your patch - I'm guessing without reviewing all derived macros. If having SCSI_BUS() return NULL was your intent you would not have needed to switch to object_dynamic_cast in your second patch. :) But let's leave it for Anthony to decide how he wants his macros to work. ;) Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1.3 1/2] qom: dynamic_cast of NULL is always NULL 2012-11-23 16:30 ` Andreas Färber @ 2012-11-23 16:51 ` Paolo Bonzini 0 siblings, 0 replies; 9+ messages in thread From: Paolo Bonzini @ 2012-11-23 16:51 UTC (permalink / raw) To: Andreas Färber; +Cc: aliguori, lcapitulino, qemu-devel, armbru Il 23/11/2012 17:30, Andreas Färber ha scritto: > If having SCSI_BUS() return NULL was your intent you would not have > needed to switch to object_dynamic_cast in your second patch. :) In the second patch I needed object_dynamic_cast in case the bus was not a SCSI bus at all. For example: $ qemu-system-x86_64 -S -monitor stdio -device piix3-usb-uhci (qemu) drive_add 4 if=scsi Object 0x7f2dcdcfe380 is not an instance of type SCSI Aborted Paolo ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 1.3 2/2] hmp: do not crash on invalid SCSI hotplug 2012-11-23 15:56 [Qemu-devel] [PATCH 1.3 0/2] "drive_add NN if=scsi" fixes Paolo Bonzini 2012-11-23 15:56 ` [Qemu-devel] [PATCH 1.3 1/2] qom: dynamic_cast of NULL is always NULL Paolo Bonzini @ 2012-11-23 15:56 ` Paolo Bonzini 2012-11-26 12:50 ` Luiz Capitulino 2012-11-26 21:48 ` [Qemu-devel] [PATCH 1.3 0/2] "drive_add NN if=scsi" fixes Anthony Liguori 2 siblings, 1 reply; 9+ messages in thread From: Paolo Bonzini @ 2012-11-23 15:56 UTC (permalink / raw) To: qemu-devel; +Cc: aliguori, armbru, lcapitulino Commit 0d93692 (qdev: Convert busses to QEMU Object Model, 2012-05-02) removed a check on the type of the bus where a SCSI disk is hotplugged. However, hot-plugging to the wrong kind of device now causes a crash due to either a NULL pointer dereference (avoided by the previous patch) or a failed QOM cast. Instead, in this case we need to use object_dynamic_cast and check for the result, similar to what was done before that commit. Reported-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- hw/pci-hotplug.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index e7fb780..0ca5546 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -80,7 +80,13 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter, SCSIBus *scsibus; SCSIDevice *scsidev; - scsibus = SCSI_BUS(QLIST_FIRST(&adapter->child_bus)); + scsibus = (SCSIBus *) + object_dynamic_cast(OBJECT(QLIST_FIRST(&adapter->child_bus)), + TYPE_SCSI_BUS); + if (!scsibus) { + error_report("Device is not a SCSI adapter"); + return -1; + } /* * drive_init() tries to find a default for dinfo->unit. Doesn't -- 1.8.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1.3 2/2] hmp: do not crash on invalid SCSI hotplug 2012-11-23 15:56 ` [Qemu-devel] [PATCH 1.3 2/2] hmp: do not crash on invalid SCSI hotplug Paolo Bonzini @ 2012-11-26 12:50 ` Luiz Capitulino 0 siblings, 0 replies; 9+ messages in thread From: Luiz Capitulino @ 2012-11-26 12:50 UTC (permalink / raw) To: Paolo Bonzini; +Cc: aliguori, qemu-devel, armbru On Fri, 23 Nov 2012 16:56:18 +0100 Paolo Bonzini <pbonzini@redhat.com> wrote: > Commit 0d93692 (qdev: Convert busses to QEMU Object Model, 2012-05-02) > removed a check on the type of the bus where a SCSI disk is hotplugged. > However, hot-plugging to the wrong kind of device now causes a crash > due to either a NULL pointer dereference (avoided by the previous patch) > or a failed QOM cast. > > Instead, in this case we need to use object_dynamic_cast and check for > the result, similar to what was done before that commit. > > Reported-by: Markus Armbruster <armbru@redhat.com> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> As far as HMP is concerned this looks good. > --- > hw/pci-hotplug.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c > index e7fb780..0ca5546 100644 > --- a/hw/pci-hotplug.c > +++ b/hw/pci-hotplug.c > @@ -80,7 +80,13 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter, > SCSIBus *scsibus; > SCSIDevice *scsidev; > > - scsibus = SCSI_BUS(QLIST_FIRST(&adapter->child_bus)); > + scsibus = (SCSIBus *) > + object_dynamic_cast(OBJECT(QLIST_FIRST(&adapter->child_bus)), > + TYPE_SCSI_BUS); > + if (!scsibus) { > + error_report("Device is not a SCSI adapter"); > + return -1; > + } > > /* > * drive_init() tries to find a default for dinfo->unit. Doesn't ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1.3 0/2] "drive_add NN if=scsi" fixes 2012-11-23 15:56 [Qemu-devel] [PATCH 1.3 0/2] "drive_add NN if=scsi" fixes Paolo Bonzini 2012-11-23 15:56 ` [Qemu-devel] [PATCH 1.3 1/2] qom: dynamic_cast of NULL is always NULL Paolo Bonzini 2012-11-23 15:56 ` [Qemu-devel] [PATCH 1.3 2/2] hmp: do not crash on invalid SCSI hotplug Paolo Bonzini @ 2012-11-26 21:48 ` Anthony Liguori 2 siblings, 0 replies; 9+ messages in thread From: Anthony Liguori @ 2012-11-26 21:48 UTC (permalink / raw) To: Paolo Bonzini, qemu-devel; +Cc: armbru, lcapitulino Paolo Bonzini <pbonzini@redhat.com> writes: > Reported by Markus, and a regression from 1.1. Not really SCSI stuff, > just happens to have it in the name, so I'm not sending it through my tree. > > Paolo Bonzini (2): > qom: dynamic_cast of NULL is always NULL > hmp: do not crash on invalid SCSI hotplug > > hw/pci-hotplug.c | 8 +++++++- > qom/object.c | 4 ++-- > 2 files changed, 9 insertions(+), 3 deletions(-) Applied. Thanks. Regards, Anthony Liguori > > -- > 1.8.0 ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-11-26 21:48 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-11-23 15:56 [Qemu-devel] [PATCH 1.3 0/2] "drive_add NN if=scsi" fixes Paolo Bonzini 2012-11-23 15:56 ` [Qemu-devel] [PATCH 1.3 1/2] qom: dynamic_cast of NULL is always NULL Paolo Bonzini 2012-11-23 16:16 ` Andreas Färber 2012-11-23 16:25 ` Paolo Bonzini 2012-11-23 16:30 ` Andreas Färber 2012-11-23 16:51 ` Paolo Bonzini 2012-11-23 15:56 ` [Qemu-devel] [PATCH 1.3 2/2] hmp: do not crash on invalid SCSI hotplug Paolo Bonzini 2012-11-26 12:50 ` Luiz Capitulino 2012-11-26 21:48 ` [Qemu-devel] [PATCH 1.3 0/2] "drive_add NN if=scsi" fixes Anthony Liguori
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).