]> git.hungrycats.org Git - linux/commitdiff
Revert "netfilter: conntrack: fix race in __nf_conntrack_confirm against get_next_corpse"
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 7 Dec 2014 19:46:46 +0000 (11:46 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 7 Dec 2014 19:46:46 +0000 (11:46 -0800)
This reverts commit 88fd8709858b9cd94e2d28b4b3cac4b752f0683a which was
commit 5195c14c8b27cc0b18220ddbf0e5ad3328a04187 upstream, which was
reverted in commit 43612d7c04f1a4f5e60104143918fcdf018b66ee.

Reported-by: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: Daniel Borkmann <dborkman@redhat.com>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/netfilter/nf_conntrack_core.c

index ec94ba94079f0c5e8905744f6b7ec70e9f53c133..de88c4ab5146a168bc0866f3fdc07098b5ebe543 100644 (file)
@@ -611,16 +611,12 @@ __nf_conntrack_confirm(struct sk_buff *skb)
         */
        NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
        pr_debug("Confirming conntrack %p\n", ct);
-
-       /* We have to check the DYING flag after unlink to prevent
-        * a race against nf_ct_get_next_corpse() possibly called from
-        * user context, else we insert an already 'dead' hash, blocking
-        * further use of that particular connection -JM.
-        */
-       nf_ct_del_from_dying_or_unconfirmed_list(ct);
+       /* We have to check the DYING flag inside the lock to prevent
+          a race against nf_ct_get_next_corpse() possibly called from
+          user context, else we insert an already 'dead' hash, blocking
+          further use of that particular connection -JM */
 
        if (unlikely(nf_ct_is_dying(ct))) {
-               nf_ct_add_to_dying_list(ct);
                nf_conntrack_double_unlock(hash, reply_hash);
                local_bh_enable();
                return NF_ACCEPT;
@@ -640,6 +636,8 @@ __nf_conntrack_confirm(struct sk_buff *skb)
                    zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)))
                        goto out;
 
+       nf_ct_del_from_dying_or_unconfirmed_list(ct);
+
        /* Timer relative to confirmation time, not original
           setting time, otherwise we'd get timer wrap in
           weird delay cases. */