|
|
|
View Notes By
|
|
|
|
Other Documents
|
|
|
|
|
GNU glibc Information for VU#844360
| Date Notified | 11/12/2002 |
| Date Modified | 04/24/2003 12:10:01 AM |
| Status Summary | Vulnerable |
Vendor StatementVersion 2.3.1 of the GNU C Library is vulnerable. Earlier versions are also vulnerable. The following patch has been installed into the CVS sources, and should appear in the next version of the GNU C Library. This patch is also available from the following URL:
<http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/resolv/nss_dns/dns-network.c.diff?r1=1.17&r2=1.15&cvsroot=glibc>
2002-11-18 Roland McGrath <roland@redhat.com>
* resolv/nss_dns/dns-network.c (getanswer_r): In BYNAME case, search
all aliases for one that matches the "<dotted-quad>.IN-ADDR.ARPA" form.
Do the parsing inline instead of copying strings and calling
inet_network, and properly skip all alias names not matching the form.
2002-11-14 Paul Eggert <eggert@twinsun.com>
* resolv/nss_dns/dns-network.c (getanswer_r): Check for buffer
overflow when skipping the question part and when unpacking aliases.
===================================================================
RCS file: /cvs/glibc/libc/resolv/nss_dns/dns-network.c,v
retrieving revision 1.15
retrieving revision 1.17
diff -u -r1.15 -r1.17
--- libc/resolv/nss_dns/dns-network.c 2002/10/17 21:49:12 1.15
+++ libc/resolv/nss_dns/dns-network.c 2002/11/19 06:40:16 1.17
@@ -283,7 +283,15 @@
/* Skip the question part. */
while (question_count-- > 0)
- cp += __dn_skipname (cp, end_of_message) + QFIXEDSZ;
+ {
+ int n = __dn_skipname (cp, end_of_message);
+ if (n < 0 || end_of_message - (cp + n) < QFIXEDSZ)
+ {
+ __set_h_errno (NO_RECOVERY);
+ return NSS_STATUS_UNAVAIL;
+ }
+ cp += n + QFIXEDSZ;
+ }
alias_pointer = result->n_aliases = &net_data->aliases[0];
*alias_pointer = NULL;
@@ -344,64 +352,94 @@
return NSS_STATUS_UNAVAIL;
}
cp += n;
- *alias_pointer++ = bp;
- n = strlen (bp) + 1;
- bp += n;
- linebuflen -= n;
- result->n_addrtype = class == C_IN ? AF_INET : AF_UNSPEC;
- ++have_answer;
+ if (alias_pointer + 2 < &net_data->aliases[MAX_NR_ALIASES])
+ {
+ *alias_pointer++ = bp;
+ n = strlen (bp) + 1;
+ bp += n;
+ linebuflen -= n;
+ result->n_addrtype = class == C_IN ? AF_INET : AF_UNSPEC;
+ ++have_answer;
+ }
}
}
if (have_answer)
{
- char *tmp;
- int len;
- char *in, *cp, *rp, *wp;
- int cnt, first_flag;
-
*alias_pointer = NULL;
switch (net_i)
{
case BYADDR:
- result->n_name = result->n_aliases[0];
+ result->n_name = *result->n_aliases++;
result->n_net = 0L;
- break;
- case BYNAME:
- len = strlen (result->n_aliases[0]);
- tmp = (char *) alloca (len + 1);
- tmp[len] = 0;
- wp = &tmp[len - 1];
-
- rp = in = result->n_aliases[0];
- result->n_name = ans;
-
- first_flag = 1;
- for (cnt = 0; cnt < 4; ++cnt)
- {
- char *startp;
+ return NSS_STATUS_SUCCESS;
- startp = rp;
- while (*rp != '.')
- ++rp;
- if (rp - startp > 1 || *startp != '0' || !first_flag)
- {
- first_flag = 0;
- if (cnt > 0)
- *wp-- = '.';
- cp = rp;
- while (cp > startp)
- *wp-- = *--cp;
- }
- in = rp + 1;
- }
-
- result->n_net = inet_network (wp);
+ case BYNAME:
+ {
+ char **ap = result->n_aliases++;
+ while (*ap != NULL)
+ {
+ /* Check each alias name for being of the forms:
+ 4.3.2.1.in-addr.arpa = net 1.2.3.4
+ 3.2.1.in-addr.arpa = net 0.1.2.3
+ 2.1.in-addr.arpa = net 0.0.1.2
+ 1.in-addr.arpa = net 0.0.0.1
+ */
+ uint32_t val = 0; /* Accumulator for n_net value. */
+ unsigned int shift = 0; /* Which part we are parsing now. */
+ const char *p = *ap; /* Consuming the string. */
+ do
+ {
+ /* Match the leading 0 or 0[xX] base indicator. */
+ unsigned int base = 10;
+ if (*p == '0' && p[1] != '.')
+ {
+ base = 8;
+ ++p;
+ if (*p == 'x' || *p == 'X')
+ {
+ base = 16;
+ ++p;
+ if (*p == '.')
+ break; /* No digit here. Give up on alias. */
+ }
+ if (*p == '\0')
+ break;
+ }
+
+ uint32_t part = 0; /* Accumulates this part's number. */
+ do
+ {
+ if (isdigit (*p) && (*p - '0' < base))
+ part = (part * base) + (*p - '0');
+ else if (base == 16 && isxdigit (*p))
+ part = (part << 4) + 10 + (tolower (*p) - 'a');
+ ++p;
+ } while (*p != '\0' && *p != '.');
+
+ if (*p != '.')
+ break; /* Bad form. Give up on this name. */
+
+ /* Install this as the next more significant byte. */
+ val |= part << shift;
+ shift += 8;
+ ++p;
+
+ /* If we are out of digits now, there are two cases:
+ 1. We are done with digits and now see "in-addr.arpa".
+ 2. This is not the droid we are looking for. */
+ if (!isdigit (*p) && !strcasecmp (p, "in-addr.arpa"))
+ {
+ result->n_net = val;
+ return NSS_STATUS_SUCCESS;
+ }
+
+ /* Keep going when we have seen fewer than 4 parts. */
+ } while (shift < 32);
+ }
+ }
break;
}
-
- ++result->n_aliases;
- return NSS_STATUS_SUCCESS;
}
__set_h_errno (TRY_AGAIN);
US-CERT AddendumThe CERT/CC has no additional comments at this time.
If you have feedback, comments, or additional information about this vulnerability, please send us
email.
|
 |