From: Willem de Bruijn Date: Tue, 26 Sep 2017 16:20:17 +0000 (-0400) Subject: packet: only test po->has_vnet_hdr once in packet_snd X-Git-Tag: v3.2.97~65 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d8da6748e80b542ac58fca51deb0d4f42f2d54c;p=thirdparty%2Fkernel%2Fstable.git packet: only test po->has_vnet_hdr once in packet_snd commit da7c9561015e93d10fe6aab73e9288e0d09d65a6 upstream. Packet socket option po->has_vnet_hdr can be updated concurrently with other operations if no ring is attached. Do not test the option twice in packet_snd, as the value may change in between calls. A race on setsockopt disable may cause a packet > mtu to be sent without having GSO options set. Fixes: bfd5f4a3d605 ("packet: Add GSO/csum offload support.") Signed-off-by: Willem de Bruijn Reviewed-by: Eric Dumazet Signed-off-by: David S. Miller [bwh: Backported to 3.2: adjust context] Signed-off-by: Ben Hutchings --- diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 2d44726d8a00e..4f6392d71ea2c 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2231,6 +2231,7 @@ static int packet_snd(struct socket *sock, int offset = 0; int vnet_hdr_len; struct packet_sock *po = pkt_sk(sk); + bool has_vnet_hdr = false; unsigned short gso_type = 0; /* @@ -2263,6 +2264,7 @@ static int packet_snd(struct socket *sock, reserve = dev->hard_header_len; if (po->has_vnet_hdr) { vnet_hdr_len = sizeof(vnet_hdr); + has_vnet_hdr = true; err = -EINVAL; if (len < vnet_hdr_len) @@ -2354,7 +2356,7 @@ static int packet_snd(struct socket *sock, skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; - if (po->has_vnet_hdr) { + if (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)) {