mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +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:
@ -98,7 +98,7 @@ static int
|
||||
__libc_res_nquerydomain(res_state statp, const char *name, const char *domain,
|
||||
int class, int type, u_char *answer, int anslen,
|
||||
u_char **answerp, u_char **answerp2, int *nanswerp2,
|
||||
int *resplen2);
|
||||
int *resplen2, int *answerp2_malloced);
|
||||
|
||||
/*
|
||||
* Formulate a normal query, send, and await answer.
|
||||
@ -119,7 +119,8 @@ __libc_res_nquery(res_state statp,
|
||||
u_char **answerp, /* if buffer needs to be enlarged */
|
||||
u_char **answerp2,
|
||||
int *nanswerp2,
|
||||
int *resplen2)
|
||||
int *resplen2,
|
||||
int *answerp2_malloced)
|
||||
{
|
||||
HEADER *hp = (HEADER *) answer;
|
||||
HEADER *hp2;
|
||||
@ -224,7 +225,8 @@ __libc_res_nquery(res_state statp,
|
||||
}
|
||||
assert (answerp == NULL || (void *) *answerp == (void *) answer);
|
||||
n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer,
|
||||
anslen, answerp, answerp2, nanswerp2, resplen2);
|
||||
anslen, answerp, answerp2, nanswerp2, resplen2,
|
||||
answerp2_malloced);
|
||||
if (use_malloc)
|
||||
free (buf);
|
||||
if (n < 0) {
|
||||
@ -316,7 +318,7 @@ res_nquery(res_state statp,
|
||||
int anslen) /* size of answer buffer */
|
||||
{
|
||||
return __libc_res_nquery(statp, name, class, type, answer, anslen,
|
||||
NULL, NULL, NULL, NULL);
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
libresolv_hidden_def (res_nquery)
|
||||
|
||||
@ -335,7 +337,8 @@ __libc_res_nsearch(res_state statp,
|
||||
u_char **answerp,
|
||||
u_char **answerp2,
|
||||
int *nanswerp2,
|
||||
int *resplen2)
|
||||
int *resplen2,
|
||||
int *answerp2_malloced)
|
||||
{
|
||||
const char *cp, * const *domain;
|
||||
HEADER *hp = (HEADER *) answer;
|
||||
@ -360,7 +363,7 @@ __libc_res_nsearch(res_state statp,
|
||||
if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
|
||||
return (__libc_res_nquery(statp, cp, class, type, answer,
|
||||
anslen, answerp, answerp2,
|
||||
nanswerp2, resplen2));
|
||||
nanswerp2, resplen2, answerp2_malloced));
|
||||
|
||||
#ifdef DEBUG
|
||||
if (statp->options & RES_DEBUG)
|
||||
@ -377,7 +380,8 @@ __libc_res_nsearch(res_state statp,
|
||||
if (dots >= statp->ndots || trailing_dot) {
|
||||
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
|
||||
answer, anslen, answerp,
|
||||
answerp2, nanswerp2, resplen2);
|
||||
answerp2, nanswerp2, resplen2,
|
||||
answerp2_malloced);
|
||||
if (ret > 0 || trailing_dot)
|
||||
return (ret);
|
||||
saved_herrno = h_errno;
|
||||
@ -386,11 +390,11 @@ __libc_res_nsearch(res_state statp,
|
||||
answer = *answerp;
|
||||
anslen = MAXPACKET;
|
||||
}
|
||||
if (answerp2
|
||||
&& (*answerp2 < answer || *answerp2 >= answer + anslen))
|
||||
if (answerp2 && *answerp2_malloced)
|
||||
{
|
||||
free (*answerp2);
|
||||
*answerp2 = NULL;
|
||||
*answerp2_malloced = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -417,7 +421,7 @@ __libc_res_nsearch(res_state statp,
|
||||
class, type,
|
||||
answer, anslen, answerp,
|
||||
answerp2, nanswerp2,
|
||||
resplen2);
|
||||
resplen2, answerp2_malloced);
|
||||
if (ret > 0)
|
||||
return (ret);
|
||||
|
||||
@ -425,12 +429,11 @@ __libc_res_nsearch(res_state statp,
|
||||
answer = *answerp;
|
||||
anslen = MAXPACKET;
|
||||
}
|
||||
if (answerp2
|
||||
&& (*answerp2 < answer
|
||||
|| *answerp2 >= answer + anslen))
|
||||
if (answerp2 && *answerp2_malloced)
|
||||
{
|
||||
free (*answerp2);
|
||||
*answerp2 = NULL;
|
||||
*answerp2_malloced = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -486,7 +489,8 @@ __libc_res_nsearch(res_state statp,
|
||||
&& !(tried_as_is || root_on_list)) {
|
||||
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
|
||||
answer, anslen, answerp,
|
||||
answerp2, nanswerp2, resplen2);
|
||||
answerp2, nanswerp2, resplen2,
|
||||
answerp2_malloced);
|
||||
if (ret > 0)
|
||||
return (ret);
|
||||
}
|
||||
@ -498,10 +502,11 @@ __libc_res_nsearch(res_state statp,
|
||||
* else send back meaningless H_ERRNO, that being the one from
|
||||
* the last DNSRCH we did.
|
||||
*/
|
||||
if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
|
||||
if (answerp2 && *answerp2_malloced)
|
||||
{
|
||||
free (*answerp2);
|
||||
*answerp2 = NULL;
|
||||
*answerp2_malloced = 0;
|
||||
}
|
||||
if (saved_herrno != -1)
|
||||
RES_SET_H_ERRNO(statp, saved_herrno);
|
||||
@ -521,7 +526,7 @@ res_nsearch(res_state statp,
|
||||
int anslen) /* size of answer */
|
||||
{
|
||||
return __libc_res_nsearch(statp, name, class, type, answer,
|
||||
anslen, NULL, NULL, NULL, NULL);
|
||||
anslen, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
libresolv_hidden_def (res_nsearch)
|
||||
|
||||
@ -539,7 +544,8 @@ __libc_res_nquerydomain(res_state statp,
|
||||
u_char **answerp,
|
||||
u_char **answerp2,
|
||||
int *nanswerp2,
|
||||
int *resplen2)
|
||||
int *resplen2,
|
||||
int *answerp2_malloced)
|
||||
{
|
||||
char nbuf[MAXDNAME];
|
||||
const char *longname = nbuf;
|
||||
@ -581,7 +587,7 @@ __libc_res_nquerydomain(res_state statp,
|
||||
}
|
||||
return (__libc_res_nquery(statp, longname, class, type, answer,
|
||||
anslen, answerp, answerp2, nanswerp2,
|
||||
resplen2));
|
||||
resplen2, answerp2_malloced));
|
||||
}
|
||||
|
||||
int
|
||||
@ -593,7 +599,8 @@ res_nquerydomain(res_state statp,
|
||||
int anslen) /* size of answer */
|
||||
{
|
||||
return __libc_res_nquerydomain(statp, name, domain, class, type,
|
||||
answer, anslen, NULL, NULL, NULL, NULL);
|
||||
answer, anslen, NULL, NULL, NULL, NULL,
|
||||
NULL);
|
||||
}
|
||||
libresolv_hidden_def (res_nquerydomain)
|
||||
|
||||
|
Reference in New Issue
Block a user