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.
pull/2/head
Yang Tse 15 years ago
parent 2c26d7d254
commit e03a65c3d9
  1. 1
      CHANGES
  2. 1
      RELEASE-NOTES
  3. 19
      inet_net_pton.c

@ -8,6 +8,7 @@ Fixed:
o detection of semicolon comments in resolv.conf o detection of semicolon comments in resolv.conf
o avoid using system's inet_net_pton affected by the WLB-2008080064 advisory o avoid using system's inet_net_pton affected by the WLB-2008080064 advisory
o replacement ares_inet_net_pton affected by the WLB-2008080064 advisory
Version 1.7.4 (December 9, 2010) Version 1.7.4 (December 9, 2010)

@ -8,6 +8,7 @@ Fixed:
o detection of semicolon comments in resolv.conf o detection of semicolon comments in resolv.conf
o avoid using system's inet_net_pton affected by the WLB-2008080064 advisory o avoid using system's inet_net_pton affected by the WLB-2008080064 advisory
o replacement ares_inet_net_pton affected by the WLB-2008080064 advisory
Thanks go to these friendly people for their efforts and contributions: Thanks go to these friendly people for their efforts and contributions:

@ -83,13 +83,14 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
ch = *src++; ch = *src++;
if (ch == '0' && (src[0] == 'x' || src[0] == 'X') if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
&& ISASCII(src[1])
&& ISXDIGIT(src[1])) { && ISXDIGIT(src[1])) {
/* Hexadecimal: Eat nybble string. */ /* Hexadecimal: Eat nybble string. */
if (!size) if (!size)
goto emsgsize; goto emsgsize;
dirty = 0; dirty = 0;
src++; /* skip x or X. */ src++; /* skip x or X. */
while ((ch = *src++) != '\0' && ISXDIGIT(ch)) { while ((ch = *src++) != '\0' && ISASCII(ch) && ISXDIGIT(ch)) {
if (ISUPPER(ch)) if (ISUPPER(ch))
ch = tolower(ch); ch = tolower(ch);
n = (int)(strchr(xdigits, ch) - xdigits); 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; goto emsgsize;
*dst++ = (unsigned char) (tmp << 4); *dst++ = (unsigned char) (tmp << 4);
} }
} else if (ISDIGIT(ch)) { } else if (ISASCII(ch) && ISDIGIT(ch)) {
/* Decimal: eat dotted digit string. */ /* Decimal: eat dotted digit string. */
for (;;) { for (;;) {
tmp = 0; tmp = 0;
@ -120,7 +121,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
if (tmp > 255) if (tmp > 255)
goto enoent; goto enoent;
} while ((ch = *src++) != '\0' && } while ((ch = *src++) != '\0' &&
ISDIGIT(ch)); ISASCII(ch) && ISDIGIT(ch));
if (!size--) if (!size--)
goto emsgsize; goto emsgsize;
*dst++ = (unsigned char) tmp; *dst++ = (unsigned char) tmp;
@ -129,14 +130,14 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
if (ch != '.') if (ch != '.')
goto enoent; goto enoent;
ch = *src++; ch = *src++;
if (!ISDIGIT(ch)) if (!ISASCII(ch) || !ISDIGIT(ch))
goto enoent; goto enoent;
} }
} else } else
goto enoent; goto enoent;
bits = -1; bits = -1;
if (ch == '/' && if (ch == '/' && ISASCII(src[0]) &&
ISDIGIT(src[0]) && dst > odst) { ISDIGIT(src[0]) && dst > odst) {
/* CIDR width specifier. Nothing can follow it. */ /* CIDR width specifier. Nothing can follow it. */
ch = *src++; /* Skip over the /. */ 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); n = (int)(strchr(digits, ch) - digits);
bits *= 10; bits *= 10;
bits += n; bits += n;
} while ((ch = *src++) != '\0' && ISDIGIT(ch)); if (bits > 32)
goto enoent;
} while ((ch = *src++) != '\0' && ISASCII(ch) && ISDIGIT(ch));
if (ch != '\0') if (ch != '\0')
goto enoent; goto enoent;
if (bits > 32)
goto emsgsize;
} }
/* Firey death and destruction unless we prefetched EOS. */ /* 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 0;
return (result > -1 ? 1 : -1); return (result > -1 ? 1 : -1);
} }
#endif /* HAVE_INET_PTON */ #endif

Loading…
Cancel
Save