[TCP]: Reset gso_segs if packet is dodgy
authorHerbert Xu <herbert@gondor.apana.org.au>
Fri, 30 Jun 2006 03:11:25 +0000 (20:11 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Fri, 30 Jun 2006 21:11:47 +0000 (14:11 -0700)
I wasn't paranoid enough in verifying GSO information.  A bogus gso_segs
could upset drivers as much as a bogus header would.  Let's reset it in
the per-protocol gso_segment functions.

I didn't verify gso_size because that can be verified by the source of
the dodgy packets.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/tcp.c

index 0336422c88a03becbf006d26c064b25504b62bf9..0bb0ac96d675766e306eb23298d38a9c132df353 100644 (file)
@@ -2166,13 +2166,19 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
        if (!pskb_may_pull(skb, thlen))
                goto out;
 
-       segs = NULL;
-       if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
-               goto out;
-
        oldlen = (u16)~skb->len;
        __skb_pull(skb, thlen);
 
+       if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
+               /* Packet is from an untrusted source, reset gso_segs. */
+               int mss = skb_shinfo(skb)->gso_size;
+
+               skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;
+
+               segs = NULL;
+               goto out;
+       }
+
        segs = skb_segment(skb, features);
        if (IS_ERR(segs))
                goto out;