From owner-svn-src-stable@freebsd.org Tue Dec 1 19:35:48 2020 Return-Path: Delivered-To: svn-src-stable@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id CF7474B22D9; Tue, 1 Dec 2020 19:35:48 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4ClslS5Vvjz4lK3; Tue, 1 Dec 2020 19:35:48 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id AFAAF1AF2A; Tue, 1 Dec 2020 19:35:48 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0B1JZmRc003951; Tue, 1 Dec 2020 19:35:48 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0B1JZmt9003950; Tue, 1 Dec 2020 19:35:48 GMT (envelope-from markj@FreeBSD.org) Message-Id: <202012011935.0B1JZmt9003950@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Tue, 1 Dec 2020 19:35:48 +0000 (UTC) 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 X-SVN-Group: stable-12 X-SVN-Commit-Author: markj X-SVN-Commit-Paths: stable/12/usr.sbin/rtsold X-SVN-Commit-Revision: 368250 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Dec 2020 19:35:48 -0000 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';