summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-06-29 20:11:25 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-30 14:11:47 -0700
commit3820c3f3e41786322c0bb225b9c77b8deff869d1 (patch)
treea422ad9d119950af2d139849fe24e935ad9f0a22
parent598736c55622f7ea65b98f93c825ff95c433877c (diff)
[TCP]: Reset gso_segs if packet is dodgy
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>
-rw-r--r--net/ipv4/tcp.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 0336422c88a0..0bb0ac96d675 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -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;