ipv6: Check ip6_find_1stfragopt() return value properly.
[pandora-kernel.git] / net / ipv6 / udp.c
index 15f75e4..5f0d519 100644 (file)
@@ -344,6 +344,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
        int peeked;
        int err;
        int is_udplite = IS_UDPLITE(sk);
+       bool checksum_valid = false;
        int is_udp4;
        bool slow;
 
@@ -375,11 +376,12 @@ try_again:
         */
 
        if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
-               if (udp_lib_checksum_complete(skb))
+               checksum_valid = !udp_lib_checksum_complete(skb);
+               if (!checksum_valid)
                        goto csum_copy_err;
        }
 
-       if (skb_csum_unnecessary(skb))
+       if (checksum_valid || skb_csum_unnecessary(skb))
                err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
                                              msg->msg_iov, copied       );
        else {
@@ -1314,6 +1316,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features)
        u8 frag_hdr_sz = sizeof(struct frag_hdr);
        int offset;
        __wsum csum;
+       int err;
 
        mss = skb_shinfo(skb)->gso_size;
        if (unlikely(skb->len <= mss))
@@ -1350,7 +1353,10 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features)
        /* Find the unfragmentable header and shift it left by frag_hdr_sz
         * bytes to insert fragment header.
         */
-       unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);
+       err = ip6_find_1stfragopt(skb, &prevhdr);
+       if (err < 0)
+               return ERR_PTR(err);
+       unfrag_ip6hlen = err;
        nexthdr = *prevhdr;
        *prevhdr = NEXTHDR_FRAGMENT;
        unfrag_len = skb_network_header(skb) - skb_mac_header(skb) +