diff options
-rw-r--r-- | include/linux/netfilter/x_tables.h | 2 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack_core.h | 2 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 10 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_sip.c | 12 |
4 files changed, 16 insertions, 10 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index c2ee5d8550cf..c00cc0c4d0b7 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h | |||
@@ -333,7 +333,7 @@ struct xt_target { | |||
333 | /* Called when user tries to insert an entry of this type: | 333 | /* Called when user tries to insert an entry of this type: |
334 | hook_mask is a bitmask of hooks from which it can be | 334 | hook_mask is a bitmask of hooks from which it can be |
335 | called. */ | 335 | called. */ |
336 | /* Should return true or false, or an error code (-Exxxx). */ | 336 | /* Should return 0 on success or an error code otherwise (-Exxxx). */ |
337 | int (*checkentry)(const struct xt_tgchk_param *); | 337 | int (*checkentry)(const struct xt_tgchk_param *); |
338 | 338 | ||
339 | /* Called when entry of this type deleted. */ | 339 | /* Called when entry of this type deleted. */ |
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h index dffde8e6920e..3d7524fba194 100644 --- a/include/net/netfilter/nf_conntrack_core.h +++ b/include/net/netfilter/nf_conntrack_core.h | |||
@@ -61,7 +61,7 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb) | |||
61 | int ret = NF_ACCEPT; | 61 | int ret = NF_ACCEPT; |
62 | 62 | ||
63 | if (ct && ct != &nf_conntrack_untracked) { | 63 | if (ct && ct != &nf_conntrack_untracked) { |
64 | if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) | 64 | if (!nf_ct_is_confirmed(ct)) |
65 | ret = __nf_conntrack_confirm(skb); | 65 | ret = __nf_conntrack_confirm(skb); |
66 | if (likely(ret == NF_ACCEPT)) | 66 | if (likely(ret == NF_ACCEPT)) |
67 | nf_ct_deliver_cached_events(ct); | 67 | nf_ct_deliver_cached_events(ct); |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index b83c530c5e0a..eeeb8bc73982 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -424,6 +424,16 @@ __nf_conntrack_confirm(struct sk_buff *skb) | |||
424 | 424 | ||
425 | spin_lock_bh(&nf_conntrack_lock); | 425 | spin_lock_bh(&nf_conntrack_lock); |
426 | 426 | ||
427 | /* We have to check the DYING flag inside the lock to prevent | ||
428 | a race against nf_ct_get_next_corpse() possibly called from | ||
429 | user context, else we insert an already 'dead' hash, blocking | ||
430 | further use of that particular connection -JM */ | ||
431 | |||
432 | if (unlikely(nf_ct_is_dying(ct))) { | ||
433 | spin_unlock_bh(&nf_conntrack_lock); | ||
434 | return NF_ACCEPT; | ||
435 | } | ||
436 | |||
427 | /* See if there's one in the list already, including reverse: | 437 | /* See if there's one in the list already, including reverse: |
428 | NAT could have grabbed it without realizing, since we're | 438 | NAT could have grabbed it without realizing, since we're |
429 | not in the hash. If there is, we lost race. */ | 439 | not in the hash. If there is, we lost race. */ |
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index b20f4275893c..53d892210a04 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -1393,10 +1393,8 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, | |||
1393 | 1393 | ||
1394 | nf_ct_refresh(ct, skb, sip_timeout * HZ); | 1394 | nf_ct_refresh(ct, skb, sip_timeout * HZ); |
1395 | 1395 | ||
1396 | if (skb_is_nonlinear(skb)) { | 1396 | if (unlikely(skb_linearize(skb))) |
1397 | pr_debug("Copy of skbuff not supported yet.\n"); | 1397 | return NF_DROP; |
1398 | return NF_ACCEPT; | ||
1399 | } | ||
1400 | 1398 | ||
1401 | dptr = skb->data + dataoff; | 1399 | dptr = skb->data + dataoff; |
1402 | datalen = skb->len - dataoff; | 1400 | datalen = skb->len - dataoff; |
@@ -1455,10 +1453,8 @@ static int sip_help_udp(struct sk_buff *skb, unsigned int protoff, | |||
1455 | 1453 | ||
1456 | nf_ct_refresh(ct, skb, sip_timeout * HZ); | 1454 | nf_ct_refresh(ct, skb, sip_timeout * HZ); |
1457 | 1455 | ||
1458 | if (skb_is_nonlinear(skb)) { | 1456 | if (unlikely(skb_linearize(skb))) |
1459 | pr_debug("Copy of skbuff not supported yet.\n"); | 1457 | return NF_DROP; |
1460 | return NF_ACCEPT; | ||
1461 | } | ||
1462 | 1458 | ||
1463 | dptr = skb->data + dataoff; | 1459 | dptr = skb->data + dataoff; |
1464 | datalen = skb->len - dataoff; | 1460 | datalen = skb->len - dataoff; |