mirror of
https://github.com/the-tcpdump-group/tcpdump.git
synced 2024-11-23 10:04:05 +08:00
Do more bounds checking and length checking.
Don't run past the end of the captured data, and don't run past the end of the packet (i.e., don't make the length variable go negative). Also, stop dissecting if the message length isn't valid.
This commit is contained in:
parent
9255c9b05b
commit
4038f83ebf
56
print-olsr.c
56
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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user