[libvirt] [PATCH v8 2/4] Add vbox_snapshot_conf struct

John Ferlan jferlan at redhat.com
Wed Jun 11 13:02:49 UTC 2014


Ug... and trying to "locally" fix the RW/RO discovered two more issues...

On 06/11/2014 08:21 AM, John Ferlan wrote:
> 
> This patch has resulted in many new Coverity errors - mostly resource
> leaks as a result of the virVBoxSnapshotConfAllChildren() recursive
> function.  I would clean them up, but I'm a bit leary of missing some
> nuance in the original design.
> 
> There were also a couple of issues in
> virVBoxSnapshotConfGetRWDisksPathsFromLibvirtXML and
> virVBoxSnapshotConfGetRODisksPathsFromLibvirtXML
> 
> Details of the issues and some thoughts are inline below in the functions
> 
> These should be cleaned up before the next release...
> 
> John
> 

<...snip...>

>> +
>> +/*
>> + *getRWDisksPathsFromLibvirtXML: Parse a libvirt XML snapshot file, allocates and
>> + *fills a list of read-write disk paths.
>> + *return array length on success, -1 on failure.
>> + */
>> +int virVBoxSnapshotConfGetRWDisksPathsFromLibvirtXML(char *filePath, char ***rwDisksPath)
>> +{
>> +    int result = -1;
>> +    size_t i = 0;
>> +    char **ret;

Needs to be initialized to NULL (char **ret = NULL;)

>> +    xmlDocPtr xml = NULL;
>> +    xmlXPathContextPtr xPathContext = NULL;
>> +    xmlNodePtr *nodes = NULL;
>> +    int nodeSize = 0;
>> +    if (filePath == NULL) {
>> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>> +                       _("filePath is null"));
>> +        goto cleanup;
>> +    }
>> +    xml = virXMLParse(filePath, NULL, NULL);
>> +    if (xml == NULL) {
>> +        virReportError(VIR_ERR_XML_ERROR, "%s",
>> +                       _("Unable to parse the xml"));
>> +        goto cleanup;
>> +    }
>> +    if (!(xPathContext = xmlXPathNewContext(xml))) {
>> +        virReportOOMError();
>> +        goto cleanup;
>> +    }
>> +    xPathContext->node = xmlDocGetRootElement(xml);
>> +    nodeSize = virXPathNodeSet("/domainsnapshot/disks/disk", xPathContext, &nodes);
> Coverity comlains that nodeSize can be a negative number.  Other code in
> libvirt will do something like:
> 
>     if ((nodeSize = virXPathNodeSet("/domainsnapshot/disks/disk",
>                                     xPathContext, &nodes)) < 0)
>         goto cleanup;
> 
> 
>> +
>> +    if (VIR_ALLOC_N(ret, nodeSize) < 0)
>> +        goto cleanup;
>> +
>> +    for (i = 0; i < nodeSize; i++) {
>> +        xmlNodePtr node = nodes[i];
>> +        xPathContext->node = node;
>> +        xmlNodePtr sourceNode = virXPathNode("./source", xPathContext);
>> +        if (sourceNode) {
>> +            ret[i] = virXMLPropString(sourceNode, "file");
>> +        }
>> +    }
>> +    result = 0;
>> +
>> + cleanup:
>> +    xmlFreeDoc(xml);
>> +    xmlXPathFreeContext(xPathContext);
>> +    if (result < 0) {
>> +        virStringFreeList(ret);
>> +        nodeSize = -1;
>> +    }
>> +    *rwDisksPath = ret;
>> +    return nodeSize;
>> +}
>> +
>> +/*
>> + *getRODisksPathsFromLibvirtXML: *Parse a libvirt XML snapshot file, allocates and fills
>> + *a list of read-only disk paths (the parents of the read-write disks).
>> + *return array length on success, -1 on failure.
>> + */
>> +int virVBoxSnapshotConfGetRODisksPathsFromLibvirtXML(char *filePath, char ***roDisksPath)
>> +{
>> +    int result = -1;
>> +    size_t i = 0;
>> +    char **ret;
>> +    xmlDocPtr xml = NULL;
>> +    xmlXPathContextPtr xPathContext = NULL;
>> +    xmlNodePtr *nodes = NULL;
>> +    int nodeSize = 0;
>> +    if (filePath == NULL) {
>> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>> +                       _("filePath is null"));
>> +        goto cleanup;
>> +    }
>> +    xml = virXMLParse(filePath, NULL, NULL);
>> +    if (xml == NULL) {
>> +        virReportError(VIR_ERR_XML_ERROR, "%s",
>> +                       _("Unable to parse the xml"));
>> +        goto cleanup;
>> +    }
>> +    if (!(xPathContext = xmlXPathNewContext(xml))) {
>> +        virReportOOMError();
>> +        goto cleanup;
>> +    }
>> +    xPathContext->node = xmlDocGetRootElement(xml);
>> +    nodeSize = virXPathNodeSet("/domainsnapshot/domain/devices/disk",
>> +                               xPathContext,
>> +                               &nodes);
> 
> Same issue here as the RW code - you need to handle nodeSize return:
> 
>     if ((nodeSize = virXPathNodeSet("/domainsnapshot/domain/devices/disk",
>                                     xPathContext,
>                                     &nodes)) < 0)
>         goto cleanup;
> 
>> +    if (VIR_ALLOC_N(ret, nodeSize) < 0)
>> +        goto cleanup;
>> +
>> +    for (i = 0; i < nodeSize; i++) {
>> +        xmlNodePtr node = nodes[i];
>> +        xPathContext->node = node;
>> +        xmlNodePtr sourceNode = virXPathNode("./source", xPathContext);
>> +        if (sourceNode) {
>> +            ret[i] = virXMLPropString(sourceNode, "file");
>> +        }
>> +    }
>> +    result = 0;
>> +
>> + cleanup:
>> +    xmlFreeDoc(xml);
>> +    xmlXPathFreeContext(xPathContext);
>> +    if (result < 0) {
>> +        virStringFreeList(ret);
>> +        nodeSize = -1;
>> +    }
>> +    *roDisksPath = ret;

Use:

+    } else {
+        *roDisksPath = ret;
     }

>> +    return nodeSize;
>> +}
>> +




More information about the libvir-list mailing list