svn commit: r368256 - in releng: 11.4/usr.sbin/rtsold 12.1/usr.sbin/rtsold 12.2/usr.sbin/rtsold
Gordon Tetlow
gordon at FreeBSD.org
Tue Dec 1 19:39:45 UTC 2020
Author: gordon
Date: Tue Dec 1 19:39:44 2020
New Revision: 368256
URL: https://svnweb.freebsd.org/changeset/base/368256
Log:
Fix multiple vulnerabilities in rtsold.
Approved by: so
Security: FreeBSD-SA-20:32.rtsold
Security: CVE-2020-25577
Modified:
releng/11.4/usr.sbin/rtsold/rtsol.c
releng/12.1/usr.sbin/rtsold/rtsol.c
releng/12.2/usr.sbin/rtsold/rtsol.c
Modified: releng/11.4/usr.sbin/rtsold/rtsol.c
==============================================================================
--- releng/11.4/usr.sbin/rtsold/rtsol.c Tue Dec 1 19:38:52 2020 (r368255)
+++ releng/11.4/usr.sbin/rtsold/rtsol.c Tue Dec 1 19:39:44 2020 (r368256)
@@ -390,8 +390,8 @@ rtsol_input(int s)
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);
@@ -403,6 +403,15 @@ rtsol_input(int s)
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;
@@ -932,15 +941,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 + 1 + (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';
Modified: releng/12.1/usr.sbin/rtsold/rtsol.c
==============================================================================
--- releng/12.1/usr.sbin/rtsold/rtsol.c Tue Dec 1 19:38:52 2020 (r368255)
+++ releng/12.1/usr.sbin/rtsold/rtsol.c Tue Dec 1 19:39:44 2020 (r368256)
@@ -390,8 +390,8 @@ rtsol_input(int s)
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);
@@ -403,6 +403,15 @@ rtsol_input(int s)
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;
@@ -924,15 +933,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 + 1 + (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';
Modified: releng/12.2/usr.sbin/rtsold/rtsol.c
==============================================================================
--- releng/12.2/usr.sbin/rtsold/rtsol.c Tue Dec 1 19:38:52 2020 (r368255)
+++ releng/12.2/usr.sbin/rtsold/rtsol.c Tue Dec 1 19:39:44 2020 (r368256)
@@ -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 + 1 + (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';
More information about the svn-src-all
mailing list