mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-01 10:06:57 +03:00
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
This commit is contained in:
@ -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.
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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. */
|
||||
|
Reference in New Issue
Block a user