Handle running out of buffer space with IPv6 mapping enabled.

With big DNS answers like the one you get for goodtimesdot.com you can
get a truncated address list if IPv6 mapping is enabled.  Instead tell
the caller to resize the buffer.
This commit is contained in:
Andreas Schwab 2009-11-10 07:36:50 -08:00 committed by Ulrich Drepper
parent 6515a01fc1
commit 51e4196f16
3 changed files with 17 additions and 9 deletions

View File

@ -1,7 +1,15 @@
2009-11-10 Andreas Schwab <schwab@redhat.com>
* resolv/mapv4v6hostent.h (map_v4v6_hostent): Return non-zero if
out of buffer space.
* resolv/nss_dns/dns-host.c (getanswer_r): Check for
map_v4v6_hostent running out of space.
2009-11-10 Ulrich Drepper <drepper@redhat.com> 2009-11-10 Ulrich Drepper <drepper@redhat.com>
* string/bits/string3.h (memset): If the second parameter is constant * string/bits/string3.h (memset): If the second parameter is constant
and zero there is likely no transposition. and zero there is likely no transposition.
Patch by Caolan McNamara <caolanm@redhat.com.
2009-11-04 Philippe De Muyter <phdm@macqel.be> 2009-11-04 Philippe De Muyter <phdm@macqel.be>

View File

@ -57,13 +57,13 @@ typedef union {
char ac; char ac;
} align; } align;
static void static int
map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp) map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp)
{ {
char **ap; char **ap;
if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
return; return 0;
hp->h_addrtype = AF_INET6; hp->h_addrtype = AF_INET6;
hp->h_length = IN6ADDRSZ; hp->h_length = IN6ADDRSZ;
for (ap = hp->h_addr_list; *ap; ap++) for (ap = hp->h_addr_list; *ap; ap++)
@ -71,11 +71,8 @@ map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp)
int i = sizeof (align) - ((u_long) *bpp % sizeof (align)); int i = sizeof (align) - ((u_long) *bpp % sizeof (align));
if (*lenp < (i + IN6ADDRSZ)) if (*lenp < (i + IN6ADDRSZ))
{ /* Out of memory. */
/* Out of memory. Truncate address list here. XXX */ return 1;
*ap = NULL;
return;
}
*bpp += i; *bpp += i;
*lenp -= i; *lenp -= i;
map_v4v6_address (*ap, *bpp); map_v4v6_address (*ap, *bpp);
@ -83,4 +80,5 @@ map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp)
*bpp += IN6ADDRSZ; *bpp += IN6ADDRSZ;
*lenp -= IN6ADDRSZ; *lenp -= IN6ADDRSZ;
} }
return 0;
} }

View File

@ -878,7 +878,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
} }
bp += n; bp += n;
linebuflen -= n; linebuflen -= n;
map_v4v6_hostent (result, &bp, &linebuflen); if (map_v4v6_hostent (result, &bp, &linebuflen))
goto too_small;
} }
*h_errnop = NETDB_SUCCESS; *h_errnop = NETDB_SUCCESS;
return NSS_STATUS_SUCCESS; return NSS_STATUS_SUCCESS;
@ -953,7 +954,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
} }
if (have_to_map) if (have_to_map)
map_v4v6_hostent (result, &bp, &linebuflen); if (map_v4v6_hostent (result, &bp, &linebuflen))
goto too_small;
*h_errnop = NETDB_SUCCESS; *h_errnop = NETDB_SUCCESS;
return NSS_STATUS_SUCCESS; return NSS_STATUS_SUCCESS;
} }