X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fudp.c;h=0ba06cf36abcf8e088f03a57a12ff814daff7853;hb=567f20a20be06ad546b5962340c4be268462055b;hp=993a800907039e7bf01d640ba96098aa6cfc3cf2;hpb=653a9213ae6f303790975dd836d95778aab070de;p=linux-2.6.git diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 993a80090..0ba06cf36 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -909,23 +909,32 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) return 1; #else struct udp_sock *up = udp_sk(sk); - struct udphdr *uh = skb->h.uh; + struct udphdr *uh; struct iphdr *iph; int iphlen, len; - __u8 *udpdata = (__u8 *)uh + sizeof(struct udphdr); - __u32 *udpdata32 = (__u32 *)udpdata; + __u8 *udpdata; + __u32 *udpdata32; __u16 encap_type = up->encap_type; /* if we're overly short, let UDP handle it */ - if (udpdata > skb->tail) + len = skb->len - sizeof(struct udphdr); + if (len <= 0) return 1; /* if this is not encapsulated socket, then just return now */ if (!encap_type) return 1; - len = skb->tail - udpdata; + /* If this is a paged skb, make sure we pull up + * whatever data we need to look at. */ + if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8))) + return 1; + + /* Now we can get the pointers */ + uh = skb->h.uh; + udpdata = (__u8 *)uh + sizeof(struct udphdr); + udpdata32 = (__u32 *)udpdata; switch (encap_type) { default: