diff options
author | Andreas Schwab <schwab@redhat.com> | 2009-11-10 07:36:50 -0800 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2009-11-10 07:36:50 -0800 |
commit | 51e4196f16a2d98377e3c481a44e133369dc7669 (patch) | |
tree | e2d83a34e0bbe6f47dfe733f6062b6508e4d6868 | |
parent | 6515a01fc1d35d329886d5a45435537ee9115bc4 (diff) | |
download | glibc-51e4196f16a2d98377e3c481a44e133369dc7669.tar.gz glibc-51e4196f16a2d98377e3c481a44e133369dc7669.tar.xz glibc-51e4196f16a2d98377e3c481a44e133369dc7669.zip |
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.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | resolv/mapv4v6hostent.h | 12 | ||||
-rw-r--r-- | resolv/nss_dns/dns-host.c | 6 |
3 files changed, 17 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog index ac8baf13be..49c2e08a4a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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> * string/bits/string3.h (memset): If the second parameter is constant and zero there is likely no transposition. + Patch by Caolan McNamara <caolanm@redhat.com. 2009-11-04 Philippe De Muyter <phdm@macqel.be> diff --git a/resolv/mapv4v6hostent.h b/resolv/mapv4v6hostent.h index 4151ce3639..c11038adf3 100644 --- a/resolv/mapv4v6hostent.h +++ b/resolv/mapv4v6hostent.h @@ -57,13 +57,13 @@ typedef union { char ac; } align; -static void +static int map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp) { char **ap; if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) - return; + return 0; hp->h_addrtype = AF_INET6; hp->h_length = IN6ADDRSZ; 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)); if (*lenp < (i + IN6ADDRSZ)) - { - /* Out of memory. Truncate address list here. XXX */ - *ap = NULL; - return; - } + /* Out of memory. */ + return 1; *bpp += i; *lenp -= i; map_v4v6_address (*ap, *bpp); @@ -83,4 +80,5 @@ map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp) *bpp += IN6ADDRSZ; *lenp -= IN6ADDRSZ; } + return 0; } diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c index 62e67e8b01..818a40a898 100644 --- a/resolv/nss_dns/dns-host.c +++ b/resolv/nss_dns/dns-host.c @@ -878,7 +878,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, } bp += n; linebuflen -= n; - map_v4v6_hostent (result, &bp, &linebuflen); + if (map_v4v6_hostent (result, &bp, &linebuflen)) + goto too_small; } *h_errnop = NETDB_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) - map_v4v6_hostent (result, &bp, &linebuflen); + if (map_v4v6_hostent (result, &bp, &linebuflen)) + goto too_small; *h_errnop = NETDB_SUCCESS; return NSS_STATUS_SUCCESS; } |