aboutsummaryrefslogtreecommitdiff
path: root/resolv/nss_dns
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2014-02-18 10:57:25 +0100
committerAndreas Schwab <schwab@suse.de>2014-02-19 14:39:21 +0100
commitab09bf616ad527b249aca5f2a4956fd526f0712f (patch)
tree8983f676bf5ac2c5e418a4276dcd25f28755ea70 /resolv/nss_dns
parentc6af2d896ce07740ad5170eaed3c0bb7720e079e (diff)
downloadglibc-ab09bf616ad527b249aca5f2a4956fd526f0712f.zip
glibc-ab09bf616ad527b249aca5f2a4956fd526f0712f.tar.gz
glibc-ab09bf616ad527b249aca5f2a4956fd526f0712f.tar.bz2
Properly fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
Instead of trying to guess whether the second buffer needs to be freed set a flag at the place it is allocated
Diffstat (limited to 'resolv/nss_dns')
-rw-r--r--resolv/nss_dns/dns-canon.c2
-rw-r--r--resolv/nss_dns/dns-host.c23
-rw-r--r--resolv/nss_dns/dns-network.c4
3 files changed, 13 insertions, 16 deletions
diff --git a/resolv/nss_dns/dns-canon.c b/resolv/nss_dns/dns-canon.c
index a9db232..e8c112c 100644
--- a/resolv/nss_dns/dns-canon.c
+++ b/resolv/nss_dns/dns-canon.c
@@ -62,7 +62,7 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen,
{
int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i],
buf, sizeof (buf), &ansp.ptr, NULL, NULL,
- NULL);
+ NULL, NULL);
if (r > 0)
{
/* We need to decode the response. Just one question record.
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 47f998c..a5f2c0a 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -190,7 +190,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf,
- 1024, &host_buffer.ptr, NULL, NULL, NULL);
+ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
if (n < 0)
{
switch (errno)
@@ -225,7 +225,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf,
host_buffer.buf != orig_host_buffer
? MAXPACKET : 1024, &host_buffer.ptr,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
if (n < 0)
{
@@ -298,23 +298,23 @@ _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 (anslen);
+ host_buffer.buf = orig_host_buffer = (querybuf *) alloca (2048);
u_char *ans2p = NULL;
int nans2p = 0;
int resplen2 = 0;
+ int ans2p_malloced = 0;
int olderr = errno;
enum nss_status status;
int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
- host_buffer.buf->buf, anslen, &host_buffer.ptr,
- &ans2p, &nans2p, &resplen2);
+ host_buffer.buf->buf, 2048, &host_buffer.ptr,
+ &ans2p, &nans2p, &resplen2, &ans2p_malloced);
if (n >= 0)
{
status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
@@ -351,10 +351,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
}
/* 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))
+ if (ans2p_malloced)
free (ans2p);
if (host_buffer.buf != orig_host_buffer)
@@ -465,7 +462,7 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
strcpy (qp, "].ip6.arpa");
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
host_buffer.buf->buf, 1024, &host_buffer.ptr,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
if (n >= 0)
goto got_it_already;
}
@@ -486,14 +483,14 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
}
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
- 1024, &host_buffer.ptr, NULL, NULL, NULL);
+ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0)
{
strcpy (qp, "ip6.int");
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
host_buffer.buf != orig_host_buffer
? MAXPACKET : 1024, &host_buffer.ptr,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
}
if (n < 0)
{
diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
index b8aee21..0a77c8b 100644
--- a/resolv/nss_dns/dns-network.c
+++ b/resolv/nss_dns/dns-network.c
@@ -129,7 +129,7 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
- 1024, &net_buffer.ptr, NULL, NULL, NULL);
+ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
if (anslen < 0)
{
/* Nothing found. */
@@ -205,7 +205,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result,
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
- 1024, &net_buffer.ptr, NULL, NULL, NULL);
+ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
if (anslen < 0)
{
/* Nothing found. */