@@ -274,13 +274,20 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
274
274
__sum16 check ;
275
275
__be16 newlen ;
276
276
277
- if (skb_shinfo (gso_skb )-> gso_type & SKB_GSO_FRAGLIST )
278
- return __udp_gso_segment_list (gso_skb , features , is_ipv6 );
279
-
280
277
mss = skb_shinfo (gso_skb )-> gso_size ;
281
278
if (gso_skb -> len <= sizeof (* uh ) + mss )
282
279
return ERR_PTR (- EINVAL );
283
280
281
+ if (skb_gso_ok (gso_skb , features | NETIF_F_GSO_ROBUST )) {
282
+ /* Packet is from an untrusted source, reset gso_segs. */
283
+ skb_shinfo (gso_skb )-> gso_segs = DIV_ROUND_UP (gso_skb -> len - sizeof (* uh ),
284
+ mss );
285
+ return NULL ;
286
+ }
287
+
288
+ if (skb_shinfo (gso_skb )-> gso_type & SKB_GSO_FRAGLIST )
289
+ return __udp_gso_segment_list (gso_skb , features , is_ipv6 );
290
+
284
291
skb_pull (gso_skb , sizeof (* uh ));
285
292
286
293
/* clear destructor to avoid skb_segment assigning it to tail */
@@ -388,8 +395,7 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
388
395
if (!pskb_may_pull (skb , sizeof (struct udphdr )))
389
396
goto out ;
390
397
391
- if (skb_shinfo (skb )-> gso_type & SKB_GSO_UDP_L4 &&
392
- !skb_gso_ok (skb , features | NETIF_F_GSO_ROBUST ))
398
+ if (skb_shinfo (skb )-> gso_type & SKB_GSO_UDP_L4 )
393
399
return __udp_gso_segment (skb , features , false);
394
400
395
401
mss = skb_shinfo (skb )-> gso_size ;
0 commit comments