diff options
author | hrs <hrs@FreeBSD.org> | 2011-06-04 01:11:34 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2011-06-04 01:11:34 +0000 |
commit | 414167aef9f91f9b70350d9b86f0381d619b091b (patch) | |
tree | fc9f3786b8c053b02b4af9e2288ee06e958eecf4 /usr.sbin | |
parent | d45e9a2064d99aea984c4b96d47bb3b7c29b42d3 (diff) | |
download | FreeBSD-src-414167aef9f91f9b70350d9b86f0381d619b091b.zip FreeBSD-src-414167aef9f91f9b70350d9b86f0381d619b091b.tar.gz |
- 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.
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/rtadvd/dump.c | 7 | ||||
-rw-r--r-- | usr.sbin/rtsold/rtsol.c | 14 |
2 files changed, 17 insertions, 4 deletions
diff --git a/usr.sbin/rtadvd/dump.c b/usr.sbin/rtadvd/dump.c index 97dc122..704d5d8 100644 --- a/usr.sbin/rtadvd/dump.c +++ b/usr.sbin/rtadvd/dump.c @@ -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, const char *src) { 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); diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c index e5184f1..76ebe96 100644 --- a/usr.sbin/rtsold/rtsol.c +++ b/usr.sbin/rtsold/rtsol.c @@ -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, const char *src) { 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); |