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

socket: Unify getsockname and getpeername implementation

They are already implemented by the same get_name hook in the protocol
level. Bring the unification one level up to reduce code duplication
in preparation to supporting these as io_uring operations.

Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Gabriel Krisman Bertazi and committed by
Jens Axboe
4677e788 1e93de92

+16 -47
+1 -3
include/linux/socket.h
··· 454 454 extern int __sys_listen(int fd, int backlog); 455 455 extern int __sys_listen_socket(struct socket *sock, int backlog); 456 456 extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, 457 - int __user *usockaddr_len); 458 - extern int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, 459 - int __user *usockaddr_len); 457 + int __user *usockaddr_len, int peer); 460 458 extern int __sys_socketpair(int family, int type, int protocol, 461 459 int __user *usockvec); 462 460 extern int __sys_shutdown_sock(struct socket *sock, int how);
+2 -2
net/compat.c
··· 460 460 ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0); 461 461 break; 462 462 case SYS_GETSOCKNAME: 463 - ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2])); 463 + ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]), 0); 464 464 break; 465 465 case SYS_GETPEERNAME: 466 - ret = __sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2])); 466 + ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]), 1); 467 467 break; 468 468 case SYS_SOCKETPAIR: 469 469 ret = __sys_socketpair(a0, a1, a[2], compat_ptr(a[3]));
+13 -42
net/socket.c
··· 2128 2128 } 2129 2129 2130 2130 /* 2131 - * Get the local address ('name') of a socket object. Move the obtained 2132 - * name to user space. 2131 + * Get the remote or local address ('name') of a socket object. Move the 2132 + * obtained name to user space. 2133 2133 */ 2134 - 2135 2134 int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, 2136 - int __user *usockaddr_len) 2135 + int __user *usockaddr_len, int peer) 2137 2136 { 2138 2137 struct socket *sock; 2139 2138 struct sockaddr_storage address; ··· 2145 2146 if (unlikely(!sock)) 2146 2147 return -ENOTSOCK; 2147 2148 2148 - err = security_socket_getsockname(sock); 2149 + if (peer) 2150 + err = security_socket_getpeername(sock); 2151 + else 2152 + err = security_socket_getsockname(sock); 2149 2153 if (err) 2150 2154 return err; 2151 2155 2152 - err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 0); 2156 + err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, peer); 2153 2157 if (err < 0) 2154 2158 return err; 2155 2159 ··· 2163 2161 SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, 2164 2162 int __user *, usockaddr_len) 2165 2163 { 2166 - return __sys_getsockname(fd, usockaddr, usockaddr_len); 2167 - } 2168 - 2169 - /* 2170 - * Get the remote address ('name') of a socket object. Move the obtained 2171 - * name to user space. 2172 - */ 2173 - 2174 - int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, 2175 - int __user *usockaddr_len) 2176 - { 2177 - struct socket *sock; 2178 - struct sockaddr_storage address; 2179 - CLASS(fd, f)(fd); 2180 - int err; 2181 - 2182 - if (fd_empty(f)) 2183 - return -EBADF; 2184 - sock = sock_from_file(fd_file(f)); 2185 - if (unlikely(!sock)) 2186 - return -ENOTSOCK; 2187 - 2188 - err = security_socket_getpeername(sock); 2189 - if (err) 2190 - return err; 2191 - 2192 - err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 1); 2193 - if (err < 0) 2194 - return err; 2195 - 2196 - /* "err" is actually length in this case */ 2197 - return move_addr_to_user(&address, err, usockaddr, usockaddr_len); 2164 + return __sys_getsockname(fd, usockaddr, usockaddr_len, 0); 2198 2165 } 2199 2166 2200 2167 SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, 2201 2168 int __user *, usockaddr_len) 2202 2169 { 2203 - return __sys_getpeername(fd, usockaddr, usockaddr_len); 2170 + return __sys_getsockname(fd, usockaddr, usockaddr_len, 1); 2204 2171 } 2205 2172 2206 2173 /* ··· 3133 3162 case SYS_GETSOCKNAME: 3134 3163 err = 3135 3164 __sys_getsockname(a0, (struct sockaddr __user *)a1, 3136 - (int __user *)a[2]); 3165 + (int __user *)a[2], 0); 3137 3166 break; 3138 3167 case SYS_GETPEERNAME: 3139 3168 err = 3140 - __sys_getpeername(a0, (struct sockaddr __user *)a1, 3141 - (int __user *)a[2]); 3169 + __sys_getsockname(a0, (struct sockaddr __user *)a1, 3170 + (int __user *)a[2], 1); 3142 3171 break; 3143 3172 case SYS_SOCKETPAIR: 3144 3173 err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]);