Commit c3a47ab3e5ad62601449e4e5401352271b777e28
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 */ |