diff options
-rw-r--r-- | net/core/sock.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index b969d2210656..180f441f4ab6 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -148,6 +148,8 @@ #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))) { |