aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-10-30 14:22:57 -0400
committerUlrich Drepper <drepper@gmail.com>2011-10-30 14:22:57 -0400
commit636064eb4c03397c86aa26e489e68f952bd5e53f (patch)
tree9bae4b24e7bcc477018e001492c9bbb7bdd0cf25
parent2a0c698e2427394c5263fbcb986ba509b309b8c7 (diff)
downloadglibc-636064eb4c03397c86aa26e489e68f952bd5e53f.zip
glibc-636064eb4c03397c86aa26e489e68f952bd5e53f.tar.gz
glibc-636064eb4c03397c86aa26e489e68f952bd5e53f.tar.bz2
Fix potential double close in __check_fd if OOM
-rw-r--r--ChangeLog6
-rw-r--r--sysdeps/unix/sysv/linux/check_pf.c33
2 files changed, 24 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 4fccd94..b4e65a8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2011-10-30 Ulrich Drepper <drepper@gmail.com>
+
+ * sysdeps/unix/sysv/linux/check_pf.c (make_request): Don't call
+ close_not_cancel_no_status here.
+ (__check_pf): Reorganize code a bit to not call close twice if OOM.
+
2011-10-29 Ulrich Drepper <drepper@gmail.com>
[BZ #13276]
diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
index c053adc..d5ad7ea 100644
--- a/sysdeps/unix/sysv/linux/check_pf.c
+++ b/sysdeps/unix/sysv/linux/check_pf.c
@@ -211,8 +211,6 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
}
while (! done);
- close_not_cancel_no_status (fd);
-
if (*seen_ipv6 && in6ailist != NULL)
{
*in6ai = malloc (in6ailistlen * sizeof (**in6ai));
@@ -262,22 +260,27 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
{
int fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- struct sockaddr_nl nladdr;
- memset (&nladdr, '\0', sizeof (nladdr));
- nladdr.nl_family = AF_NETLINK;
+ if (__builtin_expect (fd >= 0, 1))
+ {
+ struct sockaddr_nl nladdr;
+ memset (&nladdr, '\0', sizeof (nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ socklen_t addr_len = sizeof (nladdr);
- socklen_t addr_len = sizeof (nladdr);
+ bool success
+ = (__bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) == 0
+ && __getsockname (fd, (struct sockaddr *) &nladdr,
+ &addr_len) == 0
+ && make_request (fd, nladdr.nl_pid, seen_ipv4, seen_ipv6,
+ in6ai, in6ailen) == 0);
- if (fd >= 0
- && __bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) == 0
- && __getsockname (fd, (struct sockaddr *) &nladdr, &addr_len) == 0
- && make_request (fd, nladdr.nl_pid, seen_ipv4, seen_ipv6,
- in6ai, in6ailen) == 0)
- /* It worked. */
- return;
+ close_not_cancel_no_status (fd);
- if (fd >= 0)
- __close (fd);
+ if (success)
+ /* It worked. */
+ return;
+ }
#if __ASSUME_NETLINK_SUPPORT == 0
/* Remember that there is no netlink support. */