[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] qmp: object-add: Validate class before creating
From: |
Eduardo Habkost |
Subject: |
Re: [Qemu-devel] [PATCH] qmp: object-add: Validate class before creating object |
Date: |
Wed, 16 Apr 2014 14:39:20 -0300 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Wed, Apr 16, 2014 at 08:53:23AM +0200, Markus Armbruster wrote:
> Eduardo Habkost <address@hidden> writes:
>
> > 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 <address@hidden>
>
> Related device_add fixes:
>
> 061e84f qdev-monitor: Avoid device_add crashing on non-device driver name
> 2fa4e56 qdev-monitor: Fix crash when device_add is called with abstract driver
> 7ea5e78 qdev: Do not let the user try to device_add when it cannot work
>
> > ---
> > qmp.c | 21 ++++++++++++++-------
> > 1 file changed, 14 insertions(+), 7 deletions(-)
> >
> > diff --git a/qmp.c b/qmp.c
> > index 87a28f7..e7ecbb7 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_is_abstract(klass)) {
> > + error_setg(errp, "object type '%s' is abstract", type);
> > + return;
> > + }
> > +
> > + if (!object_class_dynamic_cast(klass, TYPE_USER_CREATABLE)) {
> > + error_setg(errp, "object type '%s' isn't supported by object-add",
> > + type);
> > + return;
> > + }
> > +
> > obj = object_new(type);
> > if (qdict) {
> > for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
>
> For comparison, this is qdev_device_add():
>
> oc = object_class_by_name(driver);
> if (!oc) {
> const char *typename = find_typename_by_alias(driver);
>
> if (typename) {
> driver = typename;
> oc = object_class_by_name(driver);
> }
> }
>
> if (!object_class_dynamic_cast(oc, TYPE_DEVICE)) {
> qerror_report(ERROR_CLASS_GENERIC_ERROR,
> "'%s' is not a valid device model name", driver);
> return NULL;
> }
>
> if (object_class_is_abstract(oc)) {
> qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver",
> "non-abstract device type");
> return NULL;
> }
>
> dc = DEVICE_CLASS(oc);
> if (dc->cannot_instantiate_with_device_add_yet) {
> qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver",
> "pluggable device type");
> return NULL;
> }
>
> Got the "subtype of" and the "not abstract" check in the opposite order,
> and the additional cannot_instantiate_with_device_add_yet check.
>
> Does the different order matter?
The order probably doesn't matter very much. But it makes sense to keep
it similar to device_add for consistency. I will send v2.
> > @@ -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;
--
Eduardo