This is a note to let you know that I've just added the patch titled af_unix: Save listener for embryo socket. to the 6.6-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-save-listener-for-embryo-socket.patch and it can be found in the queue-6.6 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit 85705757f4b5b569af40f4a66f9a4308ea950651 Author: Kuniyuki Iwashima <kuniyu@xxxxxxxxxx> Date: Mon Mar 25 13:24:17 2024 -0700 af_unix: Save listener for embryo socket. [ Upstream commit aed6ecef55d70de3762ce41c561b7f547dbaf107 ] This is a prep patch for the following change, where we need to fetch the listening socket from the successor embryo socket during GC. We add a new field to struct unix_sock to save a pointer to a listening socket. We set it when connect() creates a new socket, and clear it when accept() is called. Signed-off-by: Kuniyuki Iwashima <kuniyu@xxxxxxxxxx> Acked-by: Paolo Abeni <pabeni@xxxxxxxxxx> Link: https://lore.kernel.org/r/20240325202425.60930-8-kuniyu@xxxxxxxxxx Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx> Stable-dep-of: 1b536948e805 ("af_unix: Annotate data-race of sk->sk_state in unix_accept().") Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 865e2f7bd67cf..1aa30778d2c05 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -62,6 +62,7 @@ struct unix_sock { struct path path; struct mutex iolock, bindlock; struct sock *peer; + struct sock *listener; struct list_head link; unsigned long inflight; spinlock_t lock; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 868f5332566c7..9d48eef5d62e3 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -987,6 +987,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, sk->sk_max_ack_backlog = READ_ONCE(net->unx.sysctl_max_dgram_qlen); sk->sk_destruct = unix_sock_destructor; u = unix_sk(sk); + u->listener = NULL; u->inflight = 0; u->path.dentry = NULL; u->path.mnt = NULL; @@ -1606,6 +1607,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, newsk->sk_type = sk->sk_type; init_peercred(newsk); newu = unix_sk(newsk); + newu->listener = other; RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq); otheru = unix_sk(other); @@ -1701,8 +1703,8 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags, bool kern) { struct sock *sk = sock->sk; - struct sock *tsk; struct sk_buff *skb; + struct sock *tsk; int err; err = -EOPNOTSUPP; @@ -1727,6 +1729,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags, } tsk = skb->sk; + unix_sk(tsk)->listener = NULL; skb_free_datagram(sk, skb); wake_up_interruptible(&unix_sk(sk)->peer_wait);