--- a/print-olsr.c +++ b/print-olsr.c @@ -178,7 +178,7 @@ struct olsr_lq_neighbor6 { /* * print a neighbor list with LQ extensions. */ -static void +static int olsr_print_lq_neighbor4(netdissect_options *ndo, const u_char *msg_data, u_int hello_len) { @@ -187,6 +187,8 @@ olsr_print_lq_neighbor4(netdissect_options *ndo, while (hello_len >= sizeof(struct olsr_lq_neighbor4)) { lq_neighbor = (struct olsr_lq_neighbor4 *)msg_data; + if (!ND_TTEST(*lq_neighbor)) + return (-1); ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2lf%%" ", neighbor-link-quality %.2lf%%", @@ -197,10 +199,11 @@ olsr_print_lq_neighbor4(netdissect_options *ndo, msg_data += sizeof(struct olsr_lq_neighbor4); hello_len -= sizeof(struct olsr_lq_neighbor4); } + return (0); } #if INET6 -static void +static int olsr_print_lq_neighbor6(netdissect_options *ndo, const u_char *msg_data, u_int hello_len) { @@ -209,6 +212,8 @@ olsr_print_lq_neighbor6(netdissect_options *ndo, while (hello_len >= sizeof(struct olsr_lq_neighbor6)) { lq_neighbor = (struct olsr_lq_neighbor6 *)msg_data; + if (!ND_TTEST(*lq_neighbor)) + return (-1); ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2lf%%" ", neighbor-link-quality %.2lf%%", @@ -219,13 +224,14 @@ olsr_print_lq_neighbor6(netdissect_options *ndo, msg_data += sizeof(struct olsr_lq_neighbor6); hello_len -= sizeof(struct olsr_lq_neighbor6); } + return (0); } #endif /* INET6 */ /* * print a neighbor list. */ -static void +static int olsr_print_neighbor(netdissect_options *ndo, const u_char *msg_data, u_int hello_len) { @@ -236,6 +242,8 @@ olsr_print_neighbor(netdissect_options *ndo, while (hello_len >= sizeof(struct in_addr)) { + if (!ND_TTEST2(*msg_data, sizeof(struct in_addr))) + return (-1); /* print 4 neighbors per line */ ND_PRINT((ndo, "%s%s", ipaddr_string(ndo, msg_data), @@ -244,6 +252,7 @@ olsr_print_neighbor(netdissect_options *ndo, msg_data += sizeof(struct in_addr); hello_len -= sizeof(struct in_addr); } + return (0); } @@ -326,6 +335,9 @@ olsr_print(netdissect_options *ndo, ME_TO_DOUBLE(msgptr.v6->vtime), EXTRACT_16BITS(msgptr.v6->msg_seq), msg_len, (msg_len_valid == 0) ? " (invalid)" : "")); + if (!msg_len_valid) { + return; + } msg_tlen = msg_len - sizeof(struct olsr_msg6); msg_data = tptr + sizeof(struct olsr_msg6); @@ -354,6 +366,9 @@ olsr_print(netdissect_options *ndo, ME_TO_DOUBLE(msgptr.v4->vtime), EXTRACT_16BITS(msgptr.v4->msg_seq), msg_len, (msg_len_valid == 0) ? " (invalid)" : "")); + if (!msg_len_valid) { + return; + } msg_tlen = msg_len - sizeof(struct olsr_msg4); msg_data = tptr + sizeof(struct olsr_msg4); @@ -362,6 +377,8 @@ olsr_print(netdissect_options *ndo, switch (msg_type) { case OLSR_HELLO_MSG: case OLSR_HELLO_LQ_MSG: + if (msg_tlen < sizeof(struct olsr_hello)) + goto trunc; ND_TCHECK2(*msg_data, sizeof(struct olsr_hello)); ptr.hello = (struct olsr_hello *)msg_data; @@ -401,15 +418,21 @@ olsr_print(netdissect_options *ndo, msg_tlen -= sizeof(struct olsr_hello_link); hello_len -= sizeof(struct olsr_hello_link); + ND_TCHECK2(*msg_data, hello_len); if (msg_type == OLSR_HELLO_MSG) { - olsr_print_neighbor(ndo, msg_data, hello_len); + if (olsr_print_neighbor(ndo, msg_data, hello_len) == -1) + goto trunc; } else { #if INET6 - if (is_ipv6) - olsr_print_lq_neighbor6(ndo, msg_data, hello_len); - else + if (is_ipv6) { + if (olsr_print_lq_neighbor6(ndo, msg_data, hello_len) == -1) + goto trunc; + } else #endif - olsr_print_lq_neighbor4(ndo, msg_data, hello_len); + { + if (olsr_print_lq_neighbor4(ndo, msg_data, hello_len) == -1) + goto trunc; + } } msg_data += hello_len; @@ -419,6 +442,8 @@ olsr_print(netdissect_options *ndo, case OLSR_TC_MSG: case OLSR_TC_LQ_MSG: + if (msg_tlen < sizeof(struct olsr_tc)) + goto trunc; ND_TCHECK2(*msg_data, sizeof(struct olsr_tc)); ptr.tc = (struct olsr_tc *)msg_data; @@ -428,14 +453,19 @@ olsr_print(netdissect_options *ndo, msg_tlen -= sizeof(struct olsr_tc); if (msg_type == OLSR_TC_MSG) { - olsr_print_neighbor(ndo, msg_data, msg_tlen); + if (olsr_print_neighbor(ndo, msg_data, msg_tlen) == -1) + goto trunc; } else { #if INET6 - if (is_ipv6) - olsr_print_lq_neighbor6(ndo, msg_data, msg_tlen); - else + if (is_ipv6) { + if (olsr_print_lq_neighbor6(ndo, msg_data, msg_tlen) == -1) + goto trunc; + } else #endif - olsr_print_lq_neighbor4(ndo, msg_data, msg_tlen); + { + if (olsr_print_lq_neighbor4(ndo, msg_data, msg_tlen) == -1) + goto trunc; + } } break;