From 636064eb4c03397c86aa26e489e68f952bd5e53f Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 30 Oct 2011 14:22:57 -0400 Subject: Fix potential double close in __check_fd if OOM --- sysdeps/unix/sysv/linux/check_pf.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'sysdeps/unix/sysv/linux') diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c index c053adcda7..d5ad7ea2e5 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. */ -- cgit 1.4.1