From 7a09e1eb9c1e5179797e0f3341ba7315c7626a0c Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 19:10:06 +0100 Subject: net: socket: add __sys_recvfrom() helper; remove in-kernel call to syscall Using the net-internal helper __sys_recvfrom() allows us to avoid the internal calls to the sys_recvfrom() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- net/socket.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'net/socket.c') diff --git a/net/socket.c b/net/socket.c index a93c99b518ca..712d99d8680f 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1767,10 +1767,8 @@ SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len, * sender. We verify the buffers are writable and if needed move the * sender address from kernel to user space. */ - -SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, - unsigned int, flags, struct sockaddr __user *, addr, - int __user *, addr_len) +int __sys_recvfrom(int fd, void __user *ubuf, size_t size, unsigned int flags, + struct sockaddr __user *addr, int __user *addr_len) { struct socket *sock; struct iovec iov; @@ -1810,6 +1808,13 @@ out: return err; } +SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, + unsigned int, flags, struct sockaddr __user *, addr, + int __user *, addr_len) +{ + return __sys_recvfrom(fd, ubuf, size, flags, addr, addr_len); +} + /* * Receive a datagram from a socket. */ @@ -1817,7 +1822,7 @@ out: SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size, unsigned int, flags) { - return sys_recvfrom(fd, ubuf, size, flags, NULL, NULL); + return __sys_recvfrom(fd, ubuf, size, flags, NULL, NULL); } /* @@ -2486,9 +2491,9 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) err = sys_recv(a0, (void __user *)a1, a[2], a[3]); break; case SYS_RECVFROM: - err = sys_recvfrom(a0, (void __user *)a1, a[2], a[3], - (struct sockaddr __user *)a[4], - (int __user *)a[5]); + err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3], + (struct sockaddr __user *)a[4], + (int __user *)a[5]); break; case SYS_SHUTDOWN: err = sys_shutdown(a0, a1); -- cgit v1.2.3 From 211b634b7f1ebc3436d5e8a34810a8eaa1f269d9 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 19:18:52 +0100 Subject: net: socket: add __sys_sendto() helper; remove in-kernel call to syscall Using the net-internal helper __sys_sendto() allows us to avoid the internal calls to the sys_sendto() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- include/linux/socket.h | 3 +++ net/compat.c | 3 ++- net/socket.c | 19 ++++++++++++------- 3 files changed, 17 insertions(+), 8 deletions(-) (limited to 'net/socket.c') diff --git a/include/linux/socket.h b/include/linux/socket.h index 40cc93b91628..54b85abc7265 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -358,5 +358,8 @@ extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size, unsigned int flags, struct sockaddr __user *addr, int __user *addr_len); +extern int __sys_sendto(int fd, void __user *buff, size_t len, + unsigned int flags, struct sockaddr __user *addr, + int addr_len); #endif /* _LINUX_SOCKET_H */ diff --git a/net/compat.c b/net/compat.c index 2d8186c277b2..fc82982d9b84 100644 --- a/net/compat.c +++ b/net/compat.c @@ -838,7 +838,8 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) ret = sys_send(a0, compat_ptr(a1), a[2], a[3]); break; case SYS_SENDTO: - ret = sys_sendto(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), a[5]); + ret = __sys_sendto(a0, compat_ptr(a1), a[2], a[3], + compat_ptr(a[4]), a[5]); break; case SYS_RECV: ret = compat_sys_recv(a0, compat_ptr(a1), a[2], a[3]); diff --git a/net/socket.c b/net/socket.c index 712d99d8680f..3f037a21ba5e 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1711,10 +1711,8 @@ SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, * space and check the user space data area is readable before invoking * the protocol. */ - -SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, - unsigned int, flags, struct sockaddr __user *, addr, - int, addr_len) +int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags, + struct sockaddr __user *addr, int addr_len) { struct socket *sock; struct sockaddr_storage address; @@ -1752,6 +1750,13 @@ out: return err; } +SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, + unsigned int, flags, struct sockaddr __user *, addr, + int, addr_len) +{ + return __sys_sendto(fd, buff, len, flags, addr, addr_len); +} + /* * Send a datagram down a socket. */ @@ -1759,7 +1764,7 @@ out: SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len, unsigned int, flags) { - return sys_sendto(fd, buff, len, flags, NULL, 0); + return __sys_sendto(fd, buff, len, flags, NULL, 0); } /* @@ -2484,8 +2489,8 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) err = sys_send(a0, (void __user *)a1, a[2], a[3]); break; case SYS_SENDTO: - err = sys_sendto(a0, (void __user *)a1, a[2], a[3], - (struct sockaddr __user *)a[4], a[5]); + err = __sys_sendto(a0, (void __user *)a1, a[2], a[3], + (struct sockaddr __user *)a[4], a[5]); break; case SYS_RECV: err = sys_recv(a0, (void __user *)a1, a[2], a[3]); -- cgit v1.2.3 From 4541e80560ca56d63348f40f2e34b044a5eb3dd7 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 19:24:23 +0100 Subject: net: socket: add __sys_accept4() helper; remove in-kernel call to syscall Using the net-internal helper __sys_accept4() allows us to avoid the internal calls to the sys_accept4() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- include/linux/socket.h | 2 ++ net/compat.c | 4 ++-- net/socket.c | 20 +++++++++++++------- 3 files changed, 17 insertions(+), 9 deletions(-) (limited to 'net/socket.c') diff --git a/include/linux/socket.h b/include/linux/socket.h index 54b85abc7265..6a9840271676 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -361,5 +361,7 @@ extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size, extern int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags, struct sockaddr __user *addr, int addr_len); +extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, + int __user *upeer_addrlen, int flags); #endif /* _LINUX_SOCKET_H */ diff --git a/net/compat.c b/net/compat.c index fc82982d9b84..0ff9f7451b6f 100644 --- a/net/compat.c +++ b/net/compat.c @@ -823,7 +823,7 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) ret = sys_listen(a0, a1); break; case SYS_ACCEPT: - ret = sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0); + 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])); @@ -873,7 +873,7 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) compat_ptr(a[4])); break; case SYS_ACCEPT4: - ret = sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), a[3]); + ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), a[3]); break; default: ret = -EINVAL; diff --git a/net/socket.c b/net/socket.c index 3f037a21ba5e..45f6ea0d57a5 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1519,8 +1519,8 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog) * clean when we restucture accept also. */ -SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, - int __user *, upeer_addrlen, int, flags) +int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, + int __user *upeer_addrlen, int flags) { struct socket *sock, *newsock; struct file *newfile; @@ -1599,10 +1599,16 @@ out_fd: goto out_put; } +SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, + int __user *, upeer_addrlen, int, flags) +{ + return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, flags); +} + SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr, int __user *, upeer_addrlen) { - return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0); + return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0); } /* @@ -2469,8 +2475,8 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) err = sys_listen(a0, a1); break; case SYS_ACCEPT: - err = sys_accept4(a0, (struct sockaddr __user *)a1, - (int __user *)a[2], 0); + err = __sys_accept4(a0, (struct sockaddr __user *)a1, + (int __user *)a[2], 0); break; case SYS_GETSOCKNAME: err = @@ -2525,8 +2531,8 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) (struct timespec __user *)a[4]); break; case SYS_ACCEPT4: - err = sys_accept4(a0, (struct sockaddr __user *)a1, - (int __user *)a[2], a[3]); + err = __sys_accept4(a0, (struct sockaddr __user *)a1, + (int __user *)a[2], a[3]); break; default: err = -EINVAL; -- cgit v1.2.3 From 9d6a15c3f23bcf0b0e6c6efd7d19f52d960a8697 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 19:29:43 +0100 Subject: net: socket: add __sys_socket() helper; remove in-kernel call to syscall Using the net-internal helper __sys_socket() allows us to avoid the internal calls to the sys_socket() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- include/linux/socket.h | 1 + net/compat.c | 2 +- net/socket.c | 9 +++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'net/socket.c') diff --git a/include/linux/socket.h b/include/linux/socket.h index 6a9840271676..f8d040434a13 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -363,5 +363,6 @@ extern int __sys_sendto(int fd, void __user *buff, size_t len, int addr_len); extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen, int flags); +extern int __sys_socket(int family, int type, int protocol); #endif /* _LINUX_SOCKET_H */ diff --git a/net/compat.c b/net/compat.c index 0ff9f7451b6f..5b3b74c5812e 100644 --- a/net/compat.c +++ b/net/compat.c @@ -811,7 +811,7 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) switch (call) { case SYS_SOCKET: - ret = sys_socket(a0, a1, a[2]); + ret = __sys_socket(a0, a1, a[2]); break; case SYS_BIND: ret = sys_bind(a0, compat_ptr(a1), a[2]); diff --git a/net/socket.c b/net/socket.c index 45f6ea0d57a5..07f379e50def 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1332,7 +1332,7 @@ int sock_create_kern(struct net *net, int family, int type, int protocol, struct } EXPORT_SYMBOL(sock_create_kern); -SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) +int __sys_socket(int family, int type, int protocol) { int retval; struct socket *sock; @@ -1359,6 +1359,11 @@ SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK)); } +SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) +{ + return __sys_socket(family, type, protocol); +} + /* * Create a pair of connected sockets. */ @@ -2463,7 +2468,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) switch (call) { case SYS_SOCKET: - err = sys_socket(a0, a1, a[2]); + err = __sys_socket(a0, a1, a[2]); break; case SYS_BIND: err = sys_bind(a0, (struct sockaddr __user *)a1, a[2]); -- cgit v1.2.3 From a87d35d87a3e4f2a0b0968d1f06703c909138b62 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 19:33:09 +0100 Subject: net: socket: add __sys_bind() helper; remove in-kernel call to syscall Using the net-internal helper __sys_bind() allows us to avoid the internal calls to the sys_bind() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- include/linux/socket.h | 1 + net/compat.c | 2 +- net/socket.c | 9 +++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'net/socket.c') diff --git a/include/linux/socket.h b/include/linux/socket.h index f8d040434a13..e9cee272da13 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -364,5 +364,6 @@ extern int __sys_sendto(int fd, void __user *buff, size_t len, extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen, int flags); extern int __sys_socket(int family, int type, int protocol); +extern int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen); #endif /* _LINUX_SOCKET_H */ diff --git a/net/compat.c b/net/compat.c index 5b3b74c5812e..bba555b1d863 100644 --- a/net/compat.c +++ b/net/compat.c @@ -814,7 +814,7 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) ret = __sys_socket(a0, a1, a[2]); break; case SYS_BIND: - ret = sys_bind(a0, compat_ptr(a1), a[2]); + ret = __sys_bind(a0, compat_ptr(a1), a[2]); break; case SYS_CONNECT: ret = sys_connect(a0, compat_ptr(a1), a[2]); diff --git a/net/socket.c b/net/socket.c index 07f379e50def..291cdae97341 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1462,7 +1462,7 @@ out: * the protocol layer (having also checked the address is ok). */ -SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) +int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen) { struct socket *sock; struct sockaddr_storage address; @@ -1485,6 +1485,11 @@ SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) return err; } +SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) +{ + return __sys_bind(fd, umyaddr, addrlen); +} + /* * Perform a listen. Basically, we allow the protocol to do anything * necessary for a listen, and if that works, we mark the socket as @@ -2471,7 +2476,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) err = __sys_socket(a0, a1, a[2]); break; case SYS_BIND: - err = sys_bind(a0, (struct sockaddr __user *)a1, a[2]); + err = __sys_bind(a0, (struct sockaddr __user *)a1, a[2]); break; case SYS_CONNECT: err = sys_connect(a0, (struct sockaddr __user *)a1, a[2]); -- cgit v1.2.3 From 1387c2c2f988f8180c6189d5083eaeeb8f120d44 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 19:35:09 +0100 Subject: net: socket: add __sys_connect() helper; remove in-kernel call to syscall Using the net-internal helper __sys_connect() allows us to avoid the internal calls to the sys_connect() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- include/linux/socket.h | 2 ++ net/compat.c | 2 +- net/socket.c | 11 ++++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'net/socket.c') diff --git a/include/linux/socket.h b/include/linux/socket.h index e9cee272da13..7daa344d7320 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -365,5 +365,7 @@ extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen, int flags); extern int __sys_socket(int family, int type, int protocol); extern int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen); +extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, + int addrlen); #endif /* _LINUX_SOCKET_H */ diff --git a/net/compat.c b/net/compat.c index bba555b1d863..7ab6352268f3 100644 --- a/net/compat.c +++ b/net/compat.c @@ -817,7 +817,7 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) ret = __sys_bind(a0, compat_ptr(a1), a[2]); break; case SYS_CONNECT: - ret = sys_connect(a0, compat_ptr(a1), a[2]); + ret = __sys_connect(a0, compat_ptr(a1), a[2]); break; case SYS_LISTEN: ret = sys_listen(a0, a1); diff --git a/net/socket.c b/net/socket.c index 291cdae97341..64bdfdf6c6e7 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1633,8 +1633,7 @@ SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr, * include the -EINPROGRESS status for such sockets. */ -SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, - int, addrlen) +int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen) { struct socket *sock; struct sockaddr_storage address; @@ -1660,6 +1659,12 @@ out: return err; } +SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, + int, addrlen) +{ + return __sys_connect(fd, uservaddr, addrlen); +} + /* * Get the local address ('name') of a socket object. Move the obtained * name to user space. @@ -2479,7 +2484,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) err = __sys_bind(a0, (struct sockaddr __user *)a1, a[2]); break; case SYS_CONNECT: - err = sys_connect(a0, (struct sockaddr __user *)a1, a[2]); + err = __sys_connect(a0, (struct sockaddr __user *)a1, a[2]); break; case SYS_LISTEN: err = sys_listen(a0, a1); -- cgit v1.2.3 From 25e290eed9c653cc90ac675d64b30b66cffce82f Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 19:36:54 +0100 Subject: net: socket: add __sys_listen() helper; remove in-kernel call to syscall Using the net-internal helper __sys_listen() allows us to avoid the internal calls to the sys_listen() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- include/linux/socket.h | 1 + net/compat.c | 2 +- net/socket.c | 9 +++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'net/socket.c') diff --git a/include/linux/socket.h b/include/linux/socket.h index 7daa344d7320..7e37af25509d 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -367,5 +367,6 @@ extern int __sys_socket(int family, int type, int protocol); extern int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen); extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen); +extern int __sys_listen(int fd, int backlog); #endif /* _LINUX_SOCKET_H */ diff --git a/net/compat.c b/net/compat.c index 7ab6352268f3..c80cb973f383 100644 --- a/net/compat.c +++ b/net/compat.c @@ -820,7 +820,7 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) ret = __sys_connect(a0, compat_ptr(a1), a[2]); break; case SYS_LISTEN: - ret = sys_listen(a0, a1); + ret = __sys_listen(a0, a1); break; case SYS_ACCEPT: ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0); diff --git a/net/socket.c b/net/socket.c index 64bdfdf6c6e7..67d9d70a4734 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1496,7 +1496,7 @@ SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) * ready for listening. */ -SYSCALL_DEFINE2(listen, int, fd, int, backlog) +int __sys_listen(int fd, int backlog) { struct socket *sock; int err, fput_needed; @@ -1517,6 +1517,11 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog) return err; } +SYSCALL_DEFINE2(listen, int, fd, int, backlog) +{ + return __sys_listen(fd, backlog); +} + /* * For accept, we attempt to create a new socket, set up the link * with the client, wake up the client, then return the new @@ -2487,7 +2492,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) err = __sys_connect(a0, (struct sockaddr __user *)a1, a[2]); break; case SYS_LISTEN: - err = sys_listen(a0, a1); + err = __sys_listen(a0, a1); break; case SYS_ACCEPT: err = __sys_accept4(a0, (struct sockaddr __user *)a1, -- cgit v1.2.3 From 8882a107b3062c6222cdbeadb284ea054ae50a3f Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 19:43:14 +0100 Subject: net: socket: add __sys_getsockname() helper; remove in-kernel call to syscall Using the net-internal helper __sys_getsockname() allows us to avoid the internal calls to the sys_getsockname() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- include/linux/socket.h | 2 ++ net/compat.c | 2 +- net/socket.c | 14 ++++++++++---- 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'net/socket.c') diff --git a/include/linux/socket.h b/include/linux/socket.h index 7e37af25509d..ef0226a61b03 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -368,5 +368,7 @@ extern int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen); extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen); extern int __sys_listen(int fd, int backlog); +extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, + int __user *usockaddr_len); #endif /* _LINUX_SOCKET_H */ diff --git a/net/compat.c b/net/compat.c index c80cb973f383..efd28d02608c 100644 --- a/net/compat.c +++ b/net/compat.c @@ -826,7 +826,7 @@ 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])); break; case SYS_GETPEERNAME: ret = sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2])); diff --git a/net/socket.c b/net/socket.c index 67d9d70a4734..b61e0d20f37b 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1675,8 +1675,8 @@ SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, * name to user space. */ -SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, - int __user *, usockaddr_len) +int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, + int __user *usockaddr_len) { struct socket *sock; struct sockaddr_storage address; @@ -1701,6 +1701,12 @@ out: return err; } +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. @@ -2500,8 +2506,8 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) break; case SYS_GETSOCKNAME: err = - sys_getsockname(a0, (struct sockaddr __user *)a1, - (int __user *)a[2]); + __sys_getsockname(a0, (struct sockaddr __user *)a1, + (int __user *)a[2]); break; case SYS_GETPEERNAME: err = -- cgit v1.2.3 From b21c8f838a0e5b84c0d78fd9ed6b9f2cf97afbe9 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 19:47:00 +0100 Subject: net: socket: add __sys_getpeername() helper; remove in-kernel call to syscall Using the net-internal helper __sys_getpeername() allows us to avoid the internal calls to the sys_getpeername() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- include/linux/socket.h | 2 ++ net/compat.c | 2 +- net/socket.c | 14 ++++++++++---- 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'net/socket.c') diff --git a/include/linux/socket.h b/include/linux/socket.h index ef0226a61b03..9ba003e92fea 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -370,5 +370,7 @@ extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, extern int __sys_listen(int fd, 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); #endif /* _LINUX_SOCKET_H */ diff --git a/net/compat.c b/net/compat.c index efd28d02608c..74017f618eb1 100644 --- a/net/compat.c +++ b/net/compat.c @@ -829,7 +829,7 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2])); break; case SYS_GETPEERNAME: - ret = sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2])); + ret = __sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2])); 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 b61e0d20f37b..007fb9483279 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1712,8 +1712,8 @@ SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, * name to user space. */ -SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, - int __user *, usockaddr_len) +int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, + int __user *usockaddr_len) { struct socket *sock; struct sockaddr_storage address; @@ -1738,6 +1738,12 @@ SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, return err; } +SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, + int __user *, usockaddr_len) +{ + return __sys_getpeername(fd, usockaddr, usockaddr_len); +} + /* * Send a datagram to a given address. We move the address into kernel * space and check the user space data area is readable before invoking @@ -2511,8 +2517,8 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) break; case SYS_GETPEERNAME: err = - sys_getpeername(a0, (struct sockaddr __user *)a1, - (int __user *)a[2]); + __sys_getpeername(a0, (struct sockaddr __user *)a1, + (int __user *)a[2]); break; case SYS_SOCKETPAIR: err = sys_socketpair(a0, a1, a[2], (int __user *)a[3]); -- cgit v1.2.3 From 6debc8d834ebc73566e5255c565c8fb307be22c5 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 19:49:23 +0100 Subject: net: socket: add __sys_socketpair() helper; remove in-kernel call to syscall Using the net-internal helper __sys_socketpair() allows us to avoid the internal calls to the sys_socketpair() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- include/linux/socket.h | 2 ++ net/compat.c | 2 +- net/socket.c | 11 ++++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'net/socket.c') diff --git a/include/linux/socket.h b/include/linux/socket.h index 9ba003e92fea..dbdddf0d079e 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -372,5 +372,7 @@ 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); +extern int __sys_socketpair(int family, int type, int protocol, + int __user *usockvec); #endif /* _LINUX_SOCKET_H */ diff --git a/net/compat.c b/net/compat.c index 74017f618eb1..04db26316438 100644 --- a/net/compat.c +++ b/net/compat.c @@ -832,7 +832,7 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) ret = __sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2])); break; case SYS_SOCKETPAIR: - ret = sys_socketpair(a0, a1, a[2], compat_ptr(a[3])); + ret = __sys_socketpair(a0, a1, a[2], compat_ptr(a[3])); break; case SYS_SEND: ret = sys_send(a0, compat_ptr(a1), a[2], a[3]); diff --git a/net/socket.c b/net/socket.c index 007fb9483279..5861821f46f5 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1368,8 +1368,7 @@ SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) * Create a pair of connected sockets. */ -SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, - int __user *, usockvec) +int __sys_socketpair(int family, int type, int protocol, int __user *usockvec) { struct socket *sock1, *sock2; int fd1, fd2, err; @@ -1454,6 +1453,12 @@ out: return err; } +SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, + int __user *, usockvec) +{ + return __sys_socketpair(family, type, protocol, usockvec); +} + /* * Bind a name to a socket. Nothing much to do here since it's * the protocol's responsibility to handle the local address. @@ -2521,7 +2526,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) (int __user *)a[2]); break; case SYS_SOCKETPAIR: - err = sys_socketpair(a0, a1, a[2], (int __user *)a[3]); + err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]); break; case SYS_SEND: err = sys_send(a0, (void __user *)a1, a[2], a[3]); -- cgit v1.2.3 From 005a1aeac46666e2805f316596893ebd2a3c12e7 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 20:07:05 +0100 Subject: net: socket: add __sys_shutdown() helper; remove in-kernel call to syscall Using the net-internal helper __sys_shutdown() allows us to avoid the internal calls to the sys_shutdown() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- include/linux/socket.h | 1 + net/compat.c | 2 +- net/socket.c | 9 +++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'net/socket.c') diff --git a/include/linux/socket.h b/include/linux/socket.h index dbdddf0d079e..b205138b69f1 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -374,5 +374,6 @@ extern int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len); extern int __sys_socketpair(int family, int type, int protocol, int __user *usockvec); +extern int __sys_shutdown(int fd, int how); #endif /* _LINUX_SOCKET_H */ diff --git a/net/compat.c b/net/compat.c index 04db26316438..f1ec23e9dfce 100644 --- a/net/compat.c +++ b/net/compat.c @@ -849,7 +849,7 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) compat_ptr(a[4]), compat_ptr(a[5])); break; case SYS_SHUTDOWN: - ret = sys_shutdown(a0, a1); + ret = __sys_shutdown(a0, a1); break; case SYS_SETSOCKOPT: ret = compat_sys_setsockopt(a0, a1, a[2], diff --git a/net/socket.c b/net/socket.c index 5861821f46f5..ad5dfd6a1d59 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1942,7 +1942,7 @@ out_put: * Shutdown a socket. */ -SYSCALL_DEFINE2(shutdown, int, fd, int, how) +int __sys_shutdown(int fd, int how) { int err, fput_needed; struct socket *sock; @@ -1957,6 +1957,11 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how) return err; } +SYSCALL_DEFINE2(shutdown, int, fd, int, how) +{ + return __sys_shutdown(fd, how); +} + /* A couple of helpful macros for getting the address of the 32/64 bit * fields which are the same type (int / unsigned) on our platforms. */ @@ -2544,7 +2549,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) (int __user *)a[5]); break; case SYS_SHUTDOWN: - err = sys_shutdown(a0, a1); + err = __sys_shutdown(a0, a1); break; case SYS_SETSOCKOPT: err = sys_setsockopt(a0, a1, a[2], (char __user *)a[3], a[4]); -- cgit v1.2.3 From cc36dca0dffad991135d0e28938ba2b4c0b786f7 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 20:10:59 +0100 Subject: net: socket: add __sys_setsockopt() helper; remove in-kernel call to syscall Using the net-internal helper __sys_setsockopt() allows us to avoid the internal calls to the sys_setsockopt() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- include/linux/socket.h | 1 + net/socket.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'net/socket.c') diff --git a/include/linux/socket.h b/include/linux/socket.h index b205138b69f1..cad120e4ed4b 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -376,4 +376,5 @@ extern int __sys_socketpair(int family, int type, int protocol, int __user *usockvec); extern int __sys_shutdown(int fd, int how); + #endif /* _LINUX_SOCKET_H */ diff --git a/net/socket.c b/net/socket.c index ad5dfd6a1d59..5dd2e39a6cd4 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1878,8 +1878,8 @@ SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size, * to pass the user mode parameter for the protocols to sort out. */ -SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, - char __user *, optval, int, optlen) +static int __sys_setsockopt(int fd, int level, int optname, + char __user *optval, int optlen) { int err, fput_needed; struct socket *sock; @@ -1907,6 +1907,12 @@ out_put: return err; } +SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, + char __user *, optval, int, optlen) +{ + return __sys_setsockopt(fd, level, optname, optval, optlen); +} + /* * Get a socket option. Because we don't know the option lengths we have * to pass a user mode parameter for the protocols to sort out. @@ -2552,7 +2558,8 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) err = __sys_shutdown(a0, a1); break; case SYS_SETSOCKOPT: - err = sys_setsockopt(a0, a1, a[2], (char __user *)a[3], a[4]); + err = __sys_setsockopt(a0, a1, a[2], (char __user *)a[3], + a[4]); break; case SYS_GETSOCKOPT: err = -- cgit v1.2.3 From 13a2d70e2b5218dde4b551a9b7adc5a11e359a05 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 20:15:04 +0100 Subject: net: socket: add __sys_getsockopt() helper; remove in-kernel call to syscall Using the net-internal helper __sys_getsockopt() allows us to avoid the internal calls to the sys_getsockopt() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- net/socket.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'net/socket.c') diff --git a/net/socket.c b/net/socket.c index 5dd2e39a6cd4..a05289b1f863 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1918,8 +1918,8 @@ SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, * to pass a user mode parameter for the protocols to sort out. */ -SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname, - char __user *, optval, int __user *, optlen) +static int __sys_getsockopt(int fd, int level, int optname, + char __user *optval, int __user *optlen) { int err, fput_needed; struct socket *sock; @@ -1944,6 +1944,12 @@ out_put: return err; } +SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname, + char __user *, optval, int __user *, optlen) +{ + return __sys_getsockopt(fd, level, optname, optval, optlen); +} + /* * Shutdown a socket. */ @@ -2563,8 +2569,8 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) break; case SYS_GETSOCKOPT: err = - sys_getsockopt(a0, a1, a[2], (char __user *)a[3], - (int __user *)a[4]); + __sys_getsockopt(a0, a1, a[2], (char __user *)a[3], + (int __user *)a[4]); break; case SYS_SENDMSG: err = sys_sendmsg(a0, (struct user_msghdr __user *)a1, a[2]); -- cgit v1.2.3 From 1255e2690689ba5b72814c8df7bfd9ecf50175aa Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 20:44:21 +0100 Subject: net: socket: add do_sys_recvmmsg() helper; remove in-kernel call to syscall Using the net-internal helper do_sys_recvmmsg() allows us to avoid the internal calls to the sys_getsockopt() syscall. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- net/socket.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'net/socket.c') diff --git a/net/socket.c b/net/socket.c index a05289b1f863..54d19b0edab1 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2445,9 +2445,9 @@ out_put: return datagrams; } -SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, - unsigned int, vlen, unsigned int, flags, - struct timespec __user *, timeout) +static int do_sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, + unsigned int vlen, unsigned int flags, + struct timespec __user *timeout) { int datagrams; struct timespec timeout_sys; @@ -2470,6 +2470,13 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, return datagrams; } +SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, + unsigned int, vlen, unsigned int, flags, + struct timespec __user *, timeout) +{ + return do_sys_recvmmsg(fd, mmsg, vlen, flags, timeout); +} + #ifdef __ARCH_WANT_SYS_SOCKETCALL /* Argument list sizes for sys_socketcall */ #define AL(x) ((x) * sizeof(unsigned long)) @@ -2582,8 +2589,8 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) err = sys_recvmsg(a0, (struct user_msghdr __user *)a1, a[2]); break; case SYS_RECVMMSG: - err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3], - (struct timespec __user *)a[4]); + err = do_sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], + a[3], (struct timespec __user *)a[4]); break; case SYS_ACCEPT4: err = __sys_accept4(a0, (struct sockaddr __user *)a1, -- cgit v1.2.3 From e1834a329d6bb5659c14e9e537bd1f750fe3b85e Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 20:35:57 +0100 Subject: net: socket: move check for forbid_cmsg_compat to __sys_...msg() The non-compat codepaths for sys_...msg() verify that MSG_CMSG_COMPAT is not set. By moving this check to the __sys_...msg() functions (and making it dependent on a static flag passed to this function), we can call the __sys...msg() functions instead of the syscall functions in all cases. __sys_recvmmsg() does not need this trickery, as the check is handled within the do_sys_recvmmsg() function internal to net/socket.c. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- include/linux/socket.h | 13 +++++++++---- net/compat.c | 8 +++++--- net/socket.c | 38 +++++++++++++++++++++++--------------- 3 files changed, 37 insertions(+), 22 deletions(-) (limited to 'net/socket.c') diff --git a/include/linux/socket.h b/include/linux/socket.h index cad120e4ed4b..e2b6bd4fe977 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -346,13 +346,18 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); struct timespec; -/* The __sys_...msg variants allow MSG_CMSG_COMPAT */ -extern long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags); -extern long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags); +/* The __sys_...msg variants allow MSG_CMSG_COMPAT iff + * forbid_cmsg_compat==false + */ +extern long __sys_recvmsg(int fd, struct user_msghdr __user *msg, + unsigned int flags, bool forbid_cmsg_compat); +extern long __sys_sendmsg(int fd, struct user_msghdr __user *msg, + unsigned int flags, bool forbid_cmsg_compat); extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout); extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, - unsigned int vlen, unsigned int flags); + unsigned int vlen, unsigned int flags, + bool forbid_cmsg_compat); /* helpers which do the actual work for syscalls */ extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size, diff --git a/net/compat.c b/net/compat.c index f1ec23e9dfce..5caa48987bb2 100644 --- a/net/compat.c +++ b/net/compat.c @@ -736,19 +736,21 @@ static unsigned char nas[21] = { COMPAT_SYSCALL_DEFINE3(sendmsg, int, fd, struct compat_msghdr __user *, msg, unsigned int, flags) { - return __sys_sendmsg(fd, (struct user_msghdr __user *)msg, flags | MSG_CMSG_COMPAT); + return __sys_sendmsg(fd, (struct user_msghdr __user *)msg, + flags | MSG_CMSG_COMPAT, false); } COMPAT_SYSCALL_DEFINE4(sendmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, unsigned int, vlen, unsigned int, flags) { return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, - flags | MSG_CMSG_COMPAT); + flags | MSG_CMSG_COMPAT, false); } COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg, unsigned int, flags) { - return __sys_recvmsg(fd, (struct user_msghdr __user *)msg, flags | MSG_CMSG_COMPAT); + return __sys_recvmsg(fd, (struct user_msghdr __user *)msg, + flags | MSG_CMSG_COMPAT, false); } COMPAT_SYSCALL_DEFINE4(recv, int, fd, void __user *, buf, compat_size_t, len, unsigned int, flags) diff --git a/net/socket.c b/net/socket.c index 54d19b0edab1..a70793a7ce78 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2137,12 +2137,16 @@ out_freeiov: * BSD sendmsg interface */ -long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags) +long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags, + bool forbid_cmsg_compat) { int fput_needed, err; struct msghdr msg_sys; struct socket *sock; + if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT)) + return -EINVAL; + sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; @@ -2156,9 +2160,7 @@ out: SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags) { - if (flags & MSG_CMSG_COMPAT) - return -EINVAL; - return __sys_sendmsg(fd, msg, flags); + return __sys_sendmsg(fd, msg, flags, true); } /* @@ -2166,7 +2168,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int */ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, - unsigned int flags) + unsigned int flags, bool forbid_cmsg_compat) { int fput_needed, err, datagrams; struct socket *sock; @@ -2176,6 +2178,9 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, struct used_address used_address; unsigned int oflags = flags; + if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT)) + return -EINVAL; + if (vlen > UIO_MAXIOV) vlen = UIO_MAXIOV; @@ -2232,9 +2237,7 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, unsigned int, vlen, unsigned int, flags) { - if (flags & MSG_CMSG_COMPAT) - return -EINVAL; - return __sys_sendmmsg(fd, mmsg, vlen, flags); + return __sys_sendmmsg(fd, mmsg, vlen, flags, true); } static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg, @@ -2307,12 +2310,16 @@ out_freeiov: * BSD recvmsg interface */ -long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags) +long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned int flags, + bool forbid_cmsg_compat) { int fput_needed, err; struct msghdr msg_sys; struct socket *sock; + if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT)) + return -EINVAL; + sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; @@ -2327,9 +2334,7 @@ out: SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags) { - if (flags & MSG_CMSG_COMPAT) - return -EINVAL; - return __sys_recvmsg(fd, msg, flags); + return __sys_recvmsg(fd, msg, flags, true); } /* @@ -2580,13 +2585,16 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) (int __user *)a[4]); break; case SYS_SENDMSG: - err = sys_sendmsg(a0, (struct user_msghdr __user *)a1, a[2]); + err = __sys_sendmsg(a0, (struct user_msghdr __user *)a1, + a[2], true); break; case SYS_SENDMMSG: - err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]); + err = __sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], + a[3], true); break; case SYS_RECVMSG: - err = sys_recvmsg(a0, (struct user_msghdr __user *)a1, a[2]); + err = __sys_recvmsg(a0, (struct user_msghdr __user *)a1, + a[2], true); break; case SYS_RECVMMSG: err = do_sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], -- cgit v1.2.3 From f3bf896b1d041153ea1c6cfa58f6f4658c91089f Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 19:52:00 +0100 Subject: net: socket: replace calls to sys_send() with __sys_sendto() sys_send() merely expands the parameters to __sys_sendto() by NULL and 0. Open-code this in the two places which used sys_send() as a wrapper to __sys_sendto(). This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- net/compat.c | 2 +- net/socket.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'net/socket.c') diff --git a/net/compat.c b/net/compat.c index 5caa48987bb2..d55982ff5c59 100644 --- a/net/compat.c +++ b/net/compat.c @@ -837,7 +837,7 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) ret = __sys_socketpair(a0, a1, a[2], compat_ptr(a[3])); break; case SYS_SEND: - ret = sys_send(a0, compat_ptr(a1), a[2], a[3]); + ret = __sys_sendto(a0, compat_ptr(a1), a[2], a[3], NULL, 0); break; case SYS_SENDTO: ret = __sys_sendto(a0, compat_ptr(a1), a[2], a[3], diff --git a/net/socket.c b/net/socket.c index a70793a7ce78..92de21bb1a2e 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2558,7 +2558,8 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]); break; case SYS_SEND: - err = sys_send(a0, (void __user *)a1, a[2], a[3]); + err = __sys_sendto(a0, (void __user *)a1, a[2], a[3], + NULL, 0); break; case SYS_SENDTO: err = __sys_sendto(a0, (void __user *)a1, a[2], a[3], -- cgit v1.2.3 From d27e9afc64206b5a2fe02561716cee5be9aacf01 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 19:54:17 +0100 Subject: net: socket: replace call to sys_recv() with __sys_recvfrom() sys_recv() merely expands the parameters to __sys_recvfrom() by NULL and NULL. Open-code this in the two places which used sys_recv() as a wrapper to __sys_recvfrom(). This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: David S. Miller Cc: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski --- net/compat.c | 3 ++- net/socket.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'net/socket.c') diff --git a/net/compat.c b/net/compat.c index d55982ff5c59..9e0d030063ad 100644 --- a/net/compat.c +++ b/net/compat.c @@ -755,7 +755,8 @@ COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg, uns COMPAT_SYSCALL_DEFINE4(recv, int, fd, void __user *, buf, compat_size_t, len, unsigned int, flags) { - return sys_recv(fd, buf, len, flags | MSG_CMSG_COMPAT); + return __sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, NULL, + NULL); } COMPAT_SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, buf, compat_size_t, len, diff --git a/net/socket.c b/net/socket.c index 92de21bb1a2e..03702f08aa62 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2566,7 +2566,8 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) (struct sockaddr __user *)a[4], a[5]); break; case SYS_RECV: - err = sys_recv(a0, (void __user *)a1, a[2], a[3]); + err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3], + NULL, NULL); break; case SYS_RECVFROM: err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3], -- cgit v1.2.3