[Libguestfs] [libnbd PATCH v3 06/19] socket activation: plug AF_UNIX socket address (filesystem) leak on error

Laszlo Ersek lersek at redhat.com
Thu Mar 23 12:10:03 UTC 2023


A prior patch highlighted the following leak: whenever any construction
step after bind() fails, the UNIX domain socket address (i.e., the
pathname in the filesystem) is leaked. Plug the leak by inserting a new
error handling section that unlinks the pathname.

Signed-off-by: Laszlo Ersek <lersek at redhat.com>
Reviewed-by: Richard W.M. Jones <rjones at redhat.com>
---

Notes:
    v4:
    
    - pick up Rich's R-b
    
    - resolve rebase conflict near the
      prepare_socket_activation_environment() call site, due to keeping
      set_error() internal to that callee, in patch "socket activation:
      clean up responsibilities of prep.sock.act.env.()"
    
    context:-U12

 generator/states-connect-socket-activation.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/generator/states-connect-socket-activation.c b/generator/states-connect-socket-activation.c
index b20c3f1f10bb..752ee73bb62f 100644
--- a/generator/states-connect-socket-activation.c
+++ b/generator/states-connect-socket-activation.c
@@ -137,30 +137,30 @@  CONNECT_SA.START:
     goto free_sockpath;
   }
 
   addr.sun_family = AF_UNIX;
   memcpy (addr.sun_path, sockpath, strlen (sockpath) + 1);
   if (bind (s, (struct sockaddr *) &addr, sizeof addr) == -1) {
     set_error (errno, "bind: %s", sockpath);
     goto close_socket;
   }
 
   if (listen (s, SOMAXCONN) == -1) {
     set_error (errno, "listen");
-    goto close_socket;
+    goto unlink_sockpath;
   }
 
   if (prepare_socket_activation_environment (&env) == -1)
     /* prepare_socket_activation_environment() calls set_error() internally */
-    goto close_socket;
+    goto unlink_sockpath;
 
   pid = fork ();
   if (pid == -1) {
     set_error (errno, "fork");
     goto empty_env;
   }
 
   if (pid == 0) {         /* child - run command */
     if (s != FIRST_SOCKET_ACTIVATION_FD) {
       if (dup2 (s, FIRST_SOCKET_ACTIVATION_FD) == -1) {
         nbd_internal_fork_safe_perror ("dup2");
         _exit (126);
@@ -211,24 +211,28 @@  CONNECT_SA.START:
   h->sact_sockpath = sockpath;
   h->pid = pid;
 
   h->connaddrlen = sizeof addr;
   memcpy (&h->connaddr, &addr, h->connaddrlen);
   next = %^CONNECT.START;
 
   /* fall through, for releasing the temporaries */
 
 empty_env:
   string_vector_empty (&env);
 
+unlink_sockpath:
+  if (next == %.DEAD)
+    unlink (sockpath);
+
 close_socket:
   close (s);
 
 free_sockpath:
   if (next == %.DEAD)
     free (sockpath);
 
 rmdir_tmpdir:
   if (next == %.DEAD)
     rmdir (tmpdir);
 
 free_tmpdir:



More information about the Libguestfs mailing list