diff options
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/net/getaddrinfo.c | 4 | ||||
-rw-r--r-- | lib/libc/net/gethostbydns.c | 8 | ||||
-rw-r--r-- | lib/libc/net/getnetbydns.c | 16 | ||||
-rw-r--r-- | lib/libc/net/hesiod.c | 4 | ||||
-rw-r--r-- | lib/libc/net/name6.c | 14 | ||||
-rw-r--r-- | lib/libc/net/res_update.c | 8 |
6 files changed, 42 insertions, 12 deletions
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index 0f724f9..ccd5d6e 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -1829,7 +1829,9 @@ res_queryN(name, target) } #endif - if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { + if (n < 0 || n > anslen) + hp->rcode = FORMERR; /* XXX not very informative */ + if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { rcode = hp->rcode; /* record most recent error */ #ifdef DEBUG if (_res.options & RES_DEBUG) diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c index 1044727..0effbe4 100644 --- a/lib/libc/net/gethostbydns.c +++ b/lib/libc/net/gethostbydns.c @@ -587,9 +587,13 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap) break; } - if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) { + n = res_search(name, C_IN, type, buf.buf, sizeof(buf.buf)); + if (n < 0) { dprintf("res_search failed (%d)\n", n); - return NS_UNAVAIL; + return (NULL); + } else if (n > sizeof(buf.buf)) { + dprintf("static buffer is too small (%d)\n", n); + return (NULL); } *(struct hostent **)rval = gethostanswer(&buf, n, name, type); return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND; diff --git a/lib/libc/net/getnetbydns.c b/lib/libc/net/getnetbydns.c index 369bf2b..fd771f2 100644 --- a/lib/libc/net/getnetbydns.c +++ b/lib/libc/net/getnetbydns.c @@ -263,7 +263,13 @@ _dns_getnetbyaddr(void *rval, void *cb_data, va_list ap) if (anslen < 0) { #ifdef DEBUG if (_res.options & RES_DEBUG) - printf("res_query failed\n"); + printf("res_search failed\n"); +#endif + return NS_UNAVAIL; + } else if (anslen > sizeof(buf)) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf("res_search static buffer too small"); #endif return NS_UNAVAIL; } @@ -303,7 +309,13 @@ _dns_getnetbyname(void *rval, void *cb_data, va_list ap) if (anslen < 0) { #ifdef DEBUG if (_res.options & RES_DEBUG) - printf("res_query failed\n"); + printf("res_search failed\n"); +#endif + return NS_UNAVAIL; + } else if (anslen > sizeof(buf)) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf("res_search static buffer too small"); #endif return NS_UNAVAIL; } diff --git a/lib/libc/net/hesiod.c b/lib/libc/net/hesiod.c index 701244a..c22bdba 100644 --- a/lib/libc/net/hesiod.c +++ b/lib/libc/net/hesiod.c @@ -386,8 +386,8 @@ get_txt_records(qclass, name) /* Send the query. */ n = res_send(qbuf, n, abuf, MAX_HESRESP); - if (n < 0) { - errno = ECONNREFUSED; + if (n < 0 || n > MAX_HESRESP) { + errno = ECONNREFUSED; /* XXX */ return NULL; } /* Parse the header of the result. */ diff --git a/lib/libc/net/name6.c b/lib/libc/net/name6.c index d80f9c2..3fa8aae 100644 --- a/lib/libc/net/name6.c +++ b/lib/libc/net/name6.c @@ -1287,7 +1287,7 @@ _res_search_multi(name, rtl, errp) rtl = SLIST_NEXT(rtl, rtl_entry)) { ret = res_query(cp, C_IN, rtl->rtl_type, buf.buf, sizeof(buf.buf)); - if (ret > 0) { + if (ret > 0 && ret < sizeof(buf.buf)) { hpbuf.h_addrtype = (rtl->rtl_type == T_AAAA) ? AF_INET6 : AF_INET; hpbuf.h_length = ADDRLEN(hpbuf.h_addrtype); @@ -1312,7 +1312,7 @@ _res_search_multi(name, rtl, errp) rtl = SLIST_NEXT(rtl, rtl_entry)) { ret = res_querydomain(name, NULL, C_IN, rtl->rtl_type, buf.buf, sizeof(buf.buf)); - if (ret > 0) { + if (ret > 0 && ret < sizeof(buf.buf)) { hpbuf.h_addrtype = (rtl->rtl_type == T_AAAA) ? AF_INET6 : AF_INET; hpbuf.h_length = ADDRLEN(hpbuf.h_addrtype); @@ -1349,7 +1349,7 @@ _res_search_multi(name, rtl, errp) ret = res_querydomain(name, *domain, C_IN, rtl->rtl_type, buf.buf, sizeof(buf.buf)); - if (ret > 0) { + if (ret > 0 && ret < sizeof(buf.buf)) { hpbuf.h_addrtype = (rtl->rtl_type == T_AAAA) ? AF_INET6 : AF_INET; hpbuf.h_length = ADDRLEN(hpbuf.h_addrtype); @@ -1419,7 +1419,7 @@ _res_search_multi(name, rtl, errp) rtl = SLIST_NEXT(rtl, rtl_entry)) { ret = res_querydomain(name, NULL, C_IN, rtl->rtl_type, buf.buf, sizeof(buf.buf)); - if (ret > 0) { + if (ret > 0 && ret < sizeof(buf.buf)) { hpbuf.h_addrtype = (rtl->rtl_type == T_AAAA) ? AF_INET6 : AF_INET; hpbuf.h_length = ADDRLEN(hpbuf.h_addrtype); @@ -1570,6 +1570,12 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap) if (n < 0) { *errp = h_errno; return NS_UNAVAIL; + } else if (n > sizeof(buf.buf)) { +#if 0 + errno = ERANGE; /* XXX is it OK to set errno here? */ +#endif + *errp = NETDB_INTERNAL; + return NS_UNAVAIL; } hp = getanswer(&buf, n, qbuf, T_PTR, &hbuf, errp); if (!hp) diff --git a/lib/libc/net/res_update.c b/lib/libc/net/res_update.c index f17374f..fda6f77 100644 --- a/lib/libc/net/res_update.c +++ b/lib/libc/net/res_update.c @@ -159,6 +159,9 @@ res_update(ns_updrec *rrecp_in) { fprintf(stderr, "res_update: send error for %s\n", rrecp->r_dname); return (n); + } else if (n > sizeof(answer)) { + fprintf(stderr, "res_update: buffer too small\n"); + return (-1); } if (n < HFIXEDSZ) return (-1); @@ -498,7 +501,10 @@ ans=%d, auth=%d, add=%d, rcode=%d\n", if (n < 0) { fprintf(stderr, "res_send: send error, n=%d\n", n); break; - } else + } else if (n > sizeof(answer)) { + fprintf(stderr, "res_send: buffer too small\n"); + break; + } numzones++; } |