ip: reassembly: fix one possible use-after-free 01/26701/5
authorGao Feng <davidfgao@tencent.com>
Sun, 26 Apr 2020 01:57:18 +0000 (09:57 +0800)
committerOle Trøan <otroan@employees.org>
Mon, 27 Apr 2020 13:35:17 +0000 (13:35 +0000)
When use the kv->v.memory_owner_thread_index as the index to get the
reass in pool, maybe this element is freed by the owner thread because
of timeout, too many fragments, and so on.

So we should check if do_handoff with kv->v.memory_owner_thread_index
before get the reass from pool.

Type: fix

Signed-off-by: Gao Feng <davidfgao@tencent.com>
Change-Id: Ie0f1dc368f86d0fd65292ca0c5e1908348015e09

src/vnet/ip/reass/ip4_full_reass.c
src/vnet/ip/reass/ip6_full_reass.c

index 0828d3b..4d578c5 100644 (file)
@@ -482,15 +482,15 @@ again:
   now = vlib_time_now (vm);
   if (!clib_bihash_search_16_8 (&rm->hash, &kv->kv, &kv->kv))
     {
+      if (vm->thread_index != kv->v.memory_owner_thread_index)
+       {
+         *do_handoff = 1;
+         return NULL;
+       }
       reass =
        pool_elt_at_index (rm->per_thread_data
                           [kv->v.memory_owner_thread_index].pool,
                           kv->v.reass_index);
-      if (vm->thread_index != reass->memory_owner_thread_index)
-       {
-         *do_handoff = 1;
-         return reass;
-       }
 
       if (now > reass->last_heard + rm->timeout)
        {
index 15ee3e3..f1a3606 100644 (file)
@@ -508,16 +508,17 @@ again:
 
   if (!clib_bihash_search_48_8 (&rm->hash, &kv->kv, &kv->kv))
     {
-      reass =
-       pool_elt_at_index (rm->per_thread_data
-                          [kv->v.memory_owner_thread_index].pool,
-                          kv->v.reass_index);
       if (vm->thread_index != kv->v.memory_owner_thread_index)
        {
          *do_handoff = 1;
-         return reass;
+         return NULL;
        }
 
+      reass =
+       pool_elt_at_index (rm->per_thread_data
+                          [kv->v.memory_owner_thread_index].pool,
+                          kv->v.reass_index);
+
       if (now > reass->last_heard + rm->timeout)
        {
          ip6_full_reass_on_timeout (vm, node, rm, reass, icmp_bi);