Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: core: add getsockopt SO_PEERPIDFD

Add SO_PEERPIDFD which allows to get pidfd of peer socket holder pidfd.
This thing is direct analog of SO_PEERCRED which allows to get plain PID.

Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: David Ahern <dsahern@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kees Cook <keescook@chromium.org>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Kuniyuki Iwashima <kuniyu@amazon.com>
Cc: Lennart Poettering <mzxreary@0pointer.de>
Cc: Luca Boccassi <bluca@debian.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Stanislav Fomichev <sdf@google.com>
Cc: bpf@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: linux-arch@vger.kernel.org
Reviewed-by: Christian Brauner <brauner@kernel.org>
Acked-by: Stanislav Fomichev <sdf@google.com>
Tested-by: Luca Boccassi <bluca@debian.org>
Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Alexander Mikhalitsyn and committed by
David S. Miller
7b26952a 5e2ff670

+55
+1
arch/alpha/include/uapi/asm/socket.h
··· 138 138 #define SO_RCVMARK 75 139 139 140 140 #define SO_PASSPIDFD 76 141 + #define SO_PEERPIDFD 77 141 142 142 143 #if !defined(__KERNEL__) 143 144
+1
arch/mips/include/uapi/asm/socket.h
··· 149 149 #define SO_RCVMARK 75 150 150 151 151 #define SO_PASSPIDFD 76 152 + #define SO_PEERPIDFD 77 152 153 153 154 #if !defined(__KERNEL__) 154 155
+1
arch/parisc/include/uapi/asm/socket.h
··· 130 130 #define SO_RCVMARK 0x4049 131 131 132 132 #define SO_PASSPIDFD 0x404A 133 + #define SO_PEERPIDFD 0x404B 133 134 134 135 #if !defined(__KERNEL__) 135 136
+1
arch/sparc/include/uapi/asm/socket.h
··· 131 131 #define SO_RCVMARK 0x0054 132 132 133 133 #define SO_PASSPIDFD 0x0055 134 + #define SO_PEERPIDFD 0x0056 134 135 135 136 #if !defined(__KERNEL__) 136 137
+1
include/uapi/asm-generic/socket.h
··· 133 133 #define SO_RCVMARK 75 134 134 135 135 #define SO_PASSPIDFD 76 136 + #define SO_PEERPIDFD 77 136 137 137 138 #if !defined(__KERNEL__) 138 139
+33
net/core/sock.c
··· 1758 1758 goto lenout; 1759 1759 } 1760 1760 1761 + case SO_PEERPIDFD: 1762 + { 1763 + struct pid *peer_pid; 1764 + struct file *pidfd_file = NULL; 1765 + int pidfd; 1766 + 1767 + if (len > sizeof(pidfd)) 1768 + len = sizeof(pidfd); 1769 + 1770 + spin_lock(&sk->sk_peer_lock); 1771 + peer_pid = get_pid(sk->sk_peer_pid); 1772 + spin_unlock(&sk->sk_peer_lock); 1773 + 1774 + if (!peer_pid) 1775 + return -ESRCH; 1776 + 1777 + pidfd = pidfd_prepare(peer_pid, 0, &pidfd_file); 1778 + put_pid(peer_pid); 1779 + if (pidfd < 0) 1780 + return pidfd; 1781 + 1782 + if (copy_to_sockptr(optval, &pidfd, len) || 1783 + copy_to_sockptr(optlen, &len, sizeof(int))) { 1784 + put_unused_fd(pidfd); 1785 + fput(pidfd_file); 1786 + 1787 + return -EFAULT; 1788 + } 1789 + 1790 + fd_install(pidfd, pidfd_file); 1791 + return 0; 1792 + } 1793 + 1761 1794 case SO_PEERGROUPS: 1762 1795 { 1763 1796 const struct cred *cred;
+16
net/unix/af_unix.c
··· 921 921 */ 922 922 } 923 923 924 + static bool unix_bpf_bypass_getsockopt(int level, int optname) 925 + { 926 + if (level == SOL_SOCKET) { 927 + switch (optname) { 928 + case SO_PEERPIDFD: 929 + return true; 930 + default: 931 + return false; 932 + } 933 + } 934 + 935 + return false; 936 + } 937 + 924 938 struct proto unix_dgram_proto = { 925 939 .name = "UNIX", 926 940 .owner = THIS_MODULE, 927 941 .obj_size = sizeof(struct unix_sock), 928 942 .close = unix_close, 943 + .bpf_bypass_getsockopt = unix_bpf_bypass_getsockopt, 929 944 #ifdef CONFIG_BPF_SYSCALL 930 945 .psock_update_sk_prot = unix_dgram_bpf_update_proto, 931 946 #endif ··· 952 937 .obj_size = sizeof(struct unix_sock), 953 938 .close = unix_close, 954 939 .unhash = unix_unhash, 940 + .bpf_bypass_getsockopt = unix_bpf_bypass_getsockopt, 955 941 #ifdef CONFIG_BPF_SYSCALL 956 942 .psock_update_sk_prot = unix_stream_bpf_update_proto, 957 943 #endif
+1
tools/include/uapi/asm-generic/socket.h
··· 122 122 #define SO_RCVMARK 75 123 123 124 124 #define SO_PASSPIDFD 76 125 + #define SO_PEERPIDFD 77 125 126 126 127 #if !defined(__KERNEL__) 127 128