net/packet: convert po->auxdata to an atomic flag
[ 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: 8dc4194474 ("[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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
5ca1be3658
commit
05c6db12ae
@@ -3485,7 +3485,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);
|
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;
|
struct tpacket_auxdata aux;
|
||||||
|
|
||||||
aux.tp_status = TP_STATUS_USER;
|
aux.tp_status = TP_STATUS_USER;
|
||||||
@@ -3869,9 +3869,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
|
|||||||
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
if (copy_from_sockptr(&val, optval, sizeof(val)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
lock_sock(sk);
|
packet_sock_flag_set(po, PACKET_SOCK_AUXDATA, val);
|
||||||
po->auxdata = !!val;
|
|
||||||
release_sock(sk);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case PACKET_ORIGDEV:
|
case PACKET_ORIGDEV:
|
||||||
@@ -4032,7 +4030,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case PACKET_AUXDATA:
|
case PACKET_AUXDATA:
|
||||||
val = po->auxdata;
|
val = packet_sock_flag(po, PACKET_SOCK_AUXDATA);
|
||||||
break;
|
break;
|
||||||
case PACKET_ORIGDEV:
|
case PACKET_ORIGDEV:
|
||||||
val = packet_sock_flag(po, PACKET_SOCK_ORIGDEV);
|
val = packet_sock_flag(po, PACKET_SOCK_ORIGDEV);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb)
|
|||||||
pinfo.pdi_flags = 0;
|
pinfo.pdi_flags = 0;
|
||||||
if (po->running)
|
if (po->running)
|
||||||
pinfo.pdi_flags |= PDI_RUNNING;
|
pinfo.pdi_flags |= PDI_RUNNING;
|
||||||
if (po->auxdata)
|
if (packet_sock_flag(po, PACKET_SOCK_AUXDATA))
|
||||||
pinfo.pdi_flags |= PDI_AUXDATA;
|
pinfo.pdi_flags |= PDI_AUXDATA;
|
||||||
if (packet_sock_flag(po, PACKET_SOCK_ORIGDEV))
|
if (packet_sock_flag(po, PACKET_SOCK_ORIGDEV))
|
||||||
pinfo.pdi_flags |= PDI_ORIGDEV;
|
pinfo.pdi_flags |= PDI_ORIGDEV;
|
||||||
|
|||||||
@@ -118,8 +118,7 @@ struct packet_sock {
|
|||||||
struct mutex pg_vec_lock;
|
struct mutex pg_vec_lock;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned int running; /* bind_lock must be held */
|
unsigned int running; /* bind_lock must be held */
|
||||||
unsigned int auxdata:1, /* writer must hold sock lock */
|
unsigned int has_vnet_hdr:1, /* writer must hold sock lock */
|
||||||
has_vnet_hdr:1,
|
|
||||||
tp_loss:1,
|
tp_loss:1,
|
||||||
tp_tx_has_off:1;
|
tp_tx_has_off:1;
|
||||||
int pressure;
|
int pressure;
|
||||||
@@ -146,6 +145,7 @@ static struct packet_sock *pkt_sk(struct sock *sk)
|
|||||||
|
|
||||||
enum packet_sock_flags {
|
enum packet_sock_flags {
|
||||||
PACKET_SOCK_ORIGDEV,
|
PACKET_SOCK_ORIGDEV,
|
||||||
|
PACKET_SOCK_AUXDATA,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void packet_sock_flag_set(struct packet_sock *po,
|
static inline void packet_sock_flag_set(struct packet_sock *po,
|
||||||
|
|||||||
Reference in New Issue
Block a user