X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=net%2Fipv4%2Fudp.c;h=9e1bd374875e2f86f96dcb2f768849f20ed67c52;hb=bd3c97a7c718bfb9f1e4f31c16c383a5c6f815eb;hp=865d75214a9ab1d741f3d8351359e95a0d8394e7;hpb=1e0c14f49d6b393179f423abbac47f85618d3d46;p=powerpc.git diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 865d75214a..9e1bd37487 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -928,23 +928,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); - __be32 *udpdata32 = (__be32 *)udpdata; + __u8 *udpdata; + __be32 *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 = (__be32 *)udpdata; switch (encap_type) { default: