aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenoît Ganne <bganne@cisco.com>2019-10-23 13:53:49 +0200
committerOle Trøan <otroan@employees.org>2019-10-28 09:13:50 +0000
commitcf7803d2e864fb71f14943a544ac309d3d0510cb (patch)
tree2c12f423d25fe37c2596a31b8e09742d95628e77
parent1b1ccadc900deffd7b8e306ae8dce79a3115778c (diff)
ip: reassembly: fix use-after-free
When processing the last buffer of a reassembled packet, the current buffer will be freed and must be reloaded using the updated index. Type: fix Change-Id: Ib39e29e60eb527b4cd4828a3aa37d82c8dddd709 Signed-off-by: Benoît Ganne <bganne@cisco.com>
-rw-r--r--src/vnet/ip/reass/ip4_full_reass.c7
-rw-r--r--src/vnet/ip/reass/ip6_full_reass.c8
2 files changed, 10 insertions, 5 deletions
diff --git a/src/vnet/ip/reass/ip4_full_reass.c b/src/vnet/ip/reass/ip4_full_reass.c
index 303f23337ee..f6c05466e19 100644
--- a/src/vnet/ip/reass/ip4_full_reass.c
+++ b/src/vnet/ip/reass/ip4_full_reass.c
@@ -1224,13 +1224,17 @@ ip4_full_reass_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
packet_enqueue:
- b0->error = node->errors[error0];
if (bi0 != ~0)
{
to_next[0] = bi0;
to_next += 1;
n_left_to_next -= 1;
+
+ /* bi0 might have been updated by reass_finalize, reload */
+ b0 = vlib_get_buffer (vm, bi0);
+ b0->error = node->errors[error0];
+
if (next0 == IP4_FULL_REASS_NEXT_HANDOFF)
{
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
@@ -1243,7 +1247,6 @@ ip4_full_reass_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else if (is_feature && IP4_ERROR_NONE == error0)
{
- b0 = vlib_get_buffer (vm, bi0);
vnet_feature_next (&next0, b0);
}
vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
diff --git a/src/vnet/ip/reass/ip6_full_reass.c b/src/vnet/ip/reass/ip6_full_reass.c
index aaaf56a5d59..4e9079d060d 100644
--- a/src/vnet/ip/reass/ip6_full_reass.c
+++ b/src/vnet/ip/reass/ip6_full_reass.c
@@ -1199,14 +1199,17 @@ ip6_full_reassembly_inline (vlib_main_t * vm,
error0 = IP6_ERROR_REASS_LIMIT_REACHED;
}
- b0->error = node->errors[error0];
-
if (~0 != bi0)
{
skip_reass:
to_next[0] = bi0;
to_next += 1;
n_left_to_next -= 1;
+
+ /* bi0 might have been updated by reass_finalize, reload */
+ b0 = vlib_get_buffer (vm, bi0);
+ b0->error = node->errors[error0];
+
if (next0 == IP6_FULL_REASSEMBLY_NEXT_HANDOFF)
{
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
@@ -1219,7 +1222,6 @@ ip6_full_reassembly_inline (vlib_main_t * vm,
}
else if (is_feature && IP6_ERROR_NONE == error0)
{
- b0 = vlib_get_buffer (vm, bi0);
vnet_feature_next (&next0, b0);
}
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,