]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
authorAndreas Schwab <schwab@suse.de>
Thu, 13 Feb 2014 10:01:57 +0000 (11:01 +0100)
committerAllan McRae <allan@archlinux.org>
Fri, 5 Sep 2014 12:44:08 +0000 (22:44 +1000)
(cherry picked from commit d668061994a7486a3ba9c7d5e7882d85a2883707)

Conflicts:
NEWS

ChangeLog
NEWS
resolv/nss_dns/dns-host.c

index 09056dadedf677ec7270992ddc4a083da3761880..bf80e9058a5a4972994b0e63e348c05b6a6c24be 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-02-13  Andreas Schwab  <schwab@suse.de>
+
+       [BZ #16574]
+       * resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname4_r): Free the
+       second answer buffer if it was separately allocated.
+
 2014-05-12  Andreas Schwab  <schwab@suse.de>
 
        [BZ #16932]
diff --git a/NEWS b/NEWS
index d10a3aa4424f63757634f83d4c009c17f119861f..d2b3419831d2d9dc39a8e1fae8b24f26ebdd4f39 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16623, 16882, 16885, 16916, 16932, 16943, 16958, 17048.
+  16545, 16574, 16623, 16882, 16885, 16916, 16932, 16943, 16958, 17048.
 
 * CVE-2014-4043 The posix_spawn_file_actions_addopen implementation did not
   copy the path argument.  This allowed programs to cause posix_spawn to
index f8f192e5afb54f22667066e461a91a0e8d00d3a0..f56dd3584a9c0ebf8ca526cdc47371debd5628d8 100644 (file)
@@ -298,13 +298,14 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
        name = cp;
     }
 
+  int anslen = 2048;
   union
   {
     querybuf *buf;
     u_char *ptr;
   } host_buffer;
   querybuf *orig_host_buffer;
-  host_buffer.buf = orig_host_buffer = (querybuf *) alloca (2048);
+  host_buffer.buf = orig_host_buffer = (querybuf *) alloca (anslen);
   u_char *ans2p = NULL;
   int nans2p = 0;
   int resplen2 = 0;
@@ -312,7 +313,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
   int olderr = errno;
   enum nss_status status;
   int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
-                             host_buffer.buf->buf, 2048, &host_buffer.ptr,
+                             host_buffer.buf->buf, anslen, &host_buffer.ptr,
                              &ans2p, &nans2p, &resplen2);
   if (n < 0)
     {
@@ -352,6 +353,13 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
                          resplen2, name, pat, buffer, buflen,
                          errnop, herrnop, ttlp);
 
+  /* Check whether ans2p was separately allocated.  */
+  if (host_buffer.buf != orig_host_buffer)
+    anslen = MAXPACKET;
+  if (ans2p != NULL
+      && (ans2p < host_buffer.ptr || ans2p >= host_buffer.ptr + anslen))
+    free (ans2p);
+
   if (host_buffer.buf != orig_host_buffer)
     free (host_buffer.buf);