ip: reassembly: fix use-after-free 53/22953/2
authorBenoît Ganne <bganne@cisco.com>
Wed, 23 Oct 2019 11:53:49 +0000 (13:53 +0200)
committerOle Trøan <otroan@employees.org>
Mon, 28 Oct 2019 09:13:50 +0000 (09:13 +0000)
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>
src/vnet/ip/reass/ip4_full_reass.c
src/vnet/ip/reass/ip6_full_reass.c

index 303f233..f6c0546 100644 (file)
@@ -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,
index aaaf56a..4e9079d 100644 (file)
@@ -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,