1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

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.
This commit is contained in:
Siddhesh Poyarekar
2021-05-12 09:14:54 +05:30
parent 5188a9d026
commit 900962f37f

View File

@ -48,12 +48,15 @@ __check_native (uint32_t a1_index, int *a1_native,
nladdr.nl_family = AF_NETLINK; nladdr.nl_family = AF_NETLINK;
socklen_t addr_len = sizeof (nladdr); socklen_t addr_len = sizeof (nladdr);
bool use_malloc = false;
if (fd < 0 if (fd < 0)
|| __bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) != 0
|| __getsockname (fd, (struct sockaddr *) &nladdr, &addr_len) != 0)
return; 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; pid_t pid = nladdr.nl_pid;
struct req struct req
{ {
@ -85,7 +88,6 @@ __check_native (uint32_t a1_index, int *a1_native,
#else #else
const size_t buf_size = __getpagesize (); const size_t buf_size = __getpagesize ();
#endif #endif
bool use_malloc = false;
char *buf; char *buf;
if (__libc_use_alloca (buf_size)) if (__libc_use_alloca (buf_size))
@ -96,7 +98,7 @@ __check_native (uint32_t a1_index, int *a1_native,
if (buf != NULL) if (buf != NULL)
use_malloc = true; use_malloc = true;
else else
goto out_fail; goto out;
} }
struct iovec iov = { buf, buf_size }; 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, if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0,
(struct sockaddr *) &nladdr, (struct sockaddr *) &nladdr,
sizeof (nladdr))) < 0) sizeof (nladdr))) < 0)
goto out_fail; goto out;
bool done = false; bool done = false;
do 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)); ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
__netlink_assert_response (fd, read_len); __netlink_assert_response (fd, read_len);
if (read_len < 0) if (read_len < 0)
goto out_fail; goto out;
if (msg.msg_flags & MSG_TRUNC) if (msg.msg_flags & MSG_TRUNC)
goto out_fail; goto out;
struct nlmsghdr *nlmh; struct nlmsghdr *nlmh;
for (nlmh = (struct nlmsghdr *) buf; for (nlmh = (struct nlmsghdr *) buf;
@ -166,12 +168,9 @@ __check_native (uint32_t a1_index, int *a1_native,
} }
while (! done); while (! done);
out: out:
__close_nocancel_nostatus (fd); __close_nocancel_nostatus (fd);
return;
out_fail:
if (use_malloc) if (use_malloc)
free (buf); free (buf);
} }