summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGao Feng <davidfgao@tencent.com>2020-04-26 09:57:18 +0800
committerAndrew Yourtchenko <ayourtch@gmail.com>2020-08-13 17:20:47 +0000
commitbfbbb1855e976c0c1b336fe2b9bea81fac7567a3 (patch)
treec923d27296426f652f53d17585f9e9c670cfbf31
parentd549129538b65eee8549237ea2aaf7d59d89da2f (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 (cherry picked from commit 9165e0365cc21575fd3e4a98be59317a839553f4)
-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 a2d08a4909c..cebc6a0e965 100644
--- a/src/vnet/ip/reass/ip4_full_reass.c
+++ b/src/vnet/ip/reass/ip4_full_reass.c
@@ -459,15 +459,15 @@ again:
if (!clib_bihash_search_16_8
(&rm->hash, (clib_bihash_kv_16_8_t *) kv, (clib_bihash_kv_16_8_t *) 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 6848f59c65c..69ba452840e 100644
--- a/src/vnet/ip/reass/ip6_full_reass.c
+++ b/src/vnet/ip/reass/ip6_full_reass.c
@@ -471,16 +471,17 @@ again:
if (!clib_bihash_search_48_8
(&rm->hash, (clib_bihash_kv_48_8_t *) kv, (clib_bihash_kv_48_8_t *) 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);