From: Andreas Schwab Date: Thu, 13 Feb 2014 10:01:57 +0000 (+0100) Subject: Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=efbeb31ba5277132b683011714f8e77bc2156aa2;p=thirdparty%2Fglibc.git Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer (cherry picked from commit d668061994a7486a3ba9c7d5e7882d85a2883707) Conflicts: NEWS --- diff --git a/ChangeLog b/ChangeLog index 09056dadedf..bf80e9058a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2014-02-13 Andreas Schwab + + [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 [BZ #16932] diff --git a/NEWS b/NEWS index d10a3aa4424..d2b3419831d 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 f8f192e5afb..f56dd3584a9 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);