aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ip/reass
diff options
context:
space:
mode:
authorGao Feng <davidfgao@tencent.com>2020-04-26 09:57:18 +0800
committerOle Trøan <otroan@employees.org>2020-04-27 13:35:17 +0000
commit9165e0365cc21575fd3e4a98be59317a839553f4 (patch)
tree8d6a3903e2fd0f275bf73734b262ab4bc9a2cdaf /src/vnet/ip/reass
parentffbcf6178891bd68a97543ac91d28f37256d5e13 (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
Diffstat (limited to 'src/vnet/ip/reass')
-rw-r--r--src/vnet/ip/reass/ip4_full_reass.c10
-rw-r--r--src/vnet/ip/reass/ip6_full_reass.c11
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);