* [PATCH RESEND v2 0/3] Introduce getsockname io_uring_cmd
@ 2025-11-21 16:09 Gabriel Krisman Bertazi
2025-11-21 16:09 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Gabriel Krisman Bertazi @ 2025-11-21 16:09 UTC (permalink / raw)
To: Jens Axboe
Cc: Gabriel Krisman Bertazi, netdev, io-uring, Jakub Kicinski,
David S. Miller, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni,
Willem de Bruijn, Simon Horman
[Resending v2 because silly git-format-patch doesn't To from
the branch description, only Cc, so it was missing Jen]s.
Since V1:
- minor style fixes
- Resend with (more) maintainers cc'ed
- rebased to axboe/for-next.
--
This feature has been requested a few times in the liburing repository
and Discord channels, such as in [1,2]. If anything, it also helps
solve a long standing issue in the bind-listen test that results in
occasional test failures.
The patchset is divided in three parts: Patch 1 merges the getpeername
and getsockname implementation in the network layer, making further
patches easier; Patch 2 splits out a helper used by io_uring, like done
for other network commands; Finally, patch 3 plumbs the new command in
io_uring.
The syscall path was tested by booting a Linux distro, which does all
sorts of getsockname/getpeername syscalls. The io_uring side was tested
with a couple of new liburing subtests available at:
https://github.com/krisman/liburing.git -b socket
Based on top of Jens' for-next.
[1] https://github.com/axboe/liburing/issues/1356
[2] https://discord.com/channels/1241076672589991966/1241076672589991970/1429975797912830074
---
CC: netdev@vger.kernel.org
CC: io-uring@vger.kernel.org
CC: Jakub Kicinski <kuba@kernel.org>
CC: David S. Miller <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Kuniyuki Iwashima <kuniyu@google.com>
CC: Paolo Abeni <pabeni@redhat.com>
CC: Willem de Bruijn <willemb@google.com>
CC: Simon Horman <horms@kernel.org>
Gabriel Krisman Bertazi (3):
socket: Unify getsockname and getpeername implementation
socket: Split out a getsockname helper for io_uring
io_uring: Introduce getsockname io_uring cmd
include/linux/socket.h | 6 +--
include/uapi/linux/io_uring.h | 1 +
io_uring/cmd_net.c | 23 ++++++++++++
net/compat.c | 4 +-
net/socket.c | 69 +++++++++++------------------------
5 files changed, 51 insertions(+), 52 deletions(-)
--
2.51.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation 2025-11-21 16:09 [PATCH RESEND v2 0/3] Introduce getsockname io_uring_cmd Gabriel Krisman Bertazi @ 2025-11-21 16:09 ` Gabriel Krisman Bertazi 2025-11-22 1:20 ` Jakub Kicinski 2025-11-22 2:14 ` Kuniyuki Iwashima 2025-11-21 16:09 ` [PATCH v2 2/3] socket: Split out a getsockname helper for io_uring Gabriel Krisman Bertazi 2025-11-21 16:09 ` [PATCH v2 3/3] io_uring: Introduce getsockname io_uring cmd Gabriel Krisman Bertazi 2 siblings, 2 replies; 8+ messages in thread From: Gabriel Krisman Bertazi @ 2025-11-21 16:09 UTC (permalink / raw) To: Jens Axboe Cc: Gabriel Krisman Bertazi, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn, Simon Horman 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. Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> --- include/linux/socket.h | 4 +-- net/compat.c | 4 +-- net/socket.c | 55 ++++++++++-------------------------------- 3 files changed, 16 insertions(+), 47 deletions(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index 3b262487ec06..937fe331ff1e 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -454,9 +454,7 @@ extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, extern int __sys_listen(int fd, int backlog); extern int __sys_listen_socket(struct socket *sock, int backlog); extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len); -extern int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len); + int __user *usockaddr_len, int peer); extern int __sys_socketpair(int family, int type, int protocol, int __user *usockvec); extern int __sys_shutdown_sock(struct socket *sock, int how); diff --git a/net/compat.c b/net/compat.c index 485db8ee9b28..2c9bd0edac99 100644 --- a/net/compat.c +++ b/net/compat.c @@ -460,10 +460,10 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0); break; case SYS_GETSOCKNAME: - ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2])); + ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]), 0); break; case SYS_GETPEERNAME: - ret = __sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2])); + ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]), 1); break; case SYS_SOCKETPAIR: ret = __sys_socketpair(a0, a1, a[2], compat_ptr(a[3])); diff --git a/net/socket.c b/net/socket.c index e8892b218708..ee438b9425da 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 address (remote or local ('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]); -- 2.51.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation 2025-11-21 16:09 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi @ 2025-11-22 1:20 ` Jakub Kicinski 2025-11-22 2:14 ` Kuniyuki Iwashima 1 sibling, 0 replies; 8+ messages in thread From: Jakub Kicinski @ 2025-11-22 1:20 UTC (permalink / raw) To: Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn Cc: Gabriel Krisman Bertazi, Jens Axboe, netdev, io-uring, David S. Miller, Simon Horman On Fri, 21 Nov 2025 11:09:46 -0500 Gabriel Krisman Bertazi wrote: > include/linux/socket.h | 4 +-- > net/compat.c | 4 +-- > net/socket.c | 55 ++++++++++-------------------------------- socket layer maintainers, please review ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation 2025-11-21 16:09 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi 2025-11-22 1:20 ` Jakub Kicinski @ 2025-11-22 2:14 ` Kuniyuki Iwashima 1 sibling, 0 replies; 8+ messages in thread From: Kuniyuki Iwashima @ 2025-11-22 2:14 UTC (permalink / raw) To: Gabriel Krisman Bertazi Cc: Jens Axboe, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Paolo Abeni, Willem de Bruijn, Simon Horman On Fri, Nov 21, 2025 at 8:10 AM Gabriel Krisman Bertazi <krisman@suse.de> wrote: > > 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. > > Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> > --- > include/linux/socket.h | 4 +-- > net/compat.c | 4 +-- > net/socket.c | 55 ++++++++++-------------------------------- > 3 files changed, 16 insertions(+), 47 deletions(-) > > diff --git a/include/linux/socket.h b/include/linux/socket.h > index 3b262487ec06..937fe331ff1e 100644 > --- a/include/linux/socket.h > +++ b/include/linux/socket.h > @@ -454,9 +454,7 @@ extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, > extern int __sys_listen(int fd, int backlog); > extern int __sys_listen_socket(struct socket *sock, int backlog); > extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, > - int __user *usockaddr_len); > -extern int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, > - int __user *usockaddr_len); > + int __user *usockaddr_len, int peer); > extern int __sys_socketpair(int family, int type, int protocol, > int __user *usockvec); > extern int __sys_shutdown_sock(struct socket *sock, int how); > diff --git a/net/compat.c b/net/compat.c > index 485db8ee9b28..2c9bd0edac99 100644 > --- a/net/compat.c > +++ b/net/compat.c > @@ -460,10 +460,10 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) > ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0); > break; > case SYS_GETSOCKNAME: > - ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2])); > + ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]), 0); > break; > case SYS_GETPEERNAME: > - ret = __sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2])); > + ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]), 1); > break; > case SYS_SOCKETPAIR: > ret = __sys_socketpair(a0, a1, a[2], compat_ptr(a[3])); > diff --git a/net/socket.c b/net/socket.c > index e8892b218708..ee438b9425da 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 address (remote or local ('name')) of a socket object. Move the nit: Get the remote or local address ('name') Otherwise, looks good. Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> > + * 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]); > -- > 2.51.0 > ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 2/3] socket: Split out a getsockname helper for io_uring 2025-11-21 16:09 [PATCH RESEND v2 0/3] Introduce getsockname io_uring_cmd Gabriel Krisman Bertazi 2025-11-21 16:09 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi @ 2025-11-21 16:09 ` Gabriel Krisman Bertazi 2025-11-22 2:15 ` Kuniyuki Iwashima 2025-11-21 16:09 ` [PATCH v2 3/3] io_uring: Introduce getsockname io_uring cmd Gabriel Krisman Bertazi 2 siblings, 1 reply; 8+ messages in thread From: Gabriel Krisman Bertazi @ 2025-11-21 16:09 UTC (permalink / raw) To: Jens Axboe Cc: Gabriel Krisman Bertazi, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn, Simon Horman 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> --- include/linux/socket.h | 2 ++ net/socket.c | 34 +++++++++++++++++++--------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index 937fe331ff1e..5afb5ef2990c 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, struct sockaddr_storage *address, + 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 ee438b9425da..9c110b529cdd 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2127,6 +2127,24 @@ SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, return __sys_connect(fd, uservaddr, addrlen); } +int do_getsockname(struct socket *sock, struct sockaddr_storage *address, int peer, + struct sockaddr __user *usockaddr, int __user *usockaddr_len) +{ + int err; + + 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 address (remote or local ('name')) of a socket object. Move the * obtained name to user space. @@ -2137,27 +2155,13 @@ int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, 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); + return do_getsockname(sock, &address, peer, usockaddr, usockaddr_len); } SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, -- 2.51.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] socket: Split out a getsockname helper for io_uring 2025-11-21 16:09 ` [PATCH v2 2/3] socket: Split out a getsockname helper for io_uring Gabriel Krisman Bertazi @ 2025-11-22 2:15 ` Kuniyuki Iwashima 0 siblings, 0 replies; 8+ messages in thread From: Kuniyuki Iwashima @ 2025-11-22 2:15 UTC (permalink / raw) To: Gabriel Krisman Bertazi Cc: Jens Axboe, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Paolo Abeni, Willem de Bruijn, Simon Horman On Fri, Nov 21, 2025 at 8:10 AM Gabriel Krisman Bertazi <krisman@suse.de> wrote: > > 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> > --- > include/linux/socket.h | 2 ++ > net/socket.c | 34 +++++++++++++++++++--------------- > 2 files changed, 21 insertions(+), 15 deletions(-) > > diff --git a/include/linux/socket.h b/include/linux/socket.h > index 937fe331ff1e..5afb5ef2990c 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, struct sockaddr_storage *address, > + 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 ee438b9425da..9c110b529cdd 100644 > --- a/net/socket.c > +++ b/net/socket.c > @@ -2127,6 +2127,24 @@ SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, > return __sys_connect(fd, uservaddr, addrlen); > } > > +int do_getsockname(struct socket *sock, struct sockaddr_storage *address, int peer, > + struct sockaddr __user *usockaddr, int __user *usockaddr_len) > +{ > + int err; > + > + 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 address (remote or local ('name')) of a socket object. Move the > * obtained name to user space. > @@ -2137,27 +2155,13 @@ int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, > struct socket *sock; > struct sockaddr_storage address; Could you move this to do_getsockname() ? The patch 3 also does not need to define it. > 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); > + return do_getsockname(sock, &address, peer, usockaddr, usockaddr_len); > } > > SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, > -- > 2.51.0 > ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 3/3] io_uring: Introduce getsockname io_uring cmd 2025-11-21 16:09 [PATCH RESEND v2 0/3] Introduce getsockname io_uring_cmd Gabriel Krisman Bertazi 2025-11-21 16:09 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi 2025-11-21 16:09 ` [PATCH v2 2/3] socket: Split out a getsockname helper for io_uring Gabriel Krisman Bertazi @ 2025-11-21 16:09 ` Gabriel Krisman Bertazi 2 siblings, 0 replies; 8+ messages in thread From: Gabriel Krisman Bertazi @ 2025-11-21 16:09 UTC (permalink / raw) To: Jens Axboe Cc: Gabriel Krisman Bertazi, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn, Simon Horman Introduce a socket-specific io_uring_cmd to support getsockname/getpeername via io_uring. I made this an io_uring_cmd instead of a new operation to avoid polluting the command namespace with what is exclusively a socket operation. In addition, since we don't need to conform to existing interfaces, this merges the getsockname/getpeername in a single operation, since the implementation is pretty much the same. This has been frequently requested, for instance at [1] and more recently in the project Discord channel. The main use-case is to support fixed socket file descriptors. [1] https://github.com/axboe/liburing/issues/1356 Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> --- include/uapi/linux/io_uring.h | 1 + io_uring/cmd_net.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 3d921cbb84f8..6a97c5376019 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -1010,6 +1010,7 @@ enum io_uring_socket_op { SOCKET_URING_OP_GETSOCKOPT, SOCKET_URING_OP_SETSOCKOPT, SOCKET_URING_OP_TX_TIMESTAMP, + SOCKET_URING_OP_GETSOCKNAME, }; /* diff --git a/io_uring/cmd_net.c b/io_uring/cmd_net.c index 27a09aa4c9d0..90f58f883f62 100644 --- a/io_uring/cmd_net.c +++ b/io_uring/cmd_net.c @@ -132,6 +132,27 @@ static int io_uring_cmd_timestamp(struct socket *sock, return -EAGAIN; } +static int io_uring_cmd_getsockname(struct socket *sock, + struct io_uring_cmd *cmd, + unsigned int issue_flags) +{ + const struct io_uring_sqe *sqe = cmd->sqe; + struct sockaddr_storage address; + struct sockaddr __user *uaddr; + unsigned int peer; + int __user *ulen; + + if (sqe->ioprio || sqe->__pad1 || sqe->len || sqe->rw_flags) + return -EINVAL; + + uaddr = u64_to_user_ptr(READ_ONCE(sqe->addr)); + ulen = u64_to_user_ptr(sqe->addr3); + peer = READ_ONCE(sqe->optlen); + if (peer > 1) + return -EINVAL; + return do_getsockname(sock, &address, 0, uaddr, ulen); +} + int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags) { struct socket *sock = cmd->file->private_data; @@ -159,6 +180,8 @@ int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags) return io_uring_cmd_setsockopt(sock, cmd, issue_flags); case SOCKET_URING_OP_TX_TIMESTAMP: return io_uring_cmd_timestamp(sock, cmd, issue_flags); + case SOCKET_URING_OP_GETSOCKNAME: + return io_uring_cmd_getsockname(sock, cmd, issue_flags); default: return -EOPNOTSUPP; } -- 2.51.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 0/3] Introduce getsockname io_uring_cmd @ 2025-11-20 21:58 Gabriel Krisman Bertazi 2025-11-20 21:58 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi 0 siblings, 1 reply; 8+ messages in thread From: Gabriel Krisman Bertazi @ 2025-11-20 21:58 UTC (permalink / raw) Cc: Gabriel Krisman Bertazi, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn, Simon Horman Since V1: - minor style fixes - Resend with (more) maintainers cc'ed - rebased to axboe/for-next. -- This feature has been requested a few times in the liburing repository and Discord channels, such as in [1,2]. If anything, it also helps solve a long standing issue in the bind-listen test that results in occasional test failures. The patchset is divided in three parts: Patch 1 merges the getpeername and getsockname implementation in the network layer, making further patches easier; Patch 2 splits out a helper used by io_uring, like done for other network commands; Finally, patch 3 plumbs the new command in io_uring. The syscall path was tested by booting a Linux distro, which does all sorts of getsockname/getpeername syscalls. The io_uring side was tested with a couple of new liburing subtests available at: https://github.com/krisman/liburing.git -b socket Based on top of Jens' for-next. [1] https://github.com/axboe/liburing/issues/1356 [2] https://discord.com/channels/1241076672589991966/1241076672589991970/1429975797912830074 --- To: Jens Axboe <axboe@kernel.dk> CC: netdev@vger.kernel.org CC: io-uring@vger.kernel.org CC: Jakub Kicinski <kuba@kernel.org> CC: David S. Miller <davem@davemloft.net> CC: Eric Dumazet <edumazet@google.com> CC: Kuniyuki Iwashima <kuniyu@google.com> CC: Paolo Abeni <pabeni@redhat.com> CC: Willem de Bruijn <willemb@google.com> CC: Simon Horman <horms@kernel.org> Base: axboe/for-next Gabriel Krisman Bertazi (3): socket: Unify getsockname and getpeername implementation socket: Split out a getsockname helper for io_uring io_uring: Introduce getsockname io_uring cmd include/linux/socket.h | 6 +-- include/uapi/linux/io_uring.h | 1 + io_uring/cmd_net.c | 23 ++++++++++++ net/compat.c | 4 +- net/socket.c | 69 +++++++++++------------------------ 5 files changed, 51 insertions(+), 52 deletions(-) -- 2.51.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation 2025-11-20 21:58 [PATCH v2 0/3] Introduce getsockname io_uring_cmd Gabriel Krisman Bertazi @ 2025-11-20 21:58 ` Gabriel Krisman Bertazi 0 siblings, 0 replies; 8+ messages in thread From: Gabriel Krisman Bertazi @ 2025-11-20 21:58 UTC (permalink / raw) Cc: Gabriel Krisman Bertazi, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn, Simon Horman 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. Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> --- include/linux/socket.h | 4 +-- net/compat.c | 4 +-- net/socket.c | 55 ++++++++++-------------------------------- 3 files changed, 16 insertions(+), 47 deletions(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index 3b262487ec06..937fe331ff1e 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -454,9 +454,7 @@ extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, extern int __sys_listen(int fd, int backlog); extern int __sys_listen_socket(struct socket *sock, int backlog); extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len); -extern int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len); + int __user *usockaddr_len, int peer); extern int __sys_socketpair(int family, int type, int protocol, int __user *usockvec); extern int __sys_shutdown_sock(struct socket *sock, int how); diff --git a/net/compat.c b/net/compat.c index 485db8ee9b28..2c9bd0edac99 100644 --- a/net/compat.c +++ b/net/compat.c @@ -460,10 +460,10 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0); break; case SYS_GETSOCKNAME: - ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2])); + ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]), 0); break; case SYS_GETPEERNAME: - ret = __sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2])); + ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]), 1); break; case SYS_SOCKETPAIR: ret = __sys_socketpair(a0, a1, a[2], compat_ptr(a[3])); diff --git a/net/socket.c b/net/socket.c index e8892b218708..ee438b9425da 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 address (remote or local ('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]); -- 2.51.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-11-22 2:16 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-11-21 16:09 [PATCH RESEND v2 0/3] Introduce getsockname io_uring_cmd Gabriel Krisman Bertazi 2025-11-21 16:09 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi 2025-11-22 1:20 ` Jakub Kicinski 2025-11-22 2:14 ` Kuniyuki Iwashima 2025-11-21 16:09 ` [PATCH v2 2/3] socket: Split out a getsockname helper for io_uring Gabriel Krisman Bertazi 2025-11-22 2:15 ` Kuniyuki Iwashima 2025-11-21 16:09 ` [PATCH v2 3/3] io_uring: Introduce getsockname io_uring cmd Gabriel Krisman Bertazi -- strict thread matches above, loose matches on Subject: below -- 2025-11-20 21:58 [PATCH v2 0/3] Introduce getsockname io_uring_cmd Gabriel Krisman Bertazi 2025-11-20 21:58 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.