diff options
author | Andreas Schwab <schwab@suse.de> | 2016-03-18 15:00:15 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.com> | 2016-03-18 15:27:16 -0300 |
commit | 11c1e2caad9e110f2030219d59950f8346062f27 (patch) | |
tree | eeffbe01245e40fa0de1183af74f9f55c7440f06 | |
parent | 52903e11c3c1dcfe8374472e3550966810f6296e (diff) |
Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
-rw-r--r-- | libc/resolv/nss_dns/dns-host.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/libc/resolv/nss_dns/dns-host.c b/libc/resolv/nss_dns/dns-host.c index f8f192e5a..f56dd3584 100644 --- a/libc/resolv/nss_dns/dns-host.c +++ b/libc/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); |