From f2fb8af155226583c50c1d836b83e21a3d40832c Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 1 Dec 2020 19:34:44 +0000 Subject: rtsold: Fix multiple buffer overflows Approved by: so Security: CVE-2020-25577 MFC after: now --- usr.sbin/rtsold/rtsol.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'usr.sbin/rtsold') diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c index cbdc12f84c03..30027fc65ac9 100644 --- a/usr.sbin/rtsold/rtsol.c +++ b/usr.sbin/rtsold/rtsol.c @@ -337,8 +337,8 @@ rtsol_input(int sock) newent_rai = 1; } -#define RA_OPT_NEXT_HDR(x) (struct nd_opt_hdr *)((char *)x + \ - (((struct nd_opt_hdr *)x)->nd_opt_len * 8)) +#define RA_OPT_NEXT_HDR(x) (struct nd_opt_hdr *)((char *)(x) + \ + (((struct nd_opt_hdr *)(x))->nd_opt_len * 8)) /* Process RA options. */ warnmsg(LOG_DEBUG, __func__, "Processing RA"); 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", 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) { case ND_OPT_RDNSS: 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'); dst_origin = dst; memset(dst, '\0', dlen); - while (src && (len = (uint8_t)(*src++) & 0x3f) && - (src + len) <= src_last && - (dst - dst_origin < (ssize_t)dlen)) { - if (dst != dst_origin) + while ((len = (*src++) & 0x3f) && + src + len <= src_last && + len + (dst == dst_origin ? 0 : 1) < dlen) { + if (dst != dst_origin) { *dst++ = '.'; + dlen--; + } warnmsg(LOG_DEBUG, __func__, "labellen = %zd", len); memcpy(dst, src, len); src += len; dst += len; + dlen -= len; } *dst = '\0'; -- cgit v1.2.3