This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH][BZ 21295] getaddrinfo: do not overwrite IPv6 IPs with IPv4 when using AF_UNSPEC
- From: kmeaw at kmeaw dot com
- To: libc-alpha at sourceware dot org
- Date: Thu, 23 Mar 2017 16:21:30 +0300
- Subject: [PATCH][BZ 21295] getaddrinfo: do not overwrite IPv6 IPs with IPv4 when using AF_UNSPEC
- Authentication-results: sourceware.org; auth=none
CVE-2016-3706 patch introduces a regression which disrupts connectivity
from IPv6-only to dual-stack hosts. This is caused by
convert_hostent_to_gaih_addrtuple which frees the result opposed to
appending to it (prior to the CVE patch in gaih_inet).
This change replaces free(*result) call with a loop which looks for the
pointer to the end of the linked list (&(*result)->next), so successive
calls append the result to the list instead of overwriting it.
Bugzilla entry #21295 describes a way to reproduce the issue.
---
ChangeLog | 5 +++++
sysdeps/posix/getaddrinfo.c | 8 ++++----
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 7809c3dc2b..56179d6164 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2017-03-23 Dmitry Bilunov <kmeaw@kmeaw.com>
+
+ * sysdeps/posix/getaddrinfo.c (onvert_hostent_to_gaih_addrtuple):
+ do not overwrite list of IPv6 addresses with IPv4; merge them instead.
+
2017-03-22 Zack Weinberg <zackw@panix.com>
* stdio-common/bug25.c: Include stdlib.h.
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index eed7264850..cf1d99b2e2 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -190,16 +190,16 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
/* Convert struct hostent to a list of struct gaih_addrtuple objects.
h_name is not copied, and the struct hostent object must not be
- deallocated prematurely. *RESULT must be NULL or a pointer to an
- object allocated using malloc, which is freed. */
+ deallocated prematurely. *RESULT must be NULL or a pointer to a
+ linked-list, which is scanned to the end. */
static bool
convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
int family,
struct hostent *h,
struct gaih_addrtuple **result)
{
- free (*result);
- *result = NULL;
+ while (*result)
+ result = &(*result)->next;
/* Count the number of addresses in h->h_addr_list. */
size_t count = 0;
--
2.12.0