libxlMakeNic opens a virConnect object and takes a reference on a
virNetwork object, but doesn't drop the references on all error
paths. Rework the function to follow the standard libvirt pattern
of using a local 'ret' variable to hold the function return value,
performing all cleanup and returning 'ret' at a 'cleanup' label.

Signed-off-by: Jim Fehlig <jfeh...@suse.com>
---

I noticed these leaks while trying to rework the code to use a
common virConnect object. That task has turned into quite an
effort [1], but in the meantime the leaks in the current code
should be plugged.

[1] https://www.redhat.com/archives/libvir-list/2016-February/msg01188.html

 src/libxl/libxl_conf.c | 57 ++++++++++++++++++++++++--------------------------
 1 file changed, 27 insertions(+), 30 deletions(-)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index b20df29..763f4c5 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -1286,7 +1286,11 @@ libxlMakeNic(virDomainDefPtr def,
 {
     bool ioemu_nic = def->os.type == VIR_DOMAIN_OSTYPE_HVM;
     virDomainNetType actual_type = virDomainNetGetActualType(l_nic);
+    char *brname = NULL;
+    virNetworkPtr network = NULL;
+    virConnectPtr conn = NULL;
     virNetDevBandwidthPtr actual_bw;
+    int ret = -1;
 
     /* TODO: Where is mtu stored?
      *
@@ -1312,64 +1316,50 @@ libxlMakeNic(virDomainDefPtr def,
 
     if (l_nic->model) {
         if (VIR_STRDUP(x_nic->model, l_nic->model) < 0)
-            return -1;
+            goto cleanup;
         if (STREQ(l_nic->model, "netfront"))
             x_nic->nictype = LIBXL_NIC_TYPE_VIF;
     }
 
     if (VIR_STRDUP(x_nic->ifname, l_nic->ifname) < 0)
-        return -1;
+        goto cleanup;
 
     switch (actual_type) {
         case VIR_DOMAIN_NET_TYPE_BRIDGE:
             if (VIR_STRDUP(x_nic->bridge,
                            virDomainNetGetActualBridgeName(l_nic)) < 0)
-                return -1;
+                goto cleanup;
             /* fallthrough */
         case VIR_DOMAIN_NET_TYPE_ETHERNET:
             if (VIR_STRDUP(x_nic->script, l_nic->script) < 0)
-                return -1;
+                goto cleanup;
             if (l_nic->nips > 0) {
                 x_nic->ip = virSocketAddrFormat(&l_nic->ips[0]->address);
                 if (!x_nic->ip)
-                    return -1;
+                    goto cleanup;
             }
             break;
         case VIR_DOMAIN_NET_TYPE_NETWORK:
         {
-            bool fail = false;
-            char *brname = NULL;
-            virNetworkPtr network;
-            virConnectPtr conn;
-
             if (!(conn = virConnectOpen("xen:///system")))
-                return -1;
+                goto cleanup;
 
             if (!(network =
                   virNetworkLookupByName(conn, l_nic->data.network.name))) {
-                virObjectUnref(conn);
-                return -1;
+                goto cleanup;
             }
 
             if (l_nic->nips > 0) {
                 x_nic->ip = virSocketAddrFormat(&l_nic->ips[0]->address);
                 if (!x_nic->ip)
-                    return -1;
+                    goto cleanup;
             }
 
-            if ((brname = virNetworkGetBridgeName(network))) {
-                if (VIR_STRDUP(x_nic->bridge, brname) < 0)
-                    fail = true;
-            } else {
-                fail = true;
-            }
-
-            VIR_FREE(brname);
+            if (!(brname = virNetworkGetBridgeName(network)))
+                goto cleanup;
 
-            virObjectUnref(network);
-            virObjectUnref(conn);
-            if (fail)
-                return -1;
+            if (VIR_STRDUP(x_nic->bridge, brname) < 0)
+                    goto cleanup;
             break;
         }
         case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
@@ -1385,18 +1375,18 @@ libxlMakeNic(virDomainDefPtr def,
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                     _("unsupported interface type %s"),
                     virDomainNetTypeToString(l_nic->type));
-            return -1;
+            goto cleanup;
     }
 
     if (l_nic->domain_name) {
 #ifdef LIBXL_HAVE_DEVICE_BACKEND_DOMNAME
         if (VIR_STRDUP(x_nic->backend_domname, l_nic->domain_name) < 0)
-            return -1;
+            goto cleanup;
 #else
         virReportError(VIR_ERR_XML_DETAIL, "%s",
                 _("this version of libxenlight does not "
                   "support backend domain name"));
-        return -1;
+        goto cleanup;
 #endif
     }
 
@@ -1438,7 +1428,14 @@ libxlMakeNic(virDomainDefPtr def,
         x_nic->rate_interval_usecs =  50000UL;
     }
 
-    return 0;
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(brname);
+    virObjectUnref(network);
+    virObjectUnref(conn);
+
+    return ret;
 }
 
 static int
-- 
2.6.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to