Loading net/packet/af_packet.c +22 −13 Original line number Diff line number Diff line Loading @@ -2444,13 +2444,15 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) goto out_unlock; if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && (vnet_hdr.csum_start + vnet_hdr.csum_offset + 2 > vnet_hdr.hdr_len)) vnet_hdr.hdr_len = vnet_hdr.csum_start + vnet_hdr.csum_offset + 2; (__virtio16_to_cpu(false, vnet_hdr.csum_start) + __virtio16_to_cpu(false, vnet_hdr.csum_offset) + 2 > __virtio16_to_cpu(false, vnet_hdr.hdr_len))) vnet_hdr.hdr_len = __cpu_to_virtio16(false, __virtio16_to_cpu(false, vnet_hdr.csum_start) + __virtio16_to_cpu(false, vnet_hdr.csum_offset) + 2); err = -EINVAL; if (vnet_hdr.hdr_len > len) if (__virtio16_to_cpu(false, vnet_hdr.hdr_len) > len) goto out_unlock; if (vnet_hdr.gso_type != VIRTIO_NET_HDR_GSO_NONE) { Loading Loading @@ -2492,7 +2494,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) err = -ENOBUFS; hlen = LL_RESERVED_SPACE(dev); tlen = dev->needed_tailroom; skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, vnet_hdr.hdr_len, skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, __virtio16_to_cpu(false, vnet_hdr.hdr_len), msg->msg_flags & MSG_DONTWAIT, &err); if (skb == NULL) goto out_unlock; Loading Loading @@ -2534,14 +2537,16 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) if (po->has_vnet_hdr) { if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { if (!skb_partial_csum_set(skb, vnet_hdr.csum_start, vnet_hdr.csum_offset)) { u16 s = __virtio16_to_cpu(false, vnet_hdr.csum_start); u16 o = __virtio16_to_cpu(false, vnet_hdr.csum_offset); if (!skb_partial_csum_set(skb, s, o)) { err = -EINVAL; goto out_free; } } skb_shinfo(skb)->gso_size = vnet_hdr.gso_size; skb_shinfo(skb)->gso_size = __virtio16_to_cpu(false, vnet_hdr.gso_size); skb_shinfo(skb)->gso_type = gso_type; /* Header must be checked, and gso_segs computed. */ Loading Loading @@ -2912,8 +2917,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, struct skb_shared_info *sinfo = skb_shinfo(skb); /* This is a hint as to how much should be linear. */ vnet_hdr.hdr_len = skb_headlen(skb); vnet_hdr.gso_size = sinfo->gso_size; vnet_hdr.hdr_len = __cpu_to_virtio16(false, skb_headlen(skb)); vnet_hdr.gso_size = __cpu_to_virtio16(false, sinfo->gso_size); if (sinfo->gso_type & SKB_GSO_TCPV4) vnet_hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; else if (sinfo->gso_type & SKB_GSO_TCPV6) Loading @@ -2931,8 +2938,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, if (skb->ip_summed == CHECKSUM_PARTIAL) { vnet_hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; vnet_hdr.csum_start = skb_checksum_start_offset(skb); vnet_hdr.csum_offset = skb->csum_offset; vnet_hdr.csum_start = __cpu_to_virtio16(false, skb_checksum_start_offset(skb)); vnet_hdr.csum_offset = __cpu_to_virtio16(false, skb->csum_offset); } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID; } /* else everything is zero */ Loading Loading
net/packet/af_packet.c +22 −13 Original line number Diff line number Diff line Loading @@ -2444,13 +2444,15 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) goto out_unlock; if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && (vnet_hdr.csum_start + vnet_hdr.csum_offset + 2 > vnet_hdr.hdr_len)) vnet_hdr.hdr_len = vnet_hdr.csum_start + vnet_hdr.csum_offset + 2; (__virtio16_to_cpu(false, vnet_hdr.csum_start) + __virtio16_to_cpu(false, vnet_hdr.csum_offset) + 2 > __virtio16_to_cpu(false, vnet_hdr.hdr_len))) vnet_hdr.hdr_len = __cpu_to_virtio16(false, __virtio16_to_cpu(false, vnet_hdr.csum_start) + __virtio16_to_cpu(false, vnet_hdr.csum_offset) + 2); err = -EINVAL; if (vnet_hdr.hdr_len > len) if (__virtio16_to_cpu(false, vnet_hdr.hdr_len) > len) goto out_unlock; if (vnet_hdr.gso_type != VIRTIO_NET_HDR_GSO_NONE) { Loading Loading @@ -2492,7 +2494,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) err = -ENOBUFS; hlen = LL_RESERVED_SPACE(dev); tlen = dev->needed_tailroom; skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, vnet_hdr.hdr_len, skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, __virtio16_to_cpu(false, vnet_hdr.hdr_len), msg->msg_flags & MSG_DONTWAIT, &err); if (skb == NULL) goto out_unlock; Loading Loading @@ -2534,14 +2537,16 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) if (po->has_vnet_hdr) { if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { if (!skb_partial_csum_set(skb, vnet_hdr.csum_start, vnet_hdr.csum_offset)) { u16 s = __virtio16_to_cpu(false, vnet_hdr.csum_start); u16 o = __virtio16_to_cpu(false, vnet_hdr.csum_offset); if (!skb_partial_csum_set(skb, s, o)) { err = -EINVAL; goto out_free; } } skb_shinfo(skb)->gso_size = vnet_hdr.gso_size; skb_shinfo(skb)->gso_size = __virtio16_to_cpu(false, vnet_hdr.gso_size); skb_shinfo(skb)->gso_type = gso_type; /* Header must be checked, and gso_segs computed. */ Loading Loading @@ -2912,8 +2917,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, struct skb_shared_info *sinfo = skb_shinfo(skb); /* This is a hint as to how much should be linear. */ vnet_hdr.hdr_len = skb_headlen(skb); vnet_hdr.gso_size = sinfo->gso_size; vnet_hdr.hdr_len = __cpu_to_virtio16(false, skb_headlen(skb)); vnet_hdr.gso_size = __cpu_to_virtio16(false, sinfo->gso_size); if (sinfo->gso_type & SKB_GSO_TCPV4) vnet_hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; else if (sinfo->gso_type & SKB_GSO_TCPV6) Loading @@ -2931,8 +2938,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, if (skb->ip_summed == CHECKSUM_PARTIAL) { vnet_hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; vnet_hdr.csum_start = skb_checksum_start_offset(skb); vnet_hdr.csum_offset = skb->csum_offset; vnet_hdr.csum_start = __cpu_to_virtio16(false, skb_checksum_start_offset(skb)); vnet_hdr.csum_offset = __cpu_to_virtio16(false, skb->csum_offset); } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID; } /* else everything is zero */ Loading