]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/netfilter/nf_conntrack_extend.c
netfilter: nf_nat: fix RCU races
[linux-2.6-omap-h63xx.git] / net / netfilter / nf_conntrack_extend.c
index bcc19fa4ed1e07ab4277f7c02c933235cd0dc261..8a3f8b34e4661ef38a8acb81b7c5fb015cf108c6 100644 (file)
@@ -59,12 +59,19 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp)
        if (!*ext)
                return NULL;
 
+       INIT_RCU_HEAD(&(*ext)->rcu);
        (*ext)->offset[id] = off;
        (*ext)->len = len;
 
        return (void *)(*ext) + off;
 }
 
+static void __nf_ct_ext_free_rcu(struct rcu_head *head)
+{
+       struct nf_ct_ext *ext = container_of(head, struct nf_ct_ext, rcu);
+       kfree(ext);
+}
+
 void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
 {
        struct nf_ct_ext *new;
@@ -106,7 +113,7 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
                                        (void *)ct->ext + ct->ext->offset[i]);
                        rcu_read_unlock();
                }
-               kfree(ct->ext);
+               call_rcu(&ct->ext->rcu, __nf_ct_ext_free_rcu);
                ct->ext = new;
        }