Date: Tue, 1 Dec 2020 19:35:48 +0000 (UTC) From: Mark Johnston <markj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r368250 - stable/12/usr.sbin/rtsold Message-ID: <202012011935.0B1JZmt9003950@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: markj Date: Tue Dec 1 19:35:48 2020 New Revision: 368250 URL: https://svnweb.freebsd.org/changeset/base/368250 Log: MFC r368248: rtsold: Fix multiple buffer overflows Approved by: so Security: CVE-2020-25577 Modified: stable/12/usr.sbin/rtsold/rtsol.c Directory Properties: stable/12/ (props changed) Modified: stable/12/usr.sbin/rtsold/rtsol.c ============================================================================== --- stable/12/usr.sbin/rtsold/rtsol.c Tue Dec 1 19:34:45 2020 (r368249) +++ stable/12/usr.sbin/rtsold/rtsol.c Tue Dec 1 19:35:48 2020 (r368250) @@ -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';
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202012011935.0B1JZmt9003950>