Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nf_ct_expect: use proper RCU list traversal/update APIs

We should use proper RCU list APIs to manipulate help->expectations,
as we can dump the conntrack's expectations via nfnetlink, i.e. in
ctnetlink_exp_ct_dump_table(), where only rcu_read_lock is acquired.

So for list traversal, use hlist_for_each_entry_rcu; for list add/del,
use hlist_add_head_rcu and hlist_del_rcu.

Signed-off-by: Liping Zhang <zlpnobody@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Liping Zhang and committed by
Pablo Neira Ayuso
7cddd967 207df815

+5 -5
+2 -2
net/netfilter/nf_conntrack_expect.c
··· 57 57 hlist_del_rcu(&exp->hnode); 58 58 net->ct.expect_count--; 59 59 60 - hlist_del(&exp->lnode); 60 + hlist_del_rcu(&exp->lnode); 61 61 master_help->expecting[exp->class]--; 62 62 63 63 nf_ct_expect_event_report(IPEXP_DESTROY, exp, portid, report); ··· 363 363 /* two references : one for hash insert, one for the timer */ 364 364 atomic_add(2, &exp->use); 365 365 366 - hlist_add_head(&exp->lnode, &master_help->expectations); 366 + hlist_add_head_rcu(&exp->lnode, &master_help->expectations); 367 367 master_help->expecting[exp->class]++; 368 368 369 369 hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]);
+3 -3
net/netfilter/nf_conntrack_netlink.c
··· 2680 2680 last = (struct nf_conntrack_expect *)cb->args[1]; 2681 2681 for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) { 2682 2682 restart: 2683 - hlist_for_each_entry(exp, &nf_ct_expect_hash[cb->args[0]], 2684 - hnode) { 2683 + hlist_for_each_entry_rcu(exp, &nf_ct_expect_hash[cb->args[0]], 2684 + hnode) { 2685 2685 if (l3proto && exp->tuple.src.l3num != l3proto) 2686 2686 continue; 2687 2687 ··· 2732 2732 rcu_read_lock(); 2733 2733 last = (struct nf_conntrack_expect *)cb->args[1]; 2734 2734 restart: 2735 - hlist_for_each_entry(exp, &help->expectations, lnode) { 2735 + hlist_for_each_entry_rcu(exp, &help->expectations, lnode) { 2736 2736 if (l3proto && exp->tuple.src.l3num != l3proto) 2737 2737 continue; 2738 2738 if (cb->args[1]) {