Skip to content

Commit

Permalink
Merge pull request #192 from truenas/NAS-130945
Browse files Browse the repository at this point in the history
NAS-130945 / 24.10 / net: drop bad gso csum_start and offset in virtio_net_hdr
  • Loading branch information
amotin authored Sep 9, 2024
2 parents 50620c2 + cae3470 commit ff6360d
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 11 deletions.
16 changes: 5 additions & 11 deletions include/linux/virtio_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
unsigned int thlen = 0;
unsigned int p_off = 0;
unsigned int ip_proto;
u64 ret, remainder, gso_size;

if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
Expand Down Expand Up @@ -99,16 +98,6 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
u32 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
u32 needed = start + max_t(u32, thlen, off + sizeof(__sum16));

if (hdr->gso_size) {
gso_size = __virtio16_to_cpu(little_endian, hdr->gso_size);
ret = div64_u64_rem(skb->len, gso_size, &remainder);
if (!(ret && (hdr->gso_size > needed) &&
((remainder > needed) || (remainder == 0)))) {
return -EINVAL;
}
skb_shinfo(skb)->tx_flags |= SKBFL_SHARED_FRAG;
}

if (!pskb_may_pull(skb, needed))
return -EINVAL;

Expand Down Expand Up @@ -182,6 +171,11 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
if (gso_type != SKB_GSO_UDP_L4)
return -EINVAL;
break;
case SKB_GSO_TCPV4:
case SKB_GSO_TCPV6:
if (skb->csum_offset != offsetof(struct tcphdr, check))
return -EINVAL;
break;
}

/* Kernel has a special handling for GSO_BY_FRAGS. */
Expand Down
3 changes: 3 additions & 0 deletions net/ipv4/tcp_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
if (thlen < sizeof(*th))
goto out;

if (unlikely(skb_checksum_start(skb) != skb_transport_header(skb)))
goto out;

if (!pskb_may_pull(skb, thlen))
goto out;

Expand Down
4 changes: 4 additions & 0 deletions net/ipv4/udp_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,10 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
if (gso_skb->len <= sizeof(*uh) + mss)
return ERR_PTR(-EINVAL);

if (unlikely(skb_checksum_start(gso_skb) !=
skb_transport_header(gso_skb)))
return ERR_PTR(-EINVAL);

if (skb_gso_ok(gso_skb, features | NETIF_F_GSO_ROBUST)) {
/* Packet is from an untrusted source, reset gso_segs. */
skb_shinfo(gso_skb)->gso_segs = DIV_ROUND_UP(gso_skb->len - sizeof(*uh),
Expand Down

0 comments on commit ff6360d

Please sign in to comment.