diff options
author | Eduardo Habkost <ehabkost@redhat.com> | 2014-04-16 14:39:38 -0300 |
---|---|---|
committer | Luiz Capitulino <lcapitulino@redhat.com> | 2014-04-25 11:08:34 -0400 |
commit | c3481247e58ff3f13337ce0a262b058799bd156c (patch) | |
tree | f23c7e40beebc16fd106c46f9b437e82d873d8c0 /qmp.c | |
parent | 2da1b3abbccd267f09ebda7ba604fbbb0220f406 (diff) | |
download | qemu-c3481247e58ff3f13337ce0a262b058799bd156c.tar.gz qemu-c3481247e58ff3f13337ce0a262b058799bd156c.tar.bz2 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>
Diffstat (limited to 'qmp.c')
-rw-r--r-- | qmp.c | 21 |
1 files changed, 14 insertions, 7 deletions
@@ -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; |