diff options
author | Eric Dumazet <edumazet@google.com> | 2023-03-16 01:10:08 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2023-03-17 08:52:05 +0000 |
commit | fd53c297aa7b077ae98a3d3d2d3aa278a1686ba6 (patch) | |
tree | 0a62bc12c8fee36cae0ff6ea93f82ea4ab6483cb /net/packet | |
parent | ee5675ecdf7a4e713ed21d98a70c2871d6ebed01 (diff) | |
download | linux-fd53c297aa7b077ae98a3d3d2d3aa278a1686ba6.tar.gz linux-fd53c297aa7b077ae98a3d3d2d3aa278a1686ba6.tar.bz2 linux-fd53c297aa7b077ae98a3d3d2d3aa278a1686ba6.zip |
net/packet: convert po->auxdata to an atomic flag
po->auxdata can be read while another thread
is changing its value, potentially raising KCSAN splat.
Convert it to PACKET_SOCK_AUXDATA flag.
Fixes: 8dc419447415 ("[PACKET]: Add optional checksum computation for recvmsg")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/packet')
-rw-r--r-- | net/packet/af_packet.c | 8 | ||||
-rw-r--r-- | net/packet/diag.c | 2 | ||||
-rw-r--r-- | net/packet/internal.h | 4 |
3 files changed, 6 insertions, 8 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index af7c44169b86..ecd9fc27e360 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -3514,7 +3514,7 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, copy_len); } - if (pkt_sk(sk)->auxdata) { + if (packet_sock_flag(pkt_sk(sk), PACKET_SOCK_AUXDATA)) { struct tpacket_auxdata aux; aux.tp_status = TP_STATUS_USER; @@ -3900,9 +3900,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval, if (copy_from_sockptr(&val, optval, sizeof(val))) return -EFAULT; - lock_sock(sk); - po->auxdata = !!val; - release_sock(sk); + packet_sock_flag_set(po, PACKET_SOCK_AUXDATA, val); return 0; } case PACKET_ORIGDEV: @@ -4060,7 +4058,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, break; case PACKET_AUXDATA: - val = po->auxdata; + val = packet_sock_flag(po, PACKET_SOCK_AUXDATA); break; case PACKET_ORIGDEV: val = packet_sock_flag(po, PACKET_SOCK_ORIGDEV); diff --git a/net/packet/diag.c b/net/packet/diag.c index e1ac9bb375b3..d704c7bf51b2 100644 --- a/net/packet/diag.c +++ b/net/packet/diag.c @@ -23,7 +23,7 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb) pinfo.pdi_flags = 0; if (po->running) pinfo.pdi_flags |= PDI_RUNNING; - if (po->auxdata) + if (packet_sock_flag(po, PACKET_SOCK_AUXDATA)) pinfo.pdi_flags |= PDI_AUXDATA; if (packet_sock_flag(po, PACKET_SOCK_ORIGDEV)) pinfo.pdi_flags |= PDI_ORIGDEV; diff --git a/net/packet/internal.h b/net/packet/internal.h index 178cd1852238..3bae8ea7a36f 100644 --- a/net/packet/internal.h +++ b/net/packet/internal.h @@ -118,8 +118,7 @@ struct packet_sock { struct mutex pg_vec_lock; unsigned long flags; unsigned int running; /* bind_lock must be held */ - unsigned int auxdata:1, /* writer must hold sock lock */ - has_vnet_hdr:1, + unsigned int has_vnet_hdr:1, /* writer must hold sock lock */ tp_loss:1, tp_tx_has_off:1; int pressure; @@ -146,6 +145,7 @@ static inline struct packet_sock *pkt_sk(struct sock *sk) enum packet_sock_flags { PACKET_SOCK_ORIGDEV, + PACKET_SOCK_AUXDATA, }; static inline void packet_sock_flag_set(struct packet_sock *po, |