Commit 3820c3f3e41786322c0bb225b9c77b8deff869d1
Committed by
David S. Miller
1 parent
598736c556
Exists in
master
and in
4 other branches
[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>
Showing 1 changed file with 10 additions and 4 deletions Side-by-side Diff
net/ipv4/tcp.c
| ... | ... | @@ -2166,12 +2166,18 @@ |
| 2166 | 2166 | if (!pskb_may_pull(skb, thlen)) |
| 2167 | 2167 | goto out; |
| 2168 | 2168 | |
| 2169 | - segs = NULL; | |
| 2170 | - if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) | |
| 2171 | - goto out; | |
| 2172 | - | |
| 2173 | 2169 | oldlen = (u16)~skb->len; |
| 2174 | 2170 | __skb_pull(skb, thlen); |
| 2171 | + | |
| 2172 | + if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) { | |
| 2173 | + /* Packet is from an untrusted source, reset gso_segs. */ | |
| 2174 | + int mss = skb_shinfo(skb)->gso_size; | |
| 2175 | + | |
| 2176 | + skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss; | |
| 2177 | + | |
| 2178 | + segs = NULL; | |
| 2179 | + goto out; | |
| 2180 | + } | |
| 2175 | 2181 | |
| 2176 | 2182 | segs = skb_segment(skb, features); |
| 2177 | 2183 | if (IS_ERR(segs)) |