Commit c3a47ab3e5ad62601449e4e5401352271b777e28

Authored by Patrick McHardy
Committed by David S. Miller
1 parent ebaf0c6032

[NETFILTER]: Properly use RCU in nf_ct_attach

Use rcu_assign_pointer/rcu_dereference for ip_ct_attach pointer instead
of self-made RCU and use rcu_read_lock to make sure the conntrack module
doesn't disappear below us while calling it, since this function can be
called from outside the netfilter hooks.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 3 changed files with 10 additions and 7 deletions Side-by-side Diff

net/ipv4/netfilter/ip_conntrack_core.c
... ... @@ -1354,7 +1354,7 @@
1354 1354 supposed to kill the mall. */
1355 1355 void ip_conntrack_cleanup(void)
1356 1356 {
1357   - ip_ct_attach = NULL;
  1357 + rcu_assign_pointer(ip_ct_attach, NULL);
1358 1358  
1359 1359 /* This makes sure all current packets have passed through
1360 1360 netfilter framework. Roll on, two-stage module
... ... @@ -1515,7 +1515,7 @@
1515 1515 write_unlock_bh(&ip_conntrack_lock);
1516 1516  
1517 1517 /* For use by ipt_REJECT */
1518   - ip_ct_attach = ip_conntrack_attach;
  1518 + rcu_assign_pointer(ip_ct_attach, ip_conntrack_attach);
1519 1519  
1520 1520 /* Set up fake conntrack:
1521 1521 - to never be deleted, not in any hashes */
net/netfilter/core.c
... ... @@ -248,9 +248,12 @@
248 248 {
249 249 void (*attach)(struct sk_buff *, struct sk_buff *);
250 250  
251   - if (skb->nfct && (attach = ip_ct_attach) != NULL) {
252   - mb(); /* Just to be sure: must be read before executing this */
253   - attach(new, skb);
  251 + if (skb->nfct) {
  252 + rcu_read_lock();
  253 + attach = rcu_dereference(ip_ct_attach);
  254 + if (attach)
  255 + attach(new, skb);
  256 + rcu_read_unlock();
254 257 }
255 258 }
256 259 EXPORT_SYMBOL(nf_ct_attach);
net/netfilter/nf_conntrack_core.c
... ... @@ -1105,7 +1105,7 @@
1105 1105 {
1106 1106 int i;
1107 1107  
1108   - ip_ct_attach = NULL;
  1108 + rcu_assign_pointer(ip_ct_attach, NULL);
1109 1109  
1110 1110 /* This makes sure all current packets have passed through
1111 1111 netfilter framework. Roll on, two-stage module
... ... @@ -1273,7 +1273,7 @@
1273 1273 write_unlock_bh(&nf_conntrack_lock);
1274 1274  
1275 1275 /* For use by REJECT target */
1276   - ip_ct_attach = __nf_conntrack_attach;
  1276 + rcu_assign_pointer(ip_ct_attach, __nf_conntrack_attach);
1277 1277  
1278 1278 /* Set up fake conntrack:
1279 1279 - to never be deleted, not in any hashes */