af_unix: Save listener for embryo socket.
authorKuniyuki Iwashima <kuniyu@amazon.com>
Mon, 25 Mar 2024 20:24:17 +0000 (13:24 -0700)
committerJakub Kicinski <kuba@kernel.org>
Fri, 29 Mar 2024 15:28:10 +0000 (08:28 -0700)
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@amazon.com>
Acked-by: Paolo Abeni <pabeni@redhat.com>
Link: https://lore.kernel.org/r/20240325202425.60930-8-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/af_unix.h
net/unix/af_unix.c

index 67736767b616839579061beb61f9d9b1887b7a6f..dc74691911957fd2365122a9de213fb75cf9db12 100644 (file)
@@ -83,6 +83,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;
index 24adbc4d518868449159fb935a58d79283a00125..af74e7ebc35a05a37b45ccbff98f347f8050582b 100644 (file)
@@ -979,6 +979,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern,
        sk->sk_max_ack_backlog  = 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;
@@ -1598,6 +1599,7 @@ restart:
        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);
 
@@ -1693,8 +1695,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;
@@ -1719,6 +1721,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);