Commit c3a47ab3 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[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: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ebaf0c60
...@@ -1354,7 +1354,7 @@ static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size) ...@@ -1354,7 +1354,7 @@ static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size)
supposed to kill the mall. */ supposed to kill the mall. */
void ip_conntrack_cleanup(void) void ip_conntrack_cleanup(void)
{ {
ip_ct_attach = NULL; rcu_assign_pointer(ip_ct_attach, NULL);
/* This makes sure all current packets have passed through /* This makes sure all current packets have passed through
netfilter framework. Roll on, two-stage module netfilter framework. Roll on, two-stage module
...@@ -1515,7 +1515,7 @@ int __init ip_conntrack_init(void) ...@@ -1515,7 +1515,7 @@ int __init ip_conntrack_init(void)
write_unlock_bh(&ip_conntrack_lock); write_unlock_bh(&ip_conntrack_lock);
/* For use by ipt_REJECT */ /* For use by ipt_REJECT */
ip_ct_attach = ip_conntrack_attach; rcu_assign_pointer(ip_ct_attach, ip_conntrack_attach);
/* Set up fake conntrack: /* Set up fake conntrack:
- to never be deleted, not in any hashes */ - to never be deleted, not in any hashes */
......
...@@ -248,9 +248,12 @@ void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) ...@@ -248,9 +248,12 @@ void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb)
{ {
void (*attach)(struct sk_buff *, struct sk_buff *); void (*attach)(struct sk_buff *, struct sk_buff *);
if (skb->nfct && (attach = ip_ct_attach) != NULL) { if (skb->nfct) {
mb(); /* Just to be sure: must be read before executing this */ rcu_read_lock();
attach(new, skb); attach = rcu_dereference(ip_ct_attach);
if (attach)
attach(new, skb);
rcu_read_unlock();
} }
} }
EXPORT_SYMBOL(nf_ct_attach); EXPORT_SYMBOL(nf_ct_attach);
......
...@@ -1105,7 +1105,7 @@ void nf_conntrack_cleanup(void) ...@@ -1105,7 +1105,7 @@ void nf_conntrack_cleanup(void)
{ {
int i; int i;
ip_ct_attach = NULL; rcu_assign_pointer(ip_ct_attach, NULL);
/* This makes sure all current packets have passed through /* This makes sure all current packets have passed through
netfilter framework. Roll on, two-stage module netfilter framework. Roll on, two-stage module
...@@ -1273,7 +1273,7 @@ int __init nf_conntrack_init(void) ...@@ -1273,7 +1273,7 @@ int __init nf_conntrack_init(void)
write_unlock_bh(&nf_conntrack_lock); write_unlock_bh(&nf_conntrack_lock);
/* For use by REJECT target */ /* For use by REJECT target */
ip_ct_attach = __nf_conntrack_attach; rcu_assign_pointer(ip_ct_attach, __nf_conntrack_attach);
/* Set up fake conntrack: /* Set up fake conntrack:
- to never be deleted, not in any hashes */ - to never be deleted, not in any hashes */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment