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.9-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.9 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit ba5c6a7c20e9109378e787b954a8f3efeb0dade3 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 07f0f698c9490..ba863dfc95e1f 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -70,6 +70,7 @@ struct unix_sock { struct path path; struct mutex iolock, bindlock; struct sock *peer; + struct sock *listener; struct unix_vertex *vertex; struct list_head link; unsigned long inflight; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 4100541c8c00f..a1938ba24a696 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -973,6 +973,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->vertex = NULL; u->path.dentry = NULL; @@ -1601,6 +1602,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); @@ -1696,8 +1698,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; @@ -1722,6 +1724,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);