ip4/6-reassembly fixes 99/19799/2
authorVijayabhaskar Katamreddy <vkatamre@cisco.com>
Thu, 23 May 2019 20:02:28 +0000 (13:02 -0700)
committerOle Trøan <otroan@employees.org>
Fri, 24 May 2019 09:02:40 +0000 (09:02 +0000)
When multichained fragments comes into reassembly, followed by buffer Linearization or dropping the buffer for other reasons inbetween disturbs the multichained mbuf linking.
When packet is transmitted, followed by freeing of the buffers, woudl result in double free and packet corruptions

Change-Id: Ib5711d54e61fdd6a67deb30dad0b2a14afb9c2da
Signed-off-by: Vijayabhaskar Katamreddy <vkatamre@cisco.com>
src/vnet/ip/ip4_reassembly.c
src/vnet/ip/ip6_reassembly.c

index f273510..763229c 100644 (file)
@@ -489,6 +489,7 @@ ip4_reass_finalize (vlib_main_t * vm, vlib_node_runtime_t * node,
                    }
                  tmp->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
                  tmp_bi = tmp->next_buffer;
+                 tmp->next_buffer = 0;
                  tmp = vlib_get_buffer (vm, tmp_bi);
                  vlib_buffer_free_one (vm, to_be_freed_bi);
                  continue;
@@ -540,12 +541,15 @@ ip4_reass_finalize (vlib_main_t * vm, vlib_node_runtime_t * node,
                }
              if (tmp->flags & VLIB_BUFFER_NEXT_PRESENT)
                {
+                 tmp->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
                  tmp_bi = tmp->next_buffer;
-                 tmp = vlib_get_buffer (vm, tmp->next_buffer);
+                 tmp->next_buffer = 0;
+                 tmp = vlib_get_buffer (vm, tmp_bi);
                  vlib_buffer_free_one (vm, to_be_freed_bi);
                }
              else
                {
+                 tmp->next_buffer = 0;
                  vlib_buffer_free_one (vm, to_be_freed_bi);
                  break;
                }
@@ -562,6 +566,7 @@ ip4_reass_finalize (vlib_main_t * vm, vlib_node_runtime_t * node,
       return IP4_REASS_RC_INTERNAL_ERROR;
     }
   last_b->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
+
   if (total_length < first_b->current_length)
     {
       return IP4_REASS_RC_INTERNAL_ERROR;
@@ -577,7 +582,8 @@ ip4_reass_finalize (vlib_main_t * vm, vlib_node_runtime_t * node,
     {
       return IP4_REASS_RC_NO_BUF;
     }
-
+  // reset to reconstruct the mbuf linking
+  first_b->flags &= ~VLIB_BUFFER_EXT_HDR_VALID;
   if (PREDICT_FALSE (first_b->flags & VLIB_BUFFER_IS_TRACED))
     {
       ip4_reass_add_trace (vm, node, rm, reass, reass->first_bi, FINALIZE, 0);
@@ -700,11 +706,13 @@ ip4_reass_remove_range_from_chain (vlib_main_t * vm,
        {
          discard_b->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
          discard_bi = discard_b->next_buffer;
+         discard_b->next_buffer = 0;
          discard_b = vlib_get_buffer (vm, discard_bi);
          vlib_buffer_free_one (vm, to_be_freed_bi);
        }
       else
        {
+         discard_b->next_buffer = 0;
          vlib_buffer_free_one (vm, to_be_freed_bi);
          break;
        }
index 45cd2b2..cb1cd9a 100644 (file)
@@ -633,6 +633,7 @@ ip6_reass_finalize (vlib_main_t * vm, vlib_node_runtime_t * node,
       rv = IP6_REASS_RC_NO_BUF;
       goto free_buffers_and_return;
     }
+  first_b->flags &= ~VLIB_BUFFER_EXT_HDR_VALID;
   if (PREDICT_FALSE (first_b->flags & VLIB_BUFFER_IS_TRACED))
     {
       ip6_reass_add_trace (vm, node, rm, reass, reass->first_bi, FINALIZE, 0);