[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200629153502.2494656-2-sashal@kernel.org>
Date: Mon, 29 Jun 2020 11:32:52 -0400
From: Sasha Levin <sashal@...nel.org>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
Cc: Eric Dumazet <edumazet@...gle.com>,
Willem de Bruijn <willemb@...gle.com>,
"David S . Miller" <davem@...emloft.net>,
Guenter Roeck <linux@...ck-us.net>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Subject: [PATCH 4.19 001/131] net: be more gentle about silly gso requests coming from user
From: Eric Dumazet <edumazet@...gle.com>
commit 7c6d2ecbda83150b2036a2b36b21381ad4667762 upstream.
Recent change in virtio_net_hdr_to_skb() broke some packetdrill tests.
When --mss=XXX option is set, packetdrill always provide gso_type & gso_size
for its inbound packets, regardless of packet size.
if (packet->tcp && packet->mss) {
if (packet->ipv4)
gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
else
gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
gso.gso_size = packet->mss;
}
Since many other programs could do the same, relax virtio_net_hdr_to_skb()
to no longer return an error, but instead ignore gso settings.
This keeps Willem intent to make sure no malicious packet could
reach gso stack.
Note that TCP stack has a special logic in tcp_set_skb_tso_segs()
to clear gso_size for small packets.
Fixes: 6dd912f82680 ("net: check untrusted gso_size at kernel entry")
Signed-off-by: Eric Dumazet <edumazet@...gle.com>
Cc: Willem de Bruijn <willemb@...gle.com>
Acked-by: Willem de Bruijn <willemb@...gle.com>
Signed-off-by: David S. Miller <davem@...emloft.net>
Cc: Guenter Roeck <linux@...ck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
include/linux/virtio_net.h | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index 1c296f370e461..f32fe7080d2ec 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -109,16 +109,17 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
u16 gso_size = __virtio16_to_cpu(little_endian, hdr->gso_size);
+ struct skb_shared_info *shinfo = skb_shinfo(skb);
- if (skb->len - p_off <= gso_size)
- return -EINVAL;
-
- skb_shinfo(skb)->gso_size = gso_size;
- skb_shinfo(skb)->gso_type = gso_type;
+ /* Too small packets are not really GSO ones. */
+ if (skb->len - p_off > gso_size) {
+ shinfo->gso_size = gso_size;
+ shinfo->gso_type = gso_type;
- /* Header must be checked, and gso_segs computed. */
- skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
- skb_shinfo(skb)->gso_segs = 0;
+ /* Header must be checked, and gso_segs computed. */
+ shinfo->gso_type |= SKB_GSO_DODGY;
+ shinfo->gso_segs = 0;
+ }
}
return 0;
--
2.25.1
Powered by blists - more mailing lists