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> (cherry picked from commit cf7803d2e864fb71f14943a544ac309d3d0510cb)
This commit is contained in:
Benoît Ganne
committed by
Andrew Yourtchenko
parent
442870c03a
commit
82ae1a485e
@ -1208,13 +1208,17 @@ ip4_full_reass_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
|||||||
|
|
||||||
|
|
||||||
packet_enqueue:
|
packet_enqueue:
|
||||||
b0->error = node->errors[error0];
|
|
||||||
|
|
||||||
if (bi0 != ~0)
|
if (bi0 != ~0)
|
||||||
{
|
{
|
||||||
to_next[0] = bi0;
|
to_next[0] = bi0;
|
||||||
to_next += 1;
|
to_next += 1;
|
||||||
n_left_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 (next0 == IP4_FULL_REASS_NEXT_HANDOFF)
|
||||||
{
|
{
|
||||||
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
|
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
|
||||||
@ -1233,7 +1237,6 @@ ip4_full_reass_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
|||||||
}
|
}
|
||||||
else if (is_feature && IP4_ERROR_NONE == error0)
|
else if (is_feature && IP4_ERROR_NONE == error0)
|
||||||
{
|
{
|
||||||
b0 = vlib_get_buffer (vm, bi0);
|
|
||||||
vnet_feature_next (&next0, b0);
|
vnet_feature_next (&next0, b0);
|
||||||
}
|
}
|
||||||
vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
|
vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
|
||||||
|
@ -1168,14 +1168,17 @@ ip6_full_reassembly_inline (vlib_main_t * vm,
|
|||||||
error0 = IP6_ERROR_REASS_LIMIT_REACHED;
|
error0 = IP6_ERROR_REASS_LIMIT_REACHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
b0->error = node->errors[error0];
|
|
||||||
|
|
||||||
if (~0 != bi0)
|
if (~0 != bi0)
|
||||||
{
|
{
|
||||||
skip_reass:
|
skip_reass:
|
||||||
to_next[0] = bi0;
|
to_next[0] = bi0;
|
||||||
to_next += 1;
|
to_next += 1;
|
||||||
n_left_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 (next0 == IP6_FULL_REASSEMBLY_NEXT_HANDOFF)
|
||||||
{
|
{
|
||||||
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
|
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
|
||||||
@ -1194,7 +1197,6 @@ ip6_full_reassembly_inline (vlib_main_t * vm,
|
|||||||
}
|
}
|
||||||
else if (is_feature && IP6_ERROR_NONE == error0)
|
else if (is_feature && IP6_ERROR_NONE == error0)
|
||||||
{
|
{
|
||||||
b0 = vlib_get_buffer (vm, bi0);
|
|
||||||
vnet_feature_next (&next0, b0);
|
vnet_feature_next (&next0, b0);
|
||||||
}
|
}
|
||||||
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
|
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
|
||||||
|
Reference in New Issue
Block a user