Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e402d51 authored by Eric Dumazet's avatar Eric Dumazet Committed by Greg Kroah-Hartman
Browse files

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: 8dc41944 ("[PACKET]: Add optional checksum computation for recvmsg")
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent f3ac72c7
Loading
Loading
Loading
Loading
+3 −5
Original line number Original line Diff line number Diff line
@@ -3456,7 +3456,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;
@@ -3839,9 +3839,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
		if (copy_from_user(&val, optval, sizeof(val)))
		if (copy_from_user(&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:
@@ -4002,7 +4000,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);
+1 −1
Original line number Original line Diff line number Diff line
@@ -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;
+2 −2
Original line number Original line Diff line number Diff line
@@ -117,8 +117,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;
@@ -145,6 +144,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,