svn commit: r222662 - in user/hrs/ipv6/usr.sbin: rtadvd rtsold
Hiroki Sato
hrs at FreeBSD.org
Sat Jun 4 01:11:35 UTC 2011
Author: hrs
Date: Sat Jun 4 01:11:34 2011
New Revision: 222662
URL: http://svn.freebsd.org/changeset/base/222662
Log:
- Add another length check for DNSSL option. A malformed ICMP message can have
no '\0' in the search list and/or invalid length field.
- NI_MAXHOST is defined including \0.
Modified:
user/hrs/ipv6/usr.sbin/rtadvd/dump.c
user/hrs/ipv6/usr.sbin/rtsold/rtsol.c
Modified: user/hrs/ipv6/usr.sbin/rtadvd/dump.c
==============================================================================
--- user/hrs/ipv6/usr.sbin/rtadvd/dump.c Fri Jun 3 21:17:42 2011 (r222661)
+++ user/hrs/ipv6/usr.sbin/rtadvd/dump.c Sat Jun 4 01:11:34 2011 (r222662)
@@ -254,7 +254,7 @@ if_dump(void)
TAILQ_FOREACH(dns, &rai->dnssl, dn_next) {
struct dnssl_addr *dnsa;
- char buf[NI_MAXHOST + 1];
+ char buf[NI_MAXHOST];
if (dns == TAILQ_FIRST(&rai->dnssl))
fprintf(fp, " DNS search list:\n"
@@ -295,12 +295,15 @@ dname_labeldec(char *dst, size_t dlen, c
{
size_t len;
const char *src_origin;
+ const char *src_last;
const char *dst_origin;
src_origin = src;
+ src_last = strchr(src, '\0');
dst_origin = dst;
memset(dst, '\0', dlen);
- while (src && (len = (uint8_t)(*src++) & 0x3f)) {
+ while (src && (len = (uint8_t)(*src++) & 0x3f) &&
+ (src + len) <= src_last) {
if (dst != dst_origin)
*dst++ = '.';
syslog(LOG_DEBUG, "<%s> labellen = %d", __func__, len);
Modified: user/hrs/ipv6/usr.sbin/rtsold/rtsol.c
==============================================================================
--- user/hrs/ipv6/usr.sbin/rtsold/rtsol.c Fri Jun 3 21:17:42 2011 (r222661)
+++ user/hrs/ipv6/usr.sbin/rtsold/rtsol.c Sat Jun 4 01:11:34 2011 (r222662)
@@ -248,7 +248,7 @@ rtsol_input(int s)
struct nd_opt_dnssl *dnssl;
size_t len;
char nsbuf[INET6_ADDRSTRLEN + 1 + IFNAMSIZ + 1 + 1];
- char dname[NI_MAXHOST + 1];
+ char dname[NI_MAXHOST];
struct timeval now;
struct timeval lifetime;
@@ -474,6 +474,13 @@ rtsol_input(int s)
break;
}
+ /*
+ * Ensure NUL-termination in DNSSL in case of
+ * malformed field.
+ */
+ p = (char *)RA_OPT_NEXT_HDR(raoptp);
+ *(p - 1) = '\0';
+
p = raoptp + sizeof(*dnssl);
while (1 < (len = dname_labeldec(dname, sizeof(dname),
p))) {
@@ -790,12 +797,15 @@ dname_labeldec(char *dst, size_t dlen, c
{
size_t len;
const char *src_origin;
+ const char *src_last;
const char *dst_origin;
src_origin = src;
+ src_last = strchr(src, '\0');
dst_origin = dst;
memset(dst, '\0', dlen);
- while (src && (len = (uint8_t)(*src++) & 0x3f)) {
+ while (src && (len = (uint8_t)(*src++) & 0x3f) &&
+ (src + len) <= src_last) {
if (dst != dst_origin)
*dst++ = '.';
warnmsg(LOG_DEBUG, __func__, "labellen = %zd", len);
More information about the svn-src-user
mailing list