This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][BZ 21295] getaddrinfo: do not overwrite IPv6 IPs with IPv4 when using AF_UNSPEC


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]