diff options
| author | Gabriel Krisman Bertazi <krisman@suse.de> | 2025-11-25 16:18:00 -0500 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2025-11-26 13:45:23 -0700 |
| commit | d73c1677087391379441c0bb444c7fb4238fc6e7 (patch) | |
| tree | 3bb53e13414721e63e652624596d06386358f868 | |
| parent | 4677e78800bbde62a9edce0eb3b40c775ec55e0d (diff) | |
socket: Split out a getsockname helper for io_uring
Similar to getsockopt, split out a helper to check security and issue
the operation from the main handler that can be used by io_uring.
Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
| -rw-r--r-- | include/linux/socket.h | 2 | ||||
| -rw-r--r-- | net/socket.c | 36 |
2 files changed, 22 insertions, 16 deletions
diff --git a/include/linux/socket.h b/include/linux/socket.h index 937fe331ff1e..8d580074ddea 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -453,6 +453,8 @@ extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen); extern int __sys_listen(int fd, int backlog); extern int __sys_listen_socket(struct socket *sock, int backlog); +extern int do_getsockname(struct socket *sock, int peer, + struct sockaddr __user *usockaddr, int __user *usockaddr_len); extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len, int peer); extern int __sys_socketpair(int family, int type, int protocol, diff --git a/net/socket.c b/net/socket.c index 208d92ccf0fb..89bac0a17e5a 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2127,39 +2127,43 @@ SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, return __sys_connect(fd, uservaddr, addrlen); } -/* - * 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 peer) +int do_getsockname(struct socket *sock, int peer, + 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; - 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, peer); if (err < 0) return err; - /* "err" is actually length in this case */ return move_addr_to_user(&address, err, usockaddr, usockaddr_len); } +/* + * 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 peer) +{ + struct socket *sock; + CLASS(fd, f)(fd); + + if (fd_empty(f)) + return -EBADF; + sock = sock_from_file(fd_file(f)); + if (unlikely(!sock)) + return -ENOTSOCK; + return do_getsockname(sock, peer, usockaddr, usockaddr_len); +} + SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len) { |
