summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-06-14 08:29:37 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-06-14 08:29:37 -0700
commit98a394311bc43a4e1ede4c8920cf8ffdfab4033f (patch)
treef7c7f0442b2239f8596df68041ca8422b520a860
parent3b89d48658555dc3ebfe7d7af0a25f0b3e0a19f1 (diff)
parent158cb909d603304add502d835ee7113d8335f787 (diff)
Merge bk://kernel.bkbits.net/davem/net-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c11
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c2
-rw-r--r--net/ipv6/udp.c26
3 files changed, 16 insertions, 23 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 50a467898671..67c2fd2a5335 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -324,8 +324,9 @@ destroy_conntrack(struct nf_conntrack *nfct)
ip_conntrack_destroyed(ct);
WRITE_LOCK(&ip_conntrack_lock);
- /* Delete us from our own list to prevent corruption later */
- list_del(&ct->sibling_list);
+ /* Make sure don't leave any orphaned expectations lying around */
+ if (ct->expecting)
+ remove_expectations(ct, 1);
/* Delete our master expectation */
if (ct->master) {
@@ -1127,10 +1128,8 @@ int ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
DUMP_TUPLE(newreply);
conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
- if (!conntrack->master)
- conntrack->helper = LIST_FIND(&helpers, helper_cmp,
- struct ip_conntrack_helper *,
- newreply);
+ if (!conntrack->master && list_empty(&conntrack->sibling_list))
+ conntrack->helper = ip_ct_find_helper(newreply);
WRITE_UNLOCK(&ip_conntrack_lock);
return 1;
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 9bcb718eca16..1cc796556f27 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -177,6 +177,8 @@ static int tcp_packet(struct ip_conntrack *conntrack,
if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &tcph, sizeof(tcph)) != 0)
return -1;
+ if (skb->len < skb->nh.iph->ihl * 4 + tcph.doff * 4)
+ return -1;
/* If only reply is a RST, we can consider ourselves not to
have an established connection: this is a fairly common
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 798f266f0551..0dc7f0ec1fea 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -572,34 +572,26 @@ static void udpv6_mcast_deliver(struct udphdr *uh,
struct sk_buff *skb)
{
struct sock *sk, *sk2;
- struct sk_buff *buff;
int dif;
read_lock(&udp_hash_lock);
sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
dif = skb->dev->ifindex;
sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
- if (!sk)
- goto free_skb;
+ if (!sk) {
+ kfree_skb(skb);
+ goto out;
+ }
- buff = NULL;
sk2 = sk;
while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr,
uh->source, saddr, dif))) {
- if (!buff) {
- buff = skb_clone(skb, GFP_ATOMIC);
- if (!buff)
- continue;
- }
- if (udpv6_queue_rcv_skb(sk2, buff) >= 0)
- buff = NULL;
- }
- if (buff)
- kfree_skb(buff);
- if (udpv6_queue_rcv_skb(sk, skb) < 0) {
-free_skb:
- kfree_skb(skb);
+ struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
+ if (buff)
+ udpv6_queue_rcv_skb(sk2, buff);
}
+ udpv6_queue_rcv_skb(sk, skb);
+out:
read_unlock(&udp_hash_lock);
}