Skip to content

Commit 1299f7e

Browse files
wdebruijgregkh
authored andcommitted
packet: only test po->has_vnet_hdr once in packet_snd
[ Upstream commit da7c9561015e93d10fe6aab73e9288e0d09d65a6 ] 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: bfd5f4a ("packet: Add GSO/csum offload support.") Signed-off-by: Willem de Bruijn <willemb@google.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 1b6c80e commit 1299f7e

1 file changed

Lines changed: 4 additions & 2 deletions

File tree

net/packet/af_packet.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,7 +1717,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
17171717
}
17181718
spin_unlock(&po->bind_lock);
17191719

1720-
if (err && !refcount_read(&match->sk_ref)) {
1720+
if (err && !atomic_read(&match->sk_ref)) {
17211721
list_del(&match->list);
17221722
kfree(match);
17231723
}
@@ -2656,6 +2656,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
26562656
int vnet_hdr_len;
26572657
struct packet_sock *po = pkt_sk(sk);
26582658
unsigned short gso_type = 0;
2659+
bool has_vnet_hdr = false;
26592660
int hlen, tlen, linear;
26602661
int extra_len = 0;
26612662
ssize_t n;
@@ -2743,6 +2744,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
27432744
goto out_unlock;
27442745

27452746
}
2747+
has_vnet_hdr = true;
27462748
}
27472749

27482750
if (unlikely(sock_flag(sk, SOCK_NOFCS))) {
@@ -2802,7 +2804,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
28022804

28032805
packet_pick_tx_queue(dev, skb);
28042806

2805-
if (po->has_vnet_hdr) {
2807+
if (has_vnet_hdr) {
28062808
if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
28072809
u16 s = __virtio16_to_cpu(vio_le(), vnet_hdr.csum_start);
28082810
u16 o = __virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset);

0 commit comments

Comments
 (0)