diff options
author | Ulrich Drepper <drepper@gmail.com> | 2011-10-30 14:22:57 -0400 |
---|---|---|
committer | Ulrich Drepper <drepper@gmail.com> | 2011-10-30 14:22:57 -0400 |
commit | 636064eb4c03397c86aa26e489e68f952bd5e53f (patch) | |
tree | 9bae4b24e7bcc477018e001492c9bbb7bdd0cf25 | |
parent | 2a0c698e2427394c5263fbcb986ba509b309b8c7 (diff) | |
download | glibc-636064eb4c03397c86aa26e489e68f952bd5e53f.tar.gz glibc-636064eb4c03397c86aa26e489e68f952bd5e53f.tar.xz glibc-636064eb4c03397c86aa26e489e68f952bd5e53f.zip |
Fix potential double close in __check_fd if OOM
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/check_pf.c | 33 |
2 files changed, 24 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog index 4fccd94ec6..b4e65a847c 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 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. */ |