summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Kochan <vadim4j@gmail.com>2017-12-19 00:38:18 +0200
committerTobias Klauser <tklauser@distanz.ch>2017-12-19 10:06:43 +0100
commit6e850d43799e0ed00a87313b826211fe57d03a03 (patch)
tree5ecd82a3e29f65bb04a459b170e4ee6f7cfe2fe1
parent642b2d816562ee0588aefa0947a4ee23600adbc5 (diff)
flowtop: Fix use-after-free on filter reload
There is missing logic which removes flow entry from related proc's entry while destroying global flows list on filter reloading, hence add common __flow_list_del_entry which handles this logic for both cases - when ct destroyed or filter changed. This is a 2nd fix for issue #183. Signed-off-by: Vadim Kochan <vadim4j@gmail.com> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
-rw-r--r--flowtop.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/flowtop.c b/flowtop.c
index b4c86a9..256bd05 100644
--- a/flowtop.c
+++ b/flowtop.c
@@ -470,20 +470,24 @@ static struct flow_entry *flow_list_find_id(struct flow_list *fl, uint32_t id)
return NULL;
}
+static void __flow_list_del_entry(struct flow_list *fl, struct flow_entry *n)
+{
+ if (n->proc) {
+ cds_list_del_rcu(&n->proc_head);
+ n->proc->flows_count--;
+ }
+
+ cds_list_del_rcu(&n->entry);
+ call_rcu(&n->rcu, flow_entry_xfree_rcu);
+}
+
static int flow_list_del_entry(struct flow_list *fl, const struct nf_conntrack *ct)
{
struct flow_entry *n;
n = flow_list_find_id(fl, nfct_get_attr_u32(ct, ATTR_ID));
- if (n) {
- if (n->proc) {
- cds_list_del_rcu(&n->proc_head);
- n->proc->flows_count--;
- }
-
- cds_list_del_rcu(&n->entry);
- call_rcu(&n->rcu, flow_entry_xfree_rcu);
- }
+ if (n)
+ __flow_list_del_entry(fl, n);
return NFCT_CB_CONTINUE;
}
@@ -492,10 +496,8 @@ static void flow_list_destroy(struct flow_list *fl)
{
struct flow_entry *n, *tmp;
- cds_list_for_each_entry_safe(n, tmp, &fl->head, entry) {
- cds_list_del_rcu(&n->entry);
- call_rcu(&n->rcu, flow_entry_xfree_rcu);
- }
+ cds_list_for_each_entry_safe(n, tmp, &fl->head, entry)
+ __flow_list_del_entry(fl, n);
}
static void proc_list_init(struct proc_list *proc_list)
@@ -562,7 +564,7 @@ static void flow_entry_find_process(struct flow_entry *n)
p->stat.bytes_dst += n->stat.bytes_dst;
p->flows_count++;
- cds_list_add(&n->proc_head, &p->flows);
+ cds_list_add_rcu(&n->proc_head, &p->flows);
n->proc = p;
}