rtsold: Fix multiple buffer overflows
Approved by: so Security: CVE-2020-25577 MFC after: now
This commit is contained in:
parent
79861445bc
commit
5381f89770
@ -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';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user