Skip to content

Commit 4677e78

Browse files
krismanaxboe
authored andcommitted
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>
1 parent 1e93de9 commit 4677e78

3 files changed

Lines changed: 16 additions & 47 deletions

File tree

include/linux/socket.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -454,9 +454,7 @@ extern int __sys_connect(int fd, struct sockaddr __user *uservaddr,
454454
extern int __sys_listen(int fd, int backlog);
455455
extern int __sys_listen_socket(struct socket *sock, int backlog);
456456
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);
460458
extern int __sys_socketpair(int family, int type, int protocol,
461459
int __user *usockvec);
462460
extern int __sys_shutdown_sock(struct socket *sock, int how);

net/compat.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,10 +460,10 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args)
460460
ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0);
461461
break;
462462
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);
464464
break;
465465
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);
467467
break;
468468
case SYS_SOCKETPAIR:
469469
ret = __sys_socketpair(a0, a1, a[2], compat_ptr(a[3]));

net/socket.c

Lines changed: 13 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,12 +2128,11 @@ SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
21282128
}
21292129

21302130
/*
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.
21332133
*/
2134-
21352134
int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
2136-
int __user *usockaddr_len)
2135+
int __user *usockaddr_len, int peer)
21372136
{
21382137
struct socket *sock;
21392138
struct sockaddr_storage address;
@@ -2146,11 +2145,14 @@ int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
21462145
if (unlikely(!sock))
21472146
return -ENOTSOCK;
21482147

2149-
err = security_socket_getsockname(sock);
2148+
if (peer)
2149+
err = security_socket_getpeername(sock);
2150+
else
2151+
err = security_socket_getsockname(sock);
21502152
if (err)
21512153
return err;
21522154

2153-
err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 0);
2155+
err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, peer);
21542156
if (err < 0)
21552157
return err;
21562158

@@ -2161,44 +2163,13 @@ int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
21612163
SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
21622164
int __user *, usockaddr_len)
21632165
{
2164-
return __sys_getsockname(fd, usockaddr, usockaddr_len);
2165-
}
2166-
2167-
/*
2168-
* Get the remote address ('name') of a socket object. Move the obtained
2169-
* name to user space.
2170-
*/
2171-
2172-
int __sys_getpeername(int fd, struct sockaddr __user *usockaddr,
2173-
int __user *usockaddr_len)
2174-
{
2175-
struct socket *sock;
2176-
struct sockaddr_storage address;
2177-
CLASS(fd, f)(fd);
2178-
int err;
2179-
2180-
if (fd_empty(f))
2181-
return -EBADF;
2182-
sock = sock_from_file(fd_file(f));
2183-
if (unlikely(!sock))
2184-
return -ENOTSOCK;
2185-
2186-
err = security_socket_getpeername(sock);
2187-
if (err)
2188-
return err;
2189-
2190-
err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 1);
2191-
if (err < 0)
2192-
return err;
2193-
2194-
/* "err" is actually length in this case */
2195-
return move_addr_to_user(&address, err, usockaddr, usockaddr_len);
2166+
return __sys_getsockname(fd, usockaddr, usockaddr_len, 0);
21962167
}
21972168

21982169
SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
21992170
int __user *, usockaddr_len)
22002171
{
2201-
return __sys_getpeername(fd, usockaddr, usockaddr_len);
2172+
return __sys_getsockname(fd, usockaddr, usockaddr_len, 1);
22022173
}
22032174

22042175
/*
@@ -3162,12 +3133,12 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
31623133
case SYS_GETSOCKNAME:
31633134
err =
31643135
__sys_getsockname(a0, (struct sockaddr __user *)a1,
3165-
(int __user *)a[2]);
3136+
(int __user *)a[2], 0);
31663137
break;
31673138
case SYS_GETPEERNAME:
31683139
err =
3169-
__sys_getpeername(a0, (struct sockaddr __user *)a1,
3170-
(int __user *)a[2]);
3140+
__sys_getsockname(a0, (struct sockaddr __user *)a1,
3141+
(int __user *)a[2], 1);
31713142
break;
31723143
case SYS_SOCKETPAIR:
31733144
err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]);

0 commit comments

Comments
 (0)