unsigned int seq;
        __be32 delta;
        unsigned int oldlen;
-       unsigned int len;
+       unsigned int mss;
 
        if (!pskb_may_pull(skb, sizeof(*th)))
                goto out;
        oldlen = (u16)~skb->len;
        __skb_pull(skb, thlen);
 
+       mss = skb_shinfo(skb)->gso_size;
+       if (unlikely(skb->len <= mss))
+               goto out;
+
        if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
                /* Packet is from an untrusted source, reset gso_segs. */
                int type = skb_shinfo(skb)->gso_type;
-               int mss;
 
                if (unlikely(type &
                             ~(SKB_GSO_TCPV4 |
                             !(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))))
                        goto out;
 
-               mss = skb_shinfo(skb)->gso_size;
                skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);
 
                segs = NULL;
        if (IS_ERR(segs))
                goto out;
 
-       len = skb_shinfo(skb)->gso_size;
-       delta = htonl(oldlen + (thlen + len));
+       delta = htonl(oldlen + (thlen + mss));
 
        skb = segs;
        th = tcp_hdr(skb);
                             csum_fold(csum_partial(skb_transport_header(skb),
                                                    thlen, skb->csum));
 
-               seq += len;
+               seq += mss;
                skb = skb->next;
                th = tcp_hdr(skb);