qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [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

* [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 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

* 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).