Add a helper that connects an existing socket while invoking the LSM hook. Reuse it in __sys_connect_file() to avoid duplicating the connect logic. Other socket operations have equivalent helpers that trigger the appropriate LSM hooks that can be reused, this one was the only one missing. This will be used in the next commit for a new BPF kfunc that needs to connect a socket and trigger the LSM hook. Acked-by: Song Liu Acked-by: Stanislav Fomichev Reviewed-by: Jiayuan Chen Reviewed-by: Kuniyuki Iwashima Signed-off-by: Mahe Tardy --- include/linux/socket.h | 2 ++ net/socket.c | 32 ++++++++++++++++++-------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index 2a8d7b14f1d1..5a5eb1250103 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -461,6 +461,8 @@ extern struct file *__sys_socket_file(int family, int type, int protocol); extern int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen); extern int __sys_bind_socket(struct socket *sock, struct sockaddr_storage *address, int addrlen); +int connect_socket(struct socket *sock, struct sockaddr_storage *addr, + int addrlen, int flags); extern int __sys_connect_file(struct file *file, struct sockaddr_storage *addr, int addrlen, int file_flags); extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, diff --git a/net/socket.c b/net/socket.c index 63c69a0fa74e..5b02e6217c68 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2103,6 +2103,20 @@ SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr, return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0); } +int connect_socket(struct socket *sock, struct sockaddr_storage *address, + int addrlen, int flags) +{ + int err; + + err = security_socket_connect(sock, (struct sockaddr *)address, + addrlen); + if (err) + return err; + + return READ_ONCE(sock->ops)->connect(sock, (struct sockaddr_unsized *)address, + addrlen, flags); +} + /* * Attempt to connect to a socket with the server address. The address * is in user space so we verify it is OK and move it to kernel space. @@ -2119,23 +2133,13 @@ int __sys_connect_file(struct file *file, struct sockaddr_storage *address, int addrlen, int file_flags) { struct socket *sock; - int err; sock = sock_from_file(file); - if (!sock) { - err = -ENOTSOCK; - goto out; - } - - err = - security_socket_connect(sock, (struct sockaddr *)address, addrlen); - if (err) - goto out; + if (!sock) + return -ENOTSOCK; - err = READ_ONCE(sock->ops)->connect(sock, (struct sockaddr_unsized *)address, - addrlen, sock->file->f_flags | file_flags); -out: - return err; + return connect_socket(sock, address, addrlen, + sock->file->f_flags | file_flags); } int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen) -- 2.34.1