aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2014-02-13 11:01:57 +0100
committerAllan McRae <allan@archlinux.org>2014-09-05 22:44:08 +1000
commitefbeb31ba5277132b683011714f8e77bc2156aa2 (patch)
tree4e40fc5b1edab46aff23d8693c1e97c5304c50ff
parent968b59ad2aecdbe67ac5016c395a7e38fd682bb7 (diff)
downloadglibc-efbeb31ba5277132b683011714f8e77bc2156aa2.tar
glibc-efbeb31ba5277132b683011714f8e77bc2156aa2.tar.gz
glibc-efbeb31ba5277132b683011714f8e77bc2156aa2.tar.bz2
glibc-efbeb31ba5277132b683011714f8e77bc2156aa2.zip
Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
(cherry picked from commit d668061994a7486a3ba9c7d5e7882d85a2883707) Conflicts: NEWS
-rw-r--r--ChangeLog6
-rw-r--r--NEWS2
-rw-r--r--resolv/nss_dns/dns-host.c12
3 files changed, 17 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 09056daded..bf80e9058a 100644
--- 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 d10a3aa442..d2b3419831 100644
--- 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
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index f8f192e5af..f56dd3584a 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);