about summary refs log tree commit diff
path: root/resolv
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2014-02-13 11:01:57 +0100
committerAndreas Schwab <schwab@suse.de>2014-02-13 12:54:34 +0100
commitd668061994a7486a3ba9c7d5e7882d85a2883707 (patch)
treeab372c220adff0fb3459d822e316f79917d9e803 /resolv
parent743151aeaedc113900805523195fc3d9cff0bdb6 (diff)
downloadglibc-d668061994a7486a3ba9c7d5e7882d85a2883707.tar.gz
glibc-d668061994a7486a3ba9c7d5e7882d85a2883707.tar.xz
glibc-d668061994a7486a3ba9c7d5e7882d85a2883707.zip
Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
Diffstat (limited to 'resolv')
-rw-r--r--resolv/nss_dns/dns-host.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 541c25a348..365de7095f 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -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);