This is a note to let you know that I've just added the patch titled af_unix: annotate lockless accesses to sk->sk_err to the 5.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: af_unix-annotate-lockless-accesses-to-sk-sk_err.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit d67e0043413caa1b66c8d9bb708330ddeebf7fa3 Author: Eric Dumazet <edumazet@xxxxxxxxxx> Date: Wed Mar 15 20:57:46 2023 +0000 af_unix: annotate lockless accesses to sk->sk_err [ Upstream commit cc04410af7de348234ac36a5f50c4ce416efdb4b ] unix_poll() and unix_dgram_poll() read sk->sk_err without any lock held. Add relevant READ_ONCE()/WRITE_ONCE() annotations. Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx> Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx> Stable-dep-of: 83690b82d228 ("af_unix: Use skb_queue_empty_lockless() in unix_release_sock().") Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 3fa86d70467c2..85b1c0d7c287a 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -500,7 +500,7 @@ static void unix_dgram_disconnected(struct sock *sk, struct sock *other) * when peer was not connected to us. */ if (!sock_flag(other, SOCK_DEAD) && unix_peer(other) == sk) { - other->sk_err = ECONNRESET; + WRITE_ONCE(other->sk_err, ECONNRESET); sk_error_report(other); } } @@ -571,7 +571,7 @@ static void unix_release_sock(struct sock *sk, int embrion) /* No more writes */ WRITE_ONCE(skpair->sk_shutdown, SHUTDOWN_MASK); if (!skb_queue_empty(&sk->sk_receive_queue) || embrion) - skpair->sk_err = ECONNRESET; + WRITE_ONCE(skpair->sk_err, ECONNRESET); unix_state_unlock(skpair); skpair->sk_state_change(skpair); sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP); @@ -3108,7 +3108,7 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa state = READ_ONCE(sk->sk_state); /* exceptional events? */ - if (sk->sk_err) + if (READ_ONCE(sk->sk_err)) mask |= EPOLLERR; if (shutdown == SHUTDOWN_MASK) mask |= EPOLLHUP; @@ -3155,7 +3155,8 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock, state = READ_ONCE(sk->sk_state); /* exceptional events? */ - if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue)) + if (READ_ONCE(sk->sk_err) || + !skb_queue_empty_lockless(&sk->sk_error_queue)) mask |= EPOLLERR | (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);