[libvirt] [PATCH] Fix memory leak in virNetSocketNewConnectUNIX

Jiri Denemark jdenemar at redhat.com
Fri Apr 24 10:03:37 UTC 2015


==26726==    by 0x673CD67: __vasprintf_chk (vasprintf_chk.c:80)
==26726==    by 0x5673605: UnknownInlinedFun (stdio2.h:210)
==26726==    by 0x5673605: virVasprintfInternal (virstring.c:476)
==26726==    by 0x56736EE: virAsprintfInternal (virstring.c:497)
==26726==    by 0x5680C37: virGetUserRuntimeDirectory (virutil.c:866)
==26726==    by 0x5783A89: virNetSocketNewConnectUNIX (virnetsocket.c:572)
==26726==    by 0x57751AF: virNetClientNewUNIX (virnetclient.c:344)
==26726==    by 0x57689B3: doRemoteOpen (remote_driver.c:895)
==26726==    by 0x5769F8E: remoteConnectOpen (remote_driver.c:1195)
==26726==    by 0x57092DF: do_open (libvirt.c:1189)
==26726==    by 0x570A7BF: virConnectOpenAuth (libvirt.c:1341)

https://bugzilla.redhat.com/show_bug.cgi?id=1215042
Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/rpc/virnetsocket.c | 44 +++++++++++++++++++++-----------------------
 1 file changed, 21 insertions(+), 23 deletions(-)

diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index a59e3e1..7ae2796 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -546,6 +546,7 @@ int virNetSocketNewConnectUNIX(const char *path,
     virSocketAddr localAddr;
     virSocketAddr remoteAddr;
     char *rundir = NULL;
+    int ret = -1;
 
     memset(&localAddr, 0, sizeof(localAddr));
     memset(&remoteAddr, 0, sizeof(remoteAddr));
@@ -559,50 +560,50 @@ int virNetSocketNewConnectUNIX(const char *path,
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Auto-spawn of daemon requested, "
                              "but no binary specified"));
-            goto error;
+            goto cleanup;
         }
 
         if (!(binname = last_component(binary)) || binname[0] == '\0') {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Cannot determine basename for binary '%s'"),
                            binary);
-            goto error;
+            goto cleanup;
         }
 
         if (!(rundir = virGetUserRuntimeDirectory()))
-            goto error;
+            goto cleanup;
 
         if (virFileMakePathWithMode(rundir, 0700) < 0) {
             virReportSystemError(errno,
                                  _("Cannot create user runtime directory '%s'"),
                                  rundir);
-            goto error;
+            goto cleanup;
         }
 
         if (virAsprintf(&lockpath, "%s/%s.lock", rundir, binname) < 0)
-            goto error;
+            goto cleanup;
 
         if ((lockfd = open(lockpath, O_RDWR | O_CREAT, 0600)) < 0 ||
             virSetCloseExec(lockfd) < 0) {
             virReportSystemError(errno, _("Unable to create lock '%s'"), lockpath);
-            goto error;
+            goto cleanup;
         }
 
         if (virFileLock(lockfd, false, 0, 1, true) < 0) {
             virReportSystemError(errno, _("Unable to lock '%s'"), lockpath);
-            goto error;
+            goto cleanup;
         }
     }
 
     if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
         virReportSystemError(errno, "%s", _("Failed to create socket"));
-        goto error;
+        goto cleanup;
     }
 
     remoteAddr.data.un.sun_family = AF_UNIX;
     if (virStrcpyStatic(remoteAddr.data.un.sun_path, path) == NULL) {
         virReportSystemError(ENOMEM, _("Path %s too long for unix socket"), path);
-        goto error;
+        goto cleanup;
     }
     if (remoteAddr.data.un.sun_path[0] == '@')
         remoteAddr.data.un.sun_path[0] = '\0';
@@ -612,42 +613,39 @@ int virNetSocketNewConnectUNIX(const char *path,
         if (!(spawnDaemon && errno == ENOENT)) {
             virReportSystemError(errno, _("Failed to connect socket to '%s'"),
                                  path);
-            goto error;
+            goto cleanup;
         }
 
         if (virNetSocketForkDaemon(binary) < 0)
-            goto error;
+            goto cleanup;
 
         retries--;
         usleep(5000);
     }
 
-    if (lockfd != -1) {
-        unlink(lockpath);
-        VIR_FORCE_CLOSE(lockfd);
-        VIR_FREE(lockpath);
-    }
-
     localAddr.len = sizeof(localAddr.data);
     if (getsockname(fd, &localAddr.data.sa, &localAddr.len) < 0) {
         virReportSystemError(errno, "%s", _("Unable to get local socket name"));
-        goto error;
+        goto cleanup;
     }
 
     if (!(*retsock = virNetSocketNew(&localAddr, &remoteAddr, true, fd, -1, 0)))
-        goto error;
+        goto cleanup;
 
-    return 0;
+    ret = 0;
 
- error:
+ cleanup:
     if (lockfd != -1) {
         unlink(lockpath);
         VIR_FORCE_CLOSE(lockfd);
     }
     VIR_FREE(lockpath);
     VIR_FREE(rundir);
-    VIR_FORCE_CLOSE(fd);
-    return -1;
+
+    if (ret == -1)
+        VIR_FORCE_CLOSE(fd);
+
+    return ret;
 }
 #else
 int virNetSocketNewConnectUNIX(const char *path ATTRIBUTE_UNUSED,
-- 
2.3.5




More information about the libvir-list mailing list