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;
> 


Reply via email to