52 lines
1.5 KiB
Diff
52 lines
1.5 KiB
Diff
--- usr.sbin/rtsold/rtsol.c.orig
|
|
+++ usr.sbin/rtsold/rtsol.c
|
|
@@ -337,8 +337,8 @@
|
|
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 @@
|
|
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 @@
|
|
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';
|
|
|