On 04/16/2014 01:39 PM, Eduardo Habkost wrote: > 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 <ehabk...@redhat.com> > --- > Changes v2: > * Change ordering: first check for TYPE_USER_CREATABLE and then check > if class is abstract. This makes the ordering of checks closer to > what's already done on device_add.
Changes look fine to me, re-tested to verify. Reviewed-by: Matthew Rosato <mjros...@linux.vnet.ibm.com> Tested-by: Matthew Rosato <mjros...@linux.vnet.ibm.com> > --- > qmp.c | 21 ++++++++++++++------- > 1 file changed, 14 insertions(+), 7 deletions(-) > > diff --git a/qmp.c b/qmp.c > index 87a28f7..9a93ab1 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; >