On Mon, Mar 09, 2020 at 10:51:45AM +0100, Igor Mammedov wrote: > On Mon, 9 Mar 2020 17:22:12 +0800 > Pan Nengyuan <pannengy...@huawei.com> wrote: > > > 'type/id' forgot to free in qmp_object_add, this patch fix that. > > > > The leak stack: > > Direct leak of 84 byte(s) in 6 object(s) allocated from: > > #0 0x7fe2a5ebf768 in __interceptor_malloc (/lib64/libasan.so.5+0xef768) > > #1 0x7fe2a5044445 in g_malloc (/lib64/libglib-2.0.so.0+0x52445) > > #2 0x7fe2a505dd92 in g_strdup (/lib64/libglib-2.0.so.0+0x6bd92) > > #3 0x56344954e692 in qmp_object_add > > /mnt/sdb/qemu-new/qemu_test/qemu/qom/qom-qmp-cmds.c:258 > > #4 0x563449960f5a in do_qmp_dispatch > > /mnt/sdb/qemu-new/qemu_test/qemu/qapi/qmp-dispatch.c:132 > > #5 0x563449960f5a in qmp_dispatch > > /mnt/sdb/qemu-new/qemu_test/qemu/qapi/qmp-dispatch.c:175 > > #6 0x563449498a30 in monitor_qmp_dispatch > > /mnt/sdb/qemu-new/qemu_test/qemu/monitor/qmp.c:145 > > #7 0x56344949a64f in monitor_qmp_bh_dispatcher > > /mnt/sdb/qemu-new/qemu_test/qemu/monitor/qmp.c:234 > > #8 0x563449a92a3a in aio_bh_call > > /mnt/sdb/qemu-new/qemu_test/qemu/util/async.c:136 > > > > Direct leak of 54 byte(s) in 6 object(s) allocated from: > > #0 0x7fe2a5ebf768 in __interceptor_malloc (/lib64/libasan.so.5+0xef768) > > #1 0x7fe2a5044445 in g_malloc (/lib64/libglib-2.0.so.0+0x52445) > > #2 0x7fe2a505dd92 in g_strdup (/lib64/libglib-2.0.so.0+0x6bd92) > > #3 0x56344954e6c4 in qmp_object_add > > /mnt/sdb/qemu-new/qemu_test/qemu/qom/qom-qmp-cmds.c:267 > > #4 0x563449960f5a in do_qmp_dispatch > > /mnt/sdb/qemu-new/qemu_test/qemu/qapi/qmp-dispatch.c:132 > > #5 0x563449960f5a in qmp_dispatch > > /mnt/sdb/qemu-new/qemu_test/qemu/qapi/qmp-dispatch.c:175 > > #6 0x563449498a30 in monitor_qmp_dispatch > > /mnt/sdb/qemu-new/qemu_test/qemu/monitor/qmp.c:145 > > #7 0x56344949a64f in monitor_qmp_bh_dispatcher > > /mnt/sdb/qemu-new/qemu_test/qemu/monitor/qmp.c:234 > > #8 0x563449a92a3a in aio_bh_call > > /mnt/sdb/qemu-new/qemu_test/qemu/util/async.c:136 > > > > Fixes: 5f07c4d60d091320186e7b0edaf9ed2cc16b2d1e > > Reported-by: Euler Robot <euler.ro...@huawei.com> > > Signed-off-by: Pan Nengyuan <pannengy...@huawei.com> > > --- > > qom/qom-qmp-cmds.c | 4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c > > index 49db926fcc..ac59ba1aa8 100644 > > --- a/qom/qom-qmp-cmds.c > > +++ b/qom/qom-qmp-cmds.c > > @@ -247,8 +247,8 @@ void qmp_object_add(QDict *qdict, QObject **ret_data, > > Error **errp) > > QDict *pdict; > > Visitor *v; > > Object *obj; > > - const char *type; > > - const char *id; > > + g_autofree const char *type = NULL; > > + g_autofree const char *id = NULL; > > not sure that's it's correct > > qdict_get_try_str() returns the reference to a string within > the QDict, so caller who provided qdict should take care of > freeing it.
This is correct, but two lines later we have "type = g_strdup(type)". IOW, the code is storing both a const and non-const string in the same variable which is gross. So there's definitely a leak, but this is also not the right way to fix it. To fix it, notice that g_strdup says "Duplicates a string. If str is NULL it returns NULL. The returned string should be freed with g_free() when no longer needed." IOW, instead of const char *type; type = qdict_get_try_str(qdict, "qom-type"); if (!type) { error_setg(errp, QERR_MISSING_PARAMETER, "qom-type"); return; } else { type = g_strdup(type); qdict_del(qdict, "qom-type"); } we want g_autofree char *type = NULL; type = g_strdup(qdict_get_try_str(qdict, "qom-type")); if (!type) { error_setg(errp, QERR_MISSING_PARAMETER, "qom-type"); return; } qdict_del(qdict, "qom-type"); > > type = qdict_get_try_str(qdict, "qom-type"); > > if (!type) { Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|