diff options
| author | Gabriel Krisman Bertazi <krisman@suse.de> | 2025-11-25 16:17:59 -0500 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2025-11-26 13:45:23 -0700 |
| commit | 4677e78800bbde62a9edce0eb3b40c775ec55e0d (patch) | |
| tree | a23b07bf6aed503561746a12f11744318c340d52 /net/socket.c | |
| parent | 1e93de9205b4d5c0f06507e9e1c398574a07fb80 (diff) | |
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>
Diffstat (limited to 'net/socket.c')
| -rw-r--r-- | net/socket.c | 55 |
1 files changed, 13 insertions, 42 deletions
diff --git a/net/socket.c b/net/socket.c index e8892b218708..208d92ccf0fb 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2128,12 +2128,11 @@ SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, } /* - * Get the local address ('name') of a socket object. Move the obtained - * name to user space. + * Get the remote or local address ('name') of a socket object. Move the + * obtained name to user space. */ - int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len) + int __user *usockaddr_len, int peer) { struct socket *sock; struct sockaddr_storage address; @@ -2146,11 +2145,14 @@ int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, if (unlikely(!sock)) return -ENOTSOCK; - err = security_socket_getsockname(sock); + if (peer) + err = security_socket_getpeername(sock); + else + err = security_socket_getsockname(sock); if (err) return err; - err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 0); + err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, peer); if (err < 0) return err; @@ -2161,44 +2163,13 @@ int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len) { - return __sys_getsockname(fd, usockaddr, usockaddr_len); -} - -/* - * Get the remote address ('name') of a socket object. Move the obtained - * name to user space. - */ - -int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len) -{ - struct socket *sock; - struct sockaddr_storage address; - CLASS(fd, f)(fd); - int err; - - if (fd_empty(f)) - return -EBADF; - sock = sock_from_file(fd_file(f)); - if (unlikely(!sock)) - return -ENOTSOCK; - - err = security_socket_getpeername(sock); - if (err) - return err; - - err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 1); - if (err < 0) - return err; - - /* "err" is actually length in this case */ - return move_addr_to_user(&address, err, usockaddr, usockaddr_len); + return __sys_getsockname(fd, usockaddr, usockaddr_len, 0); } SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len) { - return __sys_getpeername(fd, usockaddr, usockaddr_len); + return __sys_getsockname(fd, usockaddr, usockaddr_len, 1); } /* @@ -3162,12 +3133,12 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) case SYS_GETSOCKNAME: err = __sys_getsockname(a0, (struct sockaddr __user *)a1, - (int __user *)a[2]); + (int __user *)a[2], 0); break; case SYS_GETPEERNAME: err = - __sys_getpeername(a0, (struct sockaddr __user *)a1, - (int __user *)a[2]); + __sys_getsockname(a0, (struct sockaddr __user *)a1, + (int __user *)a[2], 1); break; case SYS_SOCKETPAIR: err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]); |