Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1354,7 +1354,7 @@ static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size)
   supposed to kill the mall. */
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
	   netfilter framework.  Roll on, two-stage module
@@ -1515,7 +1515,7 @@ int __init ip_conntrack_init(void)
	write_unlock_bh(&ip_conntrack_lock);

	/* For use by ipt_REJECT */
	ip_ct_attach = ip_conntrack_attach;
	rcu_assign_pointer(ip_ct_attach, ip_conntrack_attach);

	/* Set up fake conntrack:
	    - to never be deleted, not in any hashes */
+6 −3
Original line number Diff line number Diff line
@@ -248,9 +248,12 @@ void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb)
{
	void (*attach)(struct sk_buff *, struct sk_buff *);

	if (skb->nfct && (attach = ip_ct_attach) != NULL) {
		mb(); /* Just to be sure: must be read before executing this */
	if (skb->nfct) {
		rcu_read_lock();
		attach = rcu_dereference(ip_ct_attach);
		if (attach)
			attach(new, skb);
		rcu_read_unlock();
	}
}
EXPORT_SYMBOL(nf_ct_attach);
+2 −2
Original line number Diff line number Diff line
@@ -1105,7 +1105,7 @@ void nf_conntrack_cleanup(void)
{
	int i;

	ip_ct_attach = NULL;
	rcu_assign_pointer(ip_ct_attach, NULL);

	/* This makes sure all current packets have passed through
	   netfilter framework.  Roll on, two-stage module
@@ -1273,7 +1273,7 @@ int __init nf_conntrack_init(void)
        write_unlock_bh(&nf_conntrack_lock);

	/* For use by REJECT target */
	ip_ct_attach = __nf_conntrack_attach;
	rcu_assign_pointer(ip_ct_attach, __nf_conntrack_attach);

	/* Set up fake conntrack:
	    - to never be deleted, not in any hashes */