aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/igmp/igmp_input.c
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2018-07-11 09:21:06 -0700
committerNeale Ranns <nranns@cisco.com>2018-07-12 10:26:10 +0000
commit582856273c96113a460896a5ff9aa9a29dc73336 (patch)
treedea27e72aad1b1dbb5820e5571d0c87097831f47 /src/plugins/igmp/igmp_input.c
parentdaa1276fbfdb11e9c705b5ea05e83570b8163ad8 (diff)
IGMP: validate the packets length in the DP
thanks to coverity... validate that the length of the packet on wire matches the size of the header based on the number of groups and sources. drop those that don't match. Change-Id: Iab3f3a835f6a43d9c73c5d502ea5ceccdd6985b0 Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/plugins/igmp/igmp_input.c')
-rw-r--r--src/plugins/igmp/igmp_input.c68
1 files changed, 43 insertions, 25 deletions
diff --git a/src/plugins/igmp/igmp_input.c b/src/plugins/igmp/igmp_input.c
index d4563bf366d..5f54a0ba223 100644
--- a/src/plugins/igmp/igmp_input.c
+++ b/src/plugins/igmp/igmp_input.c
@@ -259,8 +259,8 @@ igmp_parse_query (vlib_main_t * vm, vlib_node_runtime_t * node,
{
igmp_membership_query_v3_t *igmp;
igmp_query_args_t *args;
+ u32 bi, next, len;
vlib_buffer_t *b;
- u32 bi, next;
next = IGMP_PARSE_QUERY_NEXT_DROP;
bi = from[0];
@@ -283,20 +283,29 @@ igmp_parse_query (vlib_main_t * vm, vlib_node_runtime_t * node,
clib_memcpy (tr->packet_data, vlib_buffer_get_current (b),
sizeof (tr->packet_data));
}
+ len = igmp_membership_query_v3_length (igmp);
/*
- * copy the contents of the query, and the interface, over
- * to the main thread for processing
+ * validate that the length on the packet on the wire
+ * corresponds to the length on the calculated v3 query
+ */
+ if (vlib_buffer_length_in_chain (vm, b) == len)
+ {
+ /*
+ * copy the contents of the query, and the interface, over
+ * to the main thread for processing
+ */
+ vlib_buffer_advance (b, -sizeof (u32));
+ args = vlib_buffer_get_current (b);
+ args->sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
+
+ vl_api_rpc_call_main_thread (igmp_handle_query,
+ (u8 *) args, sizeof (*args) + len);
+ }
+ /*
+ * else a packet that is reporting more or less sources
+ * than it really has, bin it
*/
- vlib_buffer_advance (b, -sizeof (u32));
- args = vlib_buffer_get_current (b);
- args->sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
-
- vl_api_rpc_call_main_thread (igmp_handle_query,
- (u8 *) args,
- sizeof (*args) +
- igmp_membership_query_v3_length
- (igmp));
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
n_left_to_next, bi, next);
@@ -351,7 +360,7 @@ igmp_parse_report (vlib_main_t * vm, vlib_node_runtime_t * node,
{
igmp_membership_report_v3_t *igmp;
igmp_report_args_t *args;
- u32 bi, next;
+ u32 bi, next, len;
vlib_buffer_t *b;
next = IGMP_PARSE_REPORT_NEXT_DROP;
@@ -368,6 +377,7 @@ igmp_parse_report (vlib_main_t * vm, vlib_node_runtime_t * node,
error = IGMP_ERROR_NONE;
b->error = error_node->errors[error];
igmp = vlib_buffer_get_current (b);
+ len = igmp_membership_report_v3_length (igmp);
ASSERT (igmp->header.type == IGMP_TYPE_membership_report_v3);
@@ -382,19 +392,27 @@ igmp_parse_report (vlib_main_t * vm, vlib_node_runtime_t * node,
}
/*
- * copy the contents of the query, and the interface, over
- * to the main thread for processing
+ * validate that the length on the packet on the wire
+ * corresponds to the length on the calculated v3 query
+ */
+ if (vlib_buffer_length_in_chain (vm, b) == len)
+ {
+ /*
+ * copy the contents of the query, and the interface, over
+ * to the main thread for processing
+ */
+ vlib_buffer_advance (b, -sizeof (u32));
+ args = vlib_buffer_get_current (b);
+ args->sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
+
+ vl_api_rpc_call_main_thread (igmp_handle_report,
+ (u8 *) args, sizeof (*args) + len);
+ }
+ /*
+ * else
+ * this is a packet with more groups/sources than the
+ * header reports. bin it
*/
- vlib_buffer_advance (b, -sizeof (u32));
- args = vlib_buffer_get_current (b);
- args->sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
-
- vl_api_rpc_call_main_thread (igmp_handle_report,
- (u8 *) args,
- sizeof (*args) +
- igmp_membership_report_v3_length
- (igmp));
-
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
n_left_to_next, bi, next);
}