about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@sourceware.org>2021-05-12 09:14:54 +0530
committerSiddhesh Poyarekar <siddhesh@sourceware.org>2021-05-12 15:53:33 +0530
commit900962f37f64c263db83ec8639847e8f6753b8d9 (patch)
treeea3a1af16b5d06e31233bd8f0f3cbcfca20ccfac /sysdeps
parent5188a9d0265cc6f7235a8af1d31ab02e4a24853d (diff)
downloadglibc-900962f37f64c263db83ec8639847e8f6753b8d9.tar.gz
glibc-900962f37f64c263db83ec8639847e8f6753b8d9.tar.xz
glibc-900962f37f64c263db83ec8639847e8f6753b8d9.zip
linux/check_native: Always close socket on return
The error paths of __check_native would leave the socket FD open on
return, resulting in an FD leak.  Rework function exit paths so that
the fd is always closed on return.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/unix/sysv/linux/check_native.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/sysdeps/unix/sysv/linux/check_native.c b/sysdeps/unix/sysv/linux/check_native.c
index e4e6e80dbc..13e5eaf339 100644
--- a/sysdeps/unix/sysv/linux/check_native.c
+++ b/sysdeps/unix/sysv/linux/check_native.c
@@ -48,12 +48,15 @@ __check_native (uint32_t a1_index, int *a1_native,
   nladdr.nl_family = AF_NETLINK;
 
   socklen_t addr_len = sizeof (nladdr);
+  bool use_malloc = false;
 
-  if (fd < 0
-      || __bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) != 0
-      || __getsockname (fd, (struct sockaddr *) &nladdr, &addr_len) != 0)
+  if (fd < 0)
     return;
 
+  if (__bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) != 0
+      || __getsockname (fd, (struct sockaddr *) &nladdr, &addr_len) != 0)
+    goto out;
+
   pid_t pid = nladdr.nl_pid;
   struct req
   {
@@ -85,7 +88,6 @@ __check_native (uint32_t a1_index, int *a1_native,
 #else
   const size_t buf_size = __getpagesize ();
 #endif
-  bool use_malloc = false;
   char *buf;
 
   if (__libc_use_alloca (buf_size))
@@ -96,7 +98,7 @@ __check_native (uint32_t a1_index, int *a1_native,
       if (buf != NULL)
 	use_malloc = true;
       else
-	goto out_fail;
+	goto out;
     }
 
   struct iovec iov = { buf, buf_size };
@@ -104,7 +106,7 @@ __check_native (uint32_t a1_index, int *a1_native,
   if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0,
 				    (struct sockaddr *) &nladdr,
 				    sizeof (nladdr))) < 0)
-    goto out_fail;
+    goto out;
 
   bool done = false;
   do
@@ -123,10 +125,10 @@ __check_native (uint32_t a1_index, int *a1_native,
       ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
       __netlink_assert_response (fd, read_len);
       if (read_len < 0)
-	goto out_fail;
+	goto out;
 
       if (msg.msg_flags & MSG_TRUNC)
-	goto out_fail;
+	goto out;
 
       struct nlmsghdr *nlmh;
       for (nlmh = (struct nlmsghdr *) buf;
@@ -166,12 +168,9 @@ __check_native (uint32_t a1_index, int *a1_native,
     }
   while (! done);
 
- out:
+out:
   __close_nocancel_nostatus (fd);
 
-  return;
-
-out_fail:
   if (use_malloc)
     free (buf);
 }