From e03a65c3d9b2eb47f6ce6234823913638cb6c816 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 15 Dec 2010 02:44:07 +0100 Subject: ares_inet_net_pton: fix non-rejection of some malformed literals ares_inet_net_pton would return wrong values when excessively large, and invalid, netmasks are used. Fixes are from bind-9.5.3rc1, issue also described in the WLB-2008080064 advisory. --- inet_net_pton.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'inet_net_pton.c') diff --git a/inet_net_pton.c b/inet_net_pton.c index d9165e7..9bbe7aa 100644 --- a/inet_net_pton.c +++ b/inet_net_pton.c @@ -83,13 +83,14 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) ch = *src++; if (ch == '0' && (src[0] == 'x' || src[0] == 'X') + && ISASCII(src[1]) && ISXDIGIT(src[1])) { /* Hexadecimal: Eat nybble string. */ if (!size) goto emsgsize; dirty = 0; src++; /* skip x or X. */ - while ((ch = *src++) != '\0' && ISXDIGIT(ch)) { + while ((ch = *src++) != '\0' && ISASCII(ch) && ISXDIGIT(ch)) { if (ISUPPER(ch)) ch = tolower(ch); n = (int)(strchr(xdigits, ch) - xdigits); @@ -109,7 +110,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) goto emsgsize; *dst++ = (unsigned char) (tmp << 4); } - } else if (ISDIGIT(ch)) { + } else if (ISASCII(ch) && ISDIGIT(ch)) { /* Decimal: eat dotted digit string. */ for (;;) { tmp = 0; @@ -120,7 +121,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) if (tmp > 255) goto enoent; } while ((ch = *src++) != '\0' && - ISDIGIT(ch)); + ISASCII(ch) && ISDIGIT(ch)); if (!size--) goto emsgsize; *dst++ = (unsigned char) tmp; @@ -129,14 +130,14 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) if (ch != '.') goto enoent; ch = *src++; - if (!ISDIGIT(ch)) + if (!ISASCII(ch) || !ISDIGIT(ch)) goto enoent; } } else goto enoent; bits = -1; - if (ch == '/' && + if (ch == '/' && ISASCII(src[0]) && ISDIGIT(src[0]) && dst > odst) { /* CIDR width specifier. Nothing can follow it. */ ch = *src++; /* Skip over the /. */ @@ -145,11 +146,11 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) n = (int)(strchr(digits, ch) - digits); bits *= 10; bits += n; - } while ((ch = *src++) != '\0' && ISDIGIT(ch)); + if (bits > 32) + goto enoent; + } while ((ch = *src++) != '\0' && ISASCII(ch) && ISDIGIT(ch)); if (ch != '\0') goto enoent; - if (bits > 32) - goto emsgsize; } /* Firey death and destruction unless we prefetched EOS. */ @@ -447,4 +448,4 @@ int ares_inet_pton(int af, const char *src, void *dst) return 0; return (result > -1 ? 1 : -1); } -#endif /* HAVE_INET_PTON */ +#endif -- cgit v1.2.3