]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net, pidfs: enable handing out pidfds for reaped sk->sk_peer_pid
authorChristian Brauner <brauner@kernel.org>
Fri, 25 Apr 2025 08:11:33 +0000 (10:11 +0200)
committerChristian Brauner <brauner@kernel.org>
Mon, 28 Apr 2025 09:04:43 +0000 (11:04 +0200)
Now that all preconditions are met, allow handing out pidfs for reaped
sk->sk_peer_pids.

Thanks to Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
for pointing out that we need to limit this to AF_UNIX sockets for now.

Link: https://lore.kernel.org/20250425-work-pidfs-net-v2-4-450a19461e75@kernel.org
Reviewed-by: David Rheinsberg <david@readahead.eu>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
net/core/sock.c

index b969d2210656473c1d77755ec337d59db90be247..180f441f4ab65aab2a929e6b0c5218febc3643c4 100644 (file)
 
 #include <linux/ethtool.h>
 
+#include <uapi/linux/pidfd.h>
+
 #include "dev.h"
 
 static DEFINE_MUTEX(proto_list_mutex);
@@ -1879,6 +1881,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
        {
                struct pid *peer_pid;
                struct file *pidfd_file = NULL;
+               unsigned int flags = 0;
                int pidfd;
 
                if (len > sizeof(pidfd))
@@ -1891,18 +1894,17 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
                if (!peer_pid)
                        return -ENODATA;
 
-               pidfd = pidfd_prepare(peer_pid, 0, &pidfd_file);
+               /* The use of PIDFD_STALE requires stashing of struct pid
+                * on pidfs with pidfs_register_pid() and only AF_UNIX
+                * were prepared for this.
+                */
+               if (sk->sk_family == AF_UNIX)
+                       flags = PIDFD_STALE;
+
+               pidfd = pidfd_prepare(peer_pid, flags, &pidfd_file);
                put_pid(peer_pid);
-               if (pidfd < 0) {
-                       /*
-                        * dbus-broker relies on -EINVAL being returned
-                        * to indicate ESRCH. Paper over it until this
-                        * is fixed in userspace.
-                        */
-                       if (pidfd == -ESRCH)
-                               pidfd = -EINVAL;
+               if (pidfd < 0)
                        return pidfd;
-               }
 
                if (copy_to_sockptr(optval, &pidfd, len) ||
                    copy_to_sockptr(optlen, &len, sizeof(int))) {