summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2016-03-18 15:00:15 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.com>2016-03-18 15:27:16 -0300
commit11c1e2caad9e110f2030219d59950f8346062f27 (patch)
treeeeffbe01245e40fa0de1183af74f9f55c7440f06
parent52903e11c3c1dcfe8374472e3550966810f6296e (diff)
Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
-rw-r--r--libc/resolv/nss_dns/dns-host.c12
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);