net/packet: convert po->auxdata to an atomic flag
authorEric Dumazet <edumazet@google.com>
Thu, 16 Mar 2023 01:10:08 +0000 (01:10 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 May 2023 14:03:18 +0000 (23:03 +0900)
[ Upstream commit fd53c297aa7b077ae98a3d3d2d3aa278a1686ba6 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/packet/af_packet.c
net/packet/diag.c
net/packet/internal.h

index 6c572fc..ac9335d 100644 (file)
@@ -3515,7 +3515,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;
@@ -3899,9 +3899,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:
@@ -4059,7 +4057,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);
index e1ac9bb..d704c7b 100644 (file)
@@ -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;
index 178cd18..3bae8ea 100644 (file)
@@ -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,