• Luiz Capitulino's avatar
    qapi: qapi-commands: fix possible leaks on visitor dealloc · 8f91ad8a
    Luiz Capitulino authored
    In qmp-marshal.c the dealloc visitor calls use the same errp
    pointer of the input visitor calls. This means that if any of
    the input visitor calls fails, then the dealloc visitor will
    return early, before freeing the object's memory.
    
    Here's an example, consider this code:
    
    int qmp_marshal_input_block_passwd(Monitor *mon, const QDict *qdict, QObject **ret)
    {
    	[...]
    
        char * device = NULL;
        char * password = NULL;
    
        mi = qmp_input_visitor_new_strict(QOBJECT(args));
        v = qmp_input_get_visitor(mi);
        visit_type_str(v, &device, "device", errp);
        visit_type_str(v, &password, "password", errp);
        qmp_input_visitor_cleanup(mi);
    
        if (error_is_set(errp)) {
            goto out;
        }
        qmp_block_passwd(device, password, errp);
    
    out:
        md = qapi_dealloc_visitor_new();
        v = qapi_dealloc_get_visitor(md);
        visit_type_str(v, &device, "device", errp);
        visit_type_str(v, &password, "password", errp);
        qapi_dealloc_visitor_cleanup(md);
    
    	[...]
    
        return 0;
    }
    
    Consider errp != NULL when the out label is reached, we're going
    to leak device and password.
    
    This patch fixes this by always passing errp=NULL for dealloc
    visitors, meaning that we always try to free them regardless of
    any previous failure. The above example would then be:
    
    out:
        md = qapi_dealloc_visitor_new();
        v = qapi_dealloc_get_visitor(md);
        visit_type_str(v, &device, "device", NULL);
        visit_type_str(v, &password, "password", NULL);
        qapi_dealloc_visitor_cleanup(md);
    Signed-off-by: default avatarLuiz Capitulino <lcapitulino@redhat.com>
    Reviewed-by: default avatarLaszlo Ersek <lersek@redhat.com>
    Reviewed-by: default avatarMichael Roth <mdroth@linux.vnet.ibm.com>
    8f91ad8a
qapi-commands.py 12 KB