[ovs-dev] [PATCH] use double postponing to free subtables.
fuzhantao
fuzhantao at huawei.com
Mon Apr 15 09:34:53 UTC 2019
From: Zhantao Fu <fuzhantao at huawei.com>
Now the subtable in classifier/dpcls is postponed by destroy_subtable before move itself out of cls->subtables(pvector).It will raise use-after-free problem.
use double postponing to free subtable
Signed-off-by: Zhantao Fu <fuzhantao at huawei.com>
---
lib/classifier.c | 29 +++++++++++++++++++----------
lib/dpif-netdev.c | 10 ++++++++--
2 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/lib/classifier.c b/lib/classifier.c
index edb40c8..10370ce 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -1468,6 +1468,24 @@ miniflow_get_map_in_range(const struct miniflow *miniflow, uint8_t start,
return map;
}
+static void
+subtable_destroy_cb(struct cls_subtable *subtable)
+{
+ int i;
+
+ ovs_assert(ovsrcu_get_protected(struct trie_node *, &subtable->ports_trie)
+ == NULL);
+ ovs_assert(cmap_is_empty(&subtable->rules));
+ ovs_assert(rculist_is_empty(&subtable->rules_list));
+
+ for (i = 0; i < subtable->n_indices; i++) {
+ ccmap_destroy(&subtable->indices[i]);
+ }
+ cmap_destroy(&subtable->rules);
+
+ ovsrcu_postpone(free, subtable);
+}
+
/* The new subtable will be visible to the readers only after this. */
static struct cls_subtable *
insert_subtable(struct classifier *cls, const struct minimask *mask)
@@ -1540,16 +1558,7 @@ destroy_subtable(struct classifier *cls, struct cls_subtable *subtable)
cmap_remove(&cls->subtables_map, &subtable->cmap_node,
minimask_hash(&subtable->mask, 0));
- ovs_assert(ovsrcu_get_protected(struct trie_node *, &subtable->ports_trie)
- == NULL);
- ovs_assert(cmap_is_empty(&subtable->rules));
- ovs_assert(rculist_is_empty(&subtable->rules_list));
-
- for (i = 0; i < subtable->n_indices; i++) {
- ccmap_destroy(&subtable->indices[i]);
- }
- cmap_destroy(&subtable->rules);
- ovsrcu_postpone(free, subtable);
+ ovsrcu_postpone(subtable_destroy_cb, subtable);
}
static unsigned int be_get_bit_at(const ovs_be32 value[], unsigned int ofs);
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 4d6d0c3..8657a61 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -7592,6 +7592,13 @@ struct dpcls_subtable {
/* 'mask' must be the last field, additional space is allocated here. */
};
+static void
+dpcls_subtable_destroy_cb(struct dpcls_subtable *subtable)
+{
+ cmap_destroy(&subtable->rules);
+ ovsrcu_postpone(free, subtable);
+}
+
/* Initializes 'cls' as a classifier that initially contains no classification
* rules. */
static void
@@ -7608,8 +7615,7 @@ dpcls_destroy_subtable(struct dpcls *cls, struct dpcls_subtable *subtable)
pvector_remove(&cls->subtables, subtable);
cmap_remove(&cls->subtables_map, &subtable->cmap_node,
subtable->mask.hash);
- cmap_destroy(&subtable->rules);
- ovsrcu_postpone(free, subtable);
+ ovsrcu_postpone(dpcls_subtable_destroy_cb, subtable);
}
/* Destroys 'cls'. Rules within 'cls', if any, are not freed; this is the
--
1.9.5.msysgit.1
More information about the dev
mailing list