diff options
author | Gao Feng <davidfgao@tencent.com> | 2020-04-26 09:57:18 +0800 |
---|---|---|
committer | Ole Trøan <otroan@employees.org> | 2020-04-27 13:35:17 +0000 |
commit | 9165e0365cc21575fd3e4a98be59317a839553f4 (patch) | |
tree | 8d6a3903e2fd0f275bf73734b262ab4bc9a2cdaf | |
parent | ffbcf6178891bd68a97543ac91d28f37256d5e13 (diff) |
ip: reassembly: fix one possible use-after-free
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
-rw-r--r-- | src/vnet/ip/reass/ip4_full_reass.c | 10 | ||||
-rw-r--r-- | src/vnet/ip/reass/ip6_full_reass.c | 11 |
2 files changed, 11 insertions, 10 deletions
diff --git a/src/vnet/ip/reass/ip4_full_reass.c b/src/vnet/ip/reass/ip4_full_reass.c index 0828d3b0e47..4d578c5ce44 100644 --- a/src/vnet/ip/reass/ip4_full_reass.c +++ b/src/vnet/ip/reass/ip4_full_reass.c @@ -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) { diff --git a/src/vnet/ip/reass/ip6_full_reass.c b/src/vnet/ip/reass/ip6_full_reass.c index 15ee3e3775d..f1a3606d41a 100644 --- a/src/vnet/ip/reass/ip6_full_reass.c +++ b/src/vnet/ip/reass/ip6_full_reass.c @@ -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); |