From 6e850d43799e0ed00a87313b826211fe57d03a03 Mon Sep 17 00:00:00 2001 From: Vadim Kochan Date: Tue, 19 Dec 2017 00:38:18 +0200 Subject: 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 Signed-off-by: Tobias Klauser --- flowtop.c | 30 ++++++++++++++++-------------- 1 file 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; } -- cgit v1.2.3-54-g00ecf