summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorEduardo Habkost <ehabkost@redhat.com>2014-04-16 14:39:38 -0300
committerLuiz Capitulino <lcapitulino@redhat.com>2014-04-25 11:08:34 -0400
commitc3481247e58ff3f13337ce0a262b058799bd156c (patch)
treef23c7e40beebc16fd106c46f9b437e82d873d8c0
parent2da1b3abbccd267f09ebda7ba604fbbb0220f406 (diff)
downloadfocaccia-qemu-c3481247e58ff3f13337ce0a262b058799bd156c.tar.gz
focaccia-qemu-c3481247e58ff3f13337ce0a262b058799bd156c.zip
qmp: object-add: Validate class before creating object
Currently it is very easy to crash QEMU by issuing an object-add command
using an abstract class or a class that doesn't support
TYPE_USER_CREATABLE as parameter.

Example: with the following QMP command:

    (QEMU) object-add qom-type=cpu id=foo

QEMU aborts at:

    ERROR:qom/object.c:335:object_initialize_with_type: assertion failed: (type->abstract == false)

This patch moves the check for TYPE_USER_CREATABLE before object_new(),
and adds a check to prevent the code from trying to instantiate abstract
classes.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com>
Tested-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
-rw-r--r--qmp.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/qmp.c b/qmp.c
index 5e2a66caab..74107be41b 100644
--- a/qmp.c
+++ b/qmp.c
@@ -540,14 +540,27 @@ void object_add(const char *type, const char *id, const QDict *qdict,
                 Visitor *v, Error **errp)
 {
     Object *obj;
+    ObjectClass *klass;
     const QDictEntry *e;
     Error *local_err = NULL;
 
-    if (!object_class_by_name(type)) {
+    klass = object_class_by_name(type);
+    if (!klass) {
         error_setg(errp, "invalid class name");
         return;
     }
 
+    if (!object_class_dynamic_cast(klass, TYPE_USER_CREATABLE)) {
+        error_setg(errp, "object type '%s' isn't supported by object-add",
+                   type);
+        return;
+    }
+
+    if (object_class_is_abstract(klass)) {
+        error_setg(errp, "object type '%s' is abstract", type);
+        return;
+    }
+
     obj = object_new(type);
     if (qdict) {
         for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
@@ -558,12 +571,6 @@ void object_add(const char *type, const char *id, const QDict *qdict,
         }
     }
 
-    if (!object_dynamic_cast(obj, TYPE_USER_CREATABLE)) {
-        error_setg(&local_err, "object type '%s' isn't supported by object-add",
-                   type);
-        goto out;
-    }
-
     user_creatable_complete(obj, &local_err);
     if (local_err) {
         goto out;