rtsold: Fix multiple buffer overflows

Approved by:	so
Security:	CVE-2020-25577
MFC after:	now
This commit is contained in:
markj 2020-12-01 19:34:44 +00:00
parent 79861445bc
commit 5381f89770

View File

@ -337,8 +337,8 @@ rtsol_input(int sock)
newent_rai = 1; newent_rai = 1;
} }
#define RA_OPT_NEXT_HDR(x) (struct nd_opt_hdr *)((char *)x + \ #define RA_OPT_NEXT_HDR(x) (struct nd_opt_hdr *)((char *)(x) + \
(((struct nd_opt_hdr *)x)->nd_opt_len * 8)) (((struct nd_opt_hdr *)(x))->nd_opt_len * 8))
/* Process RA options. */ /* Process RA options. */
warnmsg(LOG_DEBUG, __func__, "Processing RA"); warnmsg(LOG_DEBUG, __func__, "Processing RA");
raoptp = (char *)icp + sizeof(struct nd_router_advert); raoptp = (char *)icp + sizeof(struct nd_router_advert);
@ -350,6 +350,15 @@ rtsol_input(int sock)
warnmsg(LOG_DEBUG, __func__, "ndo->nd_opt_len = %d", warnmsg(LOG_DEBUG, __func__, "ndo->nd_opt_len = %d",
ndo->nd_opt_len); ndo->nd_opt_len);
if (ndo->nd_opt_len == 0) {
warnmsg(LOG_INFO, __func__, "invalid option length 0.");
break;
}
if ((char *)RA_OPT_NEXT_HDR(raoptp) > (char *)icp + msglen) {
warnmsg(LOG_INFO, __func__, "option length overflow.");
break;
}
switch (ndo->nd_opt_type) { switch (ndo->nd_opt_type) {
case ND_OPT_RDNSS: case ND_OPT_RDNSS:
rdnss = (struct nd_opt_rdnss *)raoptp; rdnss = (struct nd_opt_rdnss *)raoptp;
@ -760,15 +769,18 @@ dname_labeldec(char *dst, size_t dlen, const char *src)
src_last = strchr(src, '\0'); src_last = strchr(src, '\0');
dst_origin = dst; dst_origin = dst;
memset(dst, '\0', dlen); memset(dst, '\0', dlen);
while (src && (len = (uint8_t)(*src++) & 0x3f) && while ((len = (*src++) & 0x3f) &&
(src + len) <= src_last && src + len <= src_last &&
(dst - dst_origin < (ssize_t)dlen)) { len + (dst == dst_origin ? 0 : 1) < dlen) {
if (dst != dst_origin) if (dst != dst_origin) {
*dst++ = '.'; *dst++ = '.';
dlen--;
}
warnmsg(LOG_DEBUG, __func__, "labellen = %zd", len); warnmsg(LOG_DEBUG, __func__, "labellen = %zd", len);
memcpy(dst, src, len); memcpy(dst, src, len);
src += len; src += len;
dst += len; dst += len;
dlen -= len;
} }
*dst = '\0'; *dst = '\0';