Skip to content

Commit

Permalink
udp: segment looped gso packets correctly
Browse files Browse the repository at this point in the history
Multicast and broadcast packets can be looped from egress to ingress
pre segmentation with dev_loopback_xmit. That function unconditionally
sets ip_summed to CHECKSUM_UNNECESSARY.

udp_rcv_segment segments gso packets in the udp rx path. Segmentation
usually executes on egress, and does not expect packets of this type.
__udp_gso_segment interprets !CHECKSUM_PARTIAL as CHECKSUM_NONE. But
the offsets are not correct for gso_make_checksum.

UDP GSO packets are of type CHECKSUM_PARTIAL, with their uh->check set
to the correct pseudo header checksum. Reset ip_summed to this type.
(CHECKSUM_PARTIAL is allowed on ingress, see comments in skbuff.h)

Reported-by: syzbot <[email protected]>
Fixes: cf329aa ("udp: cope with UDP GRO packet misdirection")
Signed-off-by: Willem de Bruijn <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
wdebruij authored and davem330 committed Jan 28, 2020
1 parent 3127642 commit 6cd021a
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions include/net/udp.h
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,9 @@ static inline struct sk_buff *udp_rcv_segment(struct sock *sk,
if (!inet_get_convert_csum(sk))
features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;

if (skb->pkt_type == PACKET_LOOPBACK)
skb->ip_summed = CHECKSUM_PARTIAL;

/* the GSO CB lays after the UDP one, no need to save and restore any
* CB fragment
*/
Expand Down

0 comments on commit 6cd021a

Please sign in to comment.