Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
authorDavid S. Miller <davem@davemloft.net>
Fri, 21 May 2010 06:12:18 +0000 (23:12 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 21 May 2010 06:12:18 +0000 (23:12 -0700)
include/linux/netfilter/x_tables.h
include/net/netfilter/nf_conntrack_core.h
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_sip.c

index c2ee5d8550cf13bc84ac69fde5733b3ddf631577..c00cc0c4d0b7c29614bbafdfabe73828a04a0fbd 100644 (file)
@@ -333,7 +333,7 @@ struct xt_target {
        /* Called when user tries to insert an entry of this type:
            hook_mask is a bitmask of hooks from which it can be
            called. */
-       /* Should return true or false, or an error code (-Exxxx). */
+       /* Should return 0 on success or an error code otherwise (-Exxxx). */
        int (*checkentry)(const struct xt_tgchk_param *);
 
        /* Called when entry of this type deleted. */
index dffde8e6920eb43c37184692fa6d49d054938366..3d7524fba1946d2993033f44b8330f210eaa4bb4 100644 (file)
@@ -61,7 +61,7 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb)
        int ret = NF_ACCEPT;
 
        if (ct && ct != &nf_conntrack_untracked) {
-               if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
+               if (!nf_ct_is_confirmed(ct))
                        ret = __nf_conntrack_confirm(skb);
                if (likely(ret == NF_ACCEPT))
                        nf_ct_deliver_cached_events(ct);
index b83c530c5e0a391c7f09e5ee8950884991377053..eeeb8bc73982275655e37342c214f1fa2669efb2 100644 (file)
@@ -424,6 +424,16 @@ __nf_conntrack_confirm(struct sk_buff *skb)
 
        spin_lock_bh(&nf_conntrack_lock);
 
+       /* 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))) {
+               spin_unlock_bh(&nf_conntrack_lock);
+               return NF_ACCEPT;
+       }
+
        /* See if there's one in the list already, including reverse:
           NAT could have grabbed it without realizing, since we're
           not in the hash.  If there is, we lost race. */
index b20f4275893c8a61b68304c17c44e379e2be9a65..53d892210a049363fa3ab04f6e17b04fa9969bbe 100644 (file)
@@ -1393,10 +1393,8 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
 
        nf_ct_refresh(ct, skb, sip_timeout * HZ);
 
-       if (skb_is_nonlinear(skb)) {
-               pr_debug("Copy of skbuff not supported yet.\n");
-               return NF_ACCEPT;
-       }
+       if (unlikely(skb_linearize(skb)))
+               return NF_DROP;
 
        dptr = skb->data + dataoff;
        datalen = skb->len - dataoff;
@@ -1455,10 +1453,8 @@ static int sip_help_udp(struct sk_buff *skb, unsigned int protoff,
 
        nf_ct_refresh(ct, skb, sip_timeout * HZ);
 
-       if (skb_is_nonlinear(skb)) {
-               pr_debug("Copy of skbuff not supported yet.\n");
-               return NF_ACCEPT;
-       }
+       if (unlikely(skb_linearize(skb)))
+               return NF_DROP;
 
        dptr = skb->data + dataoff;
        datalen = skb->len - dataoff;