From 819671ff849b07b9831b91de879ddc5da4b333d4 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:25 +0100 Subject: syscalls: define and explain goal to not call syscalls in the kernel The syscall entry points to the kernel defined by SYSCALL_DEFINEx() and COMPAT_SYSCALL_DEFINEx() should only be called from userspace through kernel entry points, but not from the kernel itself. This will allow cleanups and optimizations to the entry paths *and* to the parts of the kernel code which currently need to pretend to be userspace in order to make use of syscalls. Signed-off-by: Dominik Brodowski --- include/linux/syscalls.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index a78186d826d7..0526286a0314 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -941,4 +941,11 @@ asmlinkage long sys_pkey_free(int pkey); asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags, unsigned mask, struct statx __user *buffer); + +/* + * Kernel code should not call syscalls (i.e., sys_xyzyyz()) directly. + * Instead, use one of the functions which work equivalently, such as + * the ksys_xyzyyz() functions prototyped below. + */ + #endif -- cgit v1.2.3-71-gd317 From d53238cd51a80f6f2e5b9d64830c62e2086787bd Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:37 +0100 Subject: kernel: open-code sys_rt_sigpending() in sys_sigpending() A similar but not fully equivalent code path is already open-coded three times (in sys_rt_sigpending and in the two compat stubs), so do it a fourth time here. 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- include/linux/syscalls.h | 2 +- kernel/signal.c | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 0526286a0314..a63e21e7a3af 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -288,7 +288,7 @@ asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data); asmlinkage long sys_personality(unsigned int personality); -asmlinkage long sys_sigpending(old_sigset_t __user *set); +asmlinkage long sys_sigpending(old_sigset_t __user *uset); asmlinkage long sys_sigprocmask(int how, old_sigset_t __user *set, old_sigset_t __user *oset); asmlinkage long sys_sigaltstack(const struct sigaltstack __user *uss, diff --git a/kernel/signal.c b/kernel/signal.c index c6e4c83dc090..985c61749bcf 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -3629,11 +3629,20 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp) /** * sys_sigpending - examine pending signals - * @set: where mask of pending signal is returned + * @uset: where mask of pending signal is returned */ -SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) +SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, uset) { - return sys_rt_sigpending((sigset_t __user *)set, sizeof(old_sigset_t)); + sigset_t set; + int err; + + if (sizeof(old_sigset_t) > sizeof(*uset)) + return -EINVAL; + + err = do_sigpending(&set); + if (!err && copy_to_user(uset, &set, sizeof(old_sigset_t))) + err = -EFAULT; + return err; } #ifdef CONFIG_COMPAT -- cgit v1.2.3-71-gd317 From 2de0db992de189fccc83fed57c30875144821491 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:26 +0100 Subject: mm: use do_futex() instead of sys_futex() in mm_release() sys_futex() is a wrapper to do_futex() which does not modify any values here: - uaddr, val and val3 are kept the same - op is masked with FUTEX_CMD_MASK, but is always set to FUTEX_WAKE. Therefore, val2 is always 0. - as utime is set to NULL, *timeout is NULL 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: Ingo Molnar Cc: Peter Zijlstra Cc: Darren Hart Cc: Andrew Morton Reviewed-by: Thomas Gleixner Signed-off-by: Dominik Brodowski --- include/linux/futex.h | 13 ++++++++++--- kernel/fork.c | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/futex.h b/include/linux/futex.h index c0fb9a24bbd2..821ae502d3d8 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -9,9 +9,6 @@ struct inode; struct mm_struct; struct task_struct; -long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, - u32 __user *uaddr2, u32 val2, u32 val3); - extern int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi); @@ -55,6 +52,9 @@ union futex_key { #ifdef CONFIG_FUTEX extern void exit_robust_list(struct task_struct *curr); + +long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, + u32 __user *uaddr2, u32 val2, u32 val3); #ifdef CONFIG_HAVE_FUTEX_CMPXCHG #define futex_cmpxchg_enabled 1 #else @@ -64,6 +64,13 @@ extern int futex_cmpxchg_enabled; static inline void exit_robust_list(struct task_struct *curr) { } + +static inline long do_futex(u32 __user *uaddr, int op, u32 val, + ktime_t *timeout, u32 __user *uaddr2, + u32 val2, u32 val3) +{ + return -EINVAL; +} #endif #ifdef CONFIG_FUTEX_PI diff --git a/kernel/fork.c b/kernel/fork.c index e5d9d405ae4e..b1e031aac9db 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1198,8 +1198,8 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) * not set up a proper pointer then tough luck. */ put_user(0, tsk->clear_child_tid); - sys_futex(tsk->clear_child_tid, FUTEX_WAKE, - 1, NULL, NULL, 0); + do_futex(tsk->clear_child_tid, FUTEX_WAKE, + 1, NULL, NULL, 0, 0); } tsk->clear_child_tid = NULL; } -- cgit v1.2.3-71-gd317 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 --- include/linux/socket.h | 6 ++++++ net/compat.c | 3 ++- net/socket.c | 21 +++++++++++++-------- 3 files changed, 21 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/socket.h b/include/linux/socket.h index 9286a5a8c60c..40cc93b91628 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -353,4 +353,10 @@ 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); + +/* helpers which do the actual work for syscalls */ +extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size, + unsigned int flags, struct sockaddr __user *addr, + int __user *addr_len); + #endif /* _LINUX_SOCKET_H */ diff --git a/net/compat.c b/net/compat.c index 22381719718c..2d8186c277b2 100644 --- a/net/compat.c +++ b/net/compat.c @@ -760,7 +760,8 @@ COMPAT_SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, buf, compat_size_t, len unsigned int, flags, struct sockaddr __user *, addr, int __user *, addrlen) { - return sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, addr, addrlen); + return __sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, addr, + addrlen); } COMPAT_SYSCALL_DEFINE5(recvmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, 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-71-gd317 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 'include/linux') 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-71-gd317 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 'include/linux') 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-71-gd317 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 'include/linux') 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-71-gd317 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 'include/linux') 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-71-gd317 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 'include/linux') 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-71-gd317 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 'include/linux') 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-71-gd317 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 'include/linux') 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-71-gd317 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 'include/linux') 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-71-gd317 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 'include/linux') 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-71-gd317 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 'include/linux') 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-71-gd317 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 'include/linux') 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-71-gd317 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 'include/linux') 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-71-gd317 From cb0b476ab12ca3bd9dd9122047660f3a73e8d647 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 17 Mar 2018 16:26:56 +0100 Subject: fs/quota: add kernel_quotactl() helper; remove in-kernel call to syscall Using the fs-internal kernel_quotactl() helper allows us to get rid of the fs-internal call to the sys_quotactl() 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 Acked-by: Jan Kara Signed-off-by: Dominik Brodowski --- fs/quota/compat.c | 8 ++++---- fs/quota/quota.c | 10 ++++++++-- include/linux/quotaops.h | 3 +++ 3 files changed, 15 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/fs/quota/compat.c b/fs/quota/compat.c index 779caed4f078..1577a2fd51f4 100644 --- a/fs/quota/compat.c +++ b/fs/quota/compat.c @@ -59,7 +59,7 @@ asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special, case Q_GETQUOTA: dqblk = compat_alloc_user_space(sizeof(struct if_dqblk)); compat_dqblk = addr; - ret = sys_quotactl(cmd, special, id, dqblk); + ret = kernel_quotactl(cmd, special, id, dqblk); if (ret) break; if (copy_in_user(compat_dqblk, dqblk, sizeof(*compat_dqblk)) || @@ -75,12 +75,12 @@ asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special, get_user(data, &compat_dqblk->dqb_valid) || put_user(data, &dqblk->dqb_valid)) break; - ret = sys_quotactl(cmd, special, id, dqblk); + ret = kernel_quotactl(cmd, special, id, dqblk); break; case Q_XGETQSTAT: fsqstat = compat_alloc_user_space(sizeof(struct fs_quota_stat)); compat_fsqstat = addr; - ret = sys_quotactl(cmd, special, id, fsqstat); + ret = kernel_quotactl(cmd, special, id, fsqstat); if (ret) break; ret = -EFAULT; @@ -113,7 +113,7 @@ asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special, ret = 0; break; default: - ret = sys_quotactl(cmd, special, id, addr); + ret = kernel_quotactl(cmd, special, id, addr); } return ret; } diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 43612e2a73af..860bfbe7a07a 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -833,8 +833,8 @@ static struct super_block *quotactl_block(const char __user *special, int cmd) * calls. Maybe we need to add the process quotas etc. in the future, * but we probably should use rlimits for that. */ -SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special, - qid_t, id, void __user *, addr) +int kernel_quotactl(unsigned int cmd, const char __user *special, + qid_t id, void __user *addr) { uint cmds, type; struct super_block *sb = NULL; @@ -885,3 +885,9 @@ out: path_put(pathp); return ret; } + +SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special, + qid_t, id, void __user *, addr) +{ + return kernel_quotactl(cmd, special, id, addr); +} diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 2fb6fb11132e..dc905a4ff8d7 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -27,6 +27,9 @@ static inline bool is_quota_modification(struct inode *inode, struct iattr *ia) (ia->ia_valid & ATTR_GID && !gid_eq(ia->ia_gid, inode->i_gid)); } +int kernel_quotactl(unsigned int cmd, const char __user *special, + qid_t id, void __user *addr); + #if defined(CONFIG_QUOTA) #define quota_error(sb, fmt, args...) \ -- cgit v1.2.3-71-gd317 From ab0d1e85bfd0c25260f02cd3708d5abdfb5b5a9c Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 4 Mar 2018 21:54:05 +0100 Subject: fs/quota: use COMPAT_SYSCALL_DEFINE for sys32_quotactl() While sys32_quotactl() is only needed on x86, it can use the recommended COMPAT_SYSCALL_DEFINEx() machinery for its setup. Acked-by: Jan Kara Cc: Christoph Hellwig Signed-off-by: Dominik Brodowski --- arch/x86/entry/syscalls/syscall_32.tbl | 2 +- fs/quota/compat.c | 5 +++-- include/linux/compat.h | 3 +++ include/linux/syscalls.h | 2 -- kernel/sys_ni.c | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index ef6edaf285cd..c58f75b088c5 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl @@ -137,7 +137,7 @@ 128 i386 init_module sys_init_module 129 i386 delete_module sys_delete_module 130 i386 get_kernel_syms -131 i386 quotactl sys_quotactl sys32_quotactl +131 i386 quotactl sys_quotactl compat_sys_quotactl32 132 i386 getpgid sys_getpgid 133 i386 fchdir sys_fchdir 134 i386 bdflush sys_bdflush diff --git a/fs/quota/compat.c b/fs/quota/compat.c index 1577a2fd51f4..c30572857619 100644 --- a/fs/quota/compat.c +++ b/fs/quota/compat.c @@ -41,8 +41,9 @@ struct compat_fs_quota_stat { __u16 qs_iwarnlimit; }; -asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special, - qid_t id, void __user *addr) +COMPAT_SYSCALL_DEFINE4(quotactl32, unsigned int, cmd, + const char __user *, special, qid_t, id, + void __user *, addr) { unsigned int cmds; struct if_dqblk __user *dqblk; diff --git a/include/linux/compat.h b/include/linux/compat.h index 16c3027074a2..f1649a5e6716 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -461,6 +461,9 @@ asmlinkage ssize_t compat_sys_pwritev2(compat_ulong_t fd, const struct compat_iovec __user *vec, compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags); +asmlinkage long compat_sys_quotactl32(unsigned int cmd, + const char __user *special, qid_t id, void __user *addr); + #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64 asmlinkage long compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec, diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index a63e21e7a3af..6ab7ed71a8b6 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -241,8 +241,6 @@ static inline void addr_limit_user_check(void) #endif } -asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special, - qid_t id, void __user *addr); asmlinkage long sys_time(time_t __user *tloc); asmlinkage long sys_stime(time_t __user *tptr); asmlinkage long sys_gettimeofday(struct timeval __user *tv, diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index b5189762d275..951dbda5c2b4 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -18,7 +18,7 @@ asmlinkage long sys_ni_syscall(void) } cond_syscall(sys_quotactl); -cond_syscall(sys32_quotactl); +cond_syscall(compat_sys_quotactl32); cond_syscall(sys_acct); cond_syscall(sys_lookup_dcookie); cond_syscall(compat_sys_lookup_dcookie); -- cgit v1.2.3-71-gd317 From 312db1aa1dc7bff133d95c92efcc5e42b57cefa6 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:39 +0100 Subject: fs: add ksys_mount() helper; remove in-kernel calls to sys_mount() Using this helper allows us to avoid the in-kernel calls to the sys_mount() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_mount(). In the near future, all callers of ksys_mount() should be converted to call do_mount() directly. 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: Alexander Viro Signed-off-by: Dominik Brodowski --- drivers/base/devtmpfs.c | 5 +++-- fs/namespace.c | 10 ++++++++-- include/linux/syscalls.h | 3 +++ init/do_mounts.c | 4 ++-- init/do_mounts_initrd.c | 6 +++--- 5 files changed, 19 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 50025d7959cb..4afb04686c8e 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -356,7 +356,8 @@ int devtmpfs_mount(const char *mntdir) if (!thread) return 0; - err = sys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, NULL); + err = ksys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, + NULL); if (err) printk(KERN_INFO "devtmpfs: error mounting %i\n", err); else @@ -382,7 +383,7 @@ static int devtmpfsd(void *p) *err = sys_unshare(CLONE_NEWNS); if (*err) goto out; - *err = sys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); + *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); if (*err) goto out; sys_chdir("/.."); /* will traverse into overmounted root */ diff --git a/fs/namespace.c b/fs/namespace.c index 9d1374ab6e06..642b8b229944 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3032,8 +3032,8 @@ struct dentry *mount_subtree(struct vfsmount *mnt, const char *name) } EXPORT_SYMBOL(mount_subtree); -SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, - char __user *, type, unsigned long, flags, void __user *, data) +int ksys_mount(char __user *dev_name, char __user *dir_name, char __user *type, + unsigned long flags, void __user *data) { int ret; char *kernel_type; @@ -3066,6 +3066,12 @@ out_type: return ret; } +SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, + char __user *, type, unsigned long, flags, void __user *, data) +{ + return ksys_mount(dev_name, dir_name, type, flags, data); +} + /* * Return true if path is reachable from root * diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 6ab7ed71a8b6..3a9f9c534624 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -946,4 +946,7 @@ asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags, * the ksys_xyzyyz() functions prototyped below. */ +int ksys_mount(char __user *dev_name, char __user *dir_name, char __user *type, + unsigned long flags, void __user *data); + #endif diff --git a/init/do_mounts.c b/init/do_mounts.c index 7cf4f6dafd5f..eb768de43d84 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -363,7 +363,7 @@ static void __init get_fs_names(char *page) static int __init do_mount_root(char *name, char *fs, int flags, void *data) { struct super_block *s; - int err = sys_mount(name, "/root", fs, flags, data); + int err = ksys_mount(name, "/root", fs, flags, data); if (err) return err; @@ -599,7 +599,7 @@ void __init prepare_namespace(void) mount_root(); out: devtmpfs_mount("dev"); - sys_mount(".", "/", NULL, MS_MOVE, NULL); + ksys_mount(".", "/", NULL, MS_MOVE, NULL); sys_chroot("."); } diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 53d4f0f326e7..7868a6039fb4 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -43,7 +43,7 @@ static int init_linuxrc(struct subprocess_info *info, struct cred *new) sys_dup(0); /* move initrd over / and chdir/chroot in initrd root */ sys_chdir("/root"); - sys_mount(".", "/", NULL, MS_MOVE, NULL); + ksys_mount(".", "/", NULL, MS_MOVE, NULL); sys_chroot("."); sys_setsid(); return 0; @@ -81,7 +81,7 @@ static void __init handle_initrd(void) current->flags &= ~PF_FREEZER_SKIP; /* move initrd to rootfs' /old */ - sys_mount("..", ".", NULL, MS_MOVE, NULL); + ksys_mount("..", ".", NULL, MS_MOVE, NULL); /* switch root and cwd back to / of rootfs */ sys_chroot(".."); @@ -95,7 +95,7 @@ static void __init handle_initrd(void) mount_root(); printk(KERN_NOTICE "Trying to move old root to /initrd ... "); - error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL); + error = ksys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL); if (!error) printk("okay\n"); else { -- cgit v1.2.3-71-gd317 From 3a18ef5c1b3935cb05888fc37964321f7bd6231d Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:40 +0100 Subject: fs: add ksys_umount() helper; remove in-kernel call to sys_umount() Using this helper allows us to avoid the in-kernel call to the sys_umount() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as ksys_umount(). In the near future, the only fs-external caller of ksys_umount() should be converted to call do_umount() directly. Then, ksys_umount() can be moved within sys_umount() again. 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: Alexander Viro Signed-off-by: Dominik Brodowski --- fs/namespace.c | 9 +++++++-- include/linux/syscalls.h | 1 + init/do_mounts_initrd.c | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/fs/namespace.c b/fs/namespace.c index 642b8b229944..e398f32d7541 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1680,7 +1680,7 @@ static inline bool may_mandlock(void) * unixes. Our API is identical to OSF/1 to avoid making a mess of AMD */ -SYSCALL_DEFINE2(umount, char __user *, name, int, flags) +int ksys_umount(char __user *name, int flags) { struct path path; struct mount *mnt; @@ -1720,6 +1720,11 @@ out: return retval; } +SYSCALL_DEFINE2(umount, char __user *, name, int, flags) +{ + return ksys_umount(name, flags); +} + #ifdef __ARCH_WANT_SYS_OLDUMOUNT /* @@ -1727,7 +1732,7 @@ out: */ SYSCALL_DEFINE1(oldumount, char __user *, name) { - return sys_umount(name, 0); + return ksys_umount(name, 0); } #endif diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 3a9f9c534624..48964c408c7b 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -948,5 +948,6 @@ asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags, int ksys_mount(char __user *dev_name, char __user *dir_name, char __user *type, unsigned long flags, void __user *data); +int ksys_umount(char __user *name, int flags); #endif diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 7868a6039fb4..1c4da8353332 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -105,7 +105,7 @@ static void __init handle_initrd(void) else printk("failed\n"); printk(KERN_NOTICE "Unmounting old root\n"); - sys_umount("/old", MNT_DETACH); + ksys_umount("/old", MNT_DETACH); printk(KERN_NOTICE "Trying to free ramdisk memory ... "); if (fd < 0) { error = fd; -- cgit v1.2.3-71-gd317 From c7248321a3d42ffba78db0dde88d1c49ca1c045f Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:40 +0100 Subject: fs: add ksys_dup{,3}() helper; remove in-kernel calls to sys_dup{,3}() Using ksys_dup() and ksys_dup3() as helper functions allows us to avoid the in-kernel calls to the sys_dup() and sys_dup3() syscalls. The ksys_ prefix denotes that these functions are meant as a drop-in replacement for the syscalls. In particular, they use the same calling convention as sys_dup{,3}(). In the near future, the fs-external callers of ksys_dup{,3}() should be converted to call do_dup2() directly. Then, ksys_dup{,3}() can be moved within sys_dup{,3}() again. 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: Alexander Viro Signed-off-by: Dominik Brodowski --- fs/file.c | 16 +++++++++++++--- include/linux/syscalls.h | 1 + init/do_mounts_initrd.c | 4 ++-- init/main.c | 4 ++-- 4 files changed, 18 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/fs/file.c b/fs/file.c index 42f0db4bd0fb..d304004f0b65 100644 --- a/fs/file.c +++ b/fs/file.c @@ -870,7 +870,7 @@ out_unlock: return err; } -SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags) +static int ksys_dup3(unsigned int oldfd, unsigned int newfd, int flags) { int err = -EBADF; struct file *file; @@ -904,6 +904,11 @@ out_unlock: return err; } +SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags) +{ + return ksys_dup3(oldfd, newfd, flags); +} + SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd) { if (unlikely(newfd == oldfd)) { /* corner case */ @@ -916,10 +921,10 @@ SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd) rcu_read_unlock(); return retval; } - return sys_dup3(oldfd, newfd, 0); + return ksys_dup3(oldfd, newfd, 0); } -SYSCALL_DEFINE1(dup, unsigned int, fildes) +int ksys_dup(unsigned int fildes) { int ret = -EBADF; struct file *file = fget_raw(fildes); @@ -934,6 +939,11 @@ SYSCALL_DEFINE1(dup, unsigned int, fildes) return ret; } +SYSCALL_DEFINE1(dup, unsigned int, fildes) +{ + return ksys_dup(fildes); +} + int f_dupfd(unsigned int from, struct file *file, unsigned flags) { int err; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 48964c408c7b..50876ae1d17b 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -949,5 +949,6 @@ asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags, int ksys_mount(char __user *dev_name, char __user *dir_name, char __user *type, unsigned long flags, void __user *data); int ksys_umount(char __user *name, int flags); +int ksys_dup(unsigned int fildes); #endif diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 1c4da8353332..e8573e1776f6 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -39,8 +39,8 @@ static int init_linuxrc(struct subprocess_info *info, struct cred *new) sys_unshare(CLONE_FS | CLONE_FILES); /* stdin/stdout/stderr for /linuxrc */ sys_open("/dev/console", O_RDWR, 0); - sys_dup(0); - sys_dup(0); + ksys_dup(0); + ksys_dup(0); /* move initrd over / and chdir/chroot in initrd root */ sys_chdir("/root"); ksys_mount(".", "/", NULL, MS_MOVE, NULL); diff --git a/init/main.c b/init/main.c index 969eaf140ef0..b8649d1466e1 100644 --- a/init/main.c +++ b/init/main.c @@ -1077,8 +1077,8 @@ static noinline void __init kernel_init_freeable(void) if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) pr_err("Warning: unable to open an initial console.\n"); - (void) sys_dup(0); - (void) sys_dup(0); + (void) ksys_dup(0); + (void) ksys_dup(0); /* * check if there is an early userspace init. If yes, let it do all * the work -- cgit v1.2.3-71-gd317 From a16fe33ab5572e52ef4cb9719d6eb49623b2528a Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:41 +0100 Subject: fs: add ksys_chroot() helper; remove-in kernel calls to sys_chroot() Using this helper allows us to avoid the in-kernel calls to the sys_chroot() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_chroot(). In the near future, the fs-external callers of ksys_chroot() should be converted to use kern_path()/set_fs_root() directly. Then ksys_chroot() can be moved within sys_chroot() again. 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: Alexander Viro Signed-off-by: Dominik Brodowski --- drivers/base/devtmpfs.c | 2 +- fs/open.c | 7 ++++++- include/linux/syscalls.h | 1 + init/do_mounts.c | 2 +- init/do_mounts_initrd.c | 4 ++-- 5 files changed, 11 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 4afb04686c8e..5743f04014ca 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -387,7 +387,7 @@ static int devtmpfsd(void *p) if (*err) goto out; sys_chdir("/.."); /* will traverse into overmounted root */ - sys_chroot("."); + ksys_chroot("."); complete(&setup_done); while (1) { spin_lock(&req_lock); diff --git a/fs/open.c b/fs/open.c index 7ea118471dce..7a475e8a2e41 100644 --- a/fs/open.c +++ b/fs/open.c @@ -479,7 +479,7 @@ out: return error; } -SYSCALL_DEFINE1(chroot, const char __user *, filename) +int ksys_chroot(const char __user *filename) { struct path path; int error; @@ -512,6 +512,11 @@ out: return error; } +SYSCALL_DEFINE1(chroot, const char __user *, filename) +{ + return ksys_chroot(filename); +} + static int chmod_common(const struct path *path, umode_t mode) { struct inode *inode = path->dentry->d_inode; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 50876ae1d17b..920a0db1871d 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -950,5 +950,6 @@ int ksys_mount(char __user *dev_name, char __user *dir_name, char __user *type, unsigned long flags, void __user *data); int ksys_umount(char __user *name, int flags); int ksys_dup(unsigned int fildes); +int ksys_chroot(const char __user *filename); #endif diff --git a/init/do_mounts.c b/init/do_mounts.c index eb768de43d84..2f06f7827b0c 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -600,7 +600,7 @@ void __init prepare_namespace(void) out: devtmpfs_mount("dev"); ksys_mount(".", "/", NULL, MS_MOVE, NULL); - sys_chroot("."); + ksys_chroot("."); } static bool is_tmpfs; diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index e8573e1776f6..71293265ac4b 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -44,7 +44,7 @@ static int init_linuxrc(struct subprocess_info *info, struct cred *new) /* move initrd over / and chdir/chroot in initrd root */ sys_chdir("/root"); ksys_mount(".", "/", NULL, MS_MOVE, NULL); - sys_chroot("."); + ksys_chroot("."); sys_setsid(); return 0; } @@ -83,7 +83,7 @@ static void __init handle_initrd(void) /* move initrd to rootfs' /old */ ksys_mount("..", ".", NULL, MS_MOVE, NULL); /* switch root and cwd back to / of rootfs */ - sys_chroot(".."); + ksys_chroot(".."); if (new_decode_dev(real_root_dev) == Root_RAM0) { sys_chdir("/old"); -- cgit v1.2.3-71-gd317 From e7a3e8b2edf544ec28f689385c3adc2903f46ec0 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:41 +0100 Subject: fs: add ksys_write() helper; remove in-kernel calls to sys_write() Using this helper allows us to avoid the in-kernel calls to the sys_write() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_write(). In the near future, the do_mounts / initramfs callers of ksys_write() should be converted to use filp_open() and vfs_write() instead. 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: Alexander Viro Cc: linux-s390@vger.kernel.org Signed-off-by: Dominik Brodowski --- arch/s390/kernel/compat_linux.c | 2 +- fs/read_write.c | 9 +++++++-- include/linux/syscalls.h | 1 + init/do_mounts_rd.c | 4 ++-- init/initramfs.c | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 79b7a3438d54..5a9cfde5fc28 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -468,7 +468,7 @@ COMPAT_SYSCALL_DEFINE3(s390_write, unsigned int, fd, const char __user *, buf, c if ((compat_ssize_t) count < 0) return -EINVAL; - return sys_write(fd, buf, count); + return ksys_write(fd, buf, count); } /* diff --git a/fs/read_write.c b/fs/read_write.c index f8547b82dfb3..8e8f0b4f52e2 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -578,8 +578,7 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) return ret; } -SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, - size_t, count) +ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count) { struct fd f = fdget_pos(fd); ssize_t ret = -EBADF; @@ -595,6 +594,12 @@ SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, return ret; } +SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, + size_t, count) +{ + return ksys_write(fd, buf, count); +} + SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf, size_t, count, loff_t, pos) { diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 920a0db1871d..80524faa9664 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -951,5 +951,6 @@ int ksys_mount(char __user *dev_name, char __user *dir_name, char __user *type, int ksys_umount(char __user *name, int flags); int ksys_dup(unsigned int fildes); int ksys_chroot(const char __user *filename); +ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count); #endif diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 99e0b649fc0e..2d365c398ccc 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -270,7 +270,7 @@ int __init rd_load_image(char *from) printk("Loading disk #%d... ", disk); } sys_read(in_fd, buf, BLOCK_SIZE); - sys_write(out_fd, buf, BLOCK_SIZE); + ksys_write(out_fd, buf, BLOCK_SIZE); #if !defined(CONFIG_S390) if (!(i % 16)) { pr_cont("%c\b", rotator[rotate & 0x3]); @@ -317,7 +317,7 @@ static long __init compr_fill(void *buf, unsigned long len) static long __init compr_flush(void *window, unsigned long outcnt) { - long written = sys_write(crd_outfd, window, outcnt); + long written = ksys_write(crd_outfd, window, outcnt); if (written != outcnt) { if (decompress_error == 0) printk(KERN_ERR diff --git a/init/initramfs.c b/init/initramfs.c index 7e99a0038942..6f972df15bf2 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -27,7 +27,7 @@ static ssize_t __init xwrite(int fd, const char *p, size_t count) /* sys_write only can write MAX_RW_COUNT aka 2G-4K bytes at most */ while (count) { - ssize_t rv = sys_write(fd, p, count); + ssize_t rv = ksys_write(fd, p, count); if (rv < 0) { if (rv == -EINTR || rv == -EAGAIN) -- cgit v1.2.3-71-gd317 From 447016e9681965fda8dcd9e4fd3c55308a6fd166 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:46 +0100 Subject: fs: add ksys_chdir() helper; remove in-kernel calls to sys_chdir() Using this helper allows us to avoid the in-kernel calls to the sys_chdir() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_chdir(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/base/devtmpfs.c | 2 +- fs/open.c | 7 ++++++- include/linux/syscalls.h | 1 + init/do_mounts.c | 2 +- init/do_mounts_initrd.c | 8 ++++---- 5 files changed, 13 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 5743f04014ca..3f7ee954fd2c 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -386,7 +386,7 @@ static int devtmpfsd(void *p) *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); if (*err) goto out; - sys_chdir("/.."); /* will traverse into overmounted root */ + ksys_chdir("/.."); /* will traverse into overmounted root */ ksys_chroot("."); complete(&setup_done); while (1) { diff --git a/fs/open.c b/fs/open.c index 7a475e8a2e41..a19b8277c439 100644 --- a/fs/open.c +++ b/fs/open.c @@ -431,7 +431,7 @@ SYSCALL_DEFINE2(access, const char __user *, filename, int, mode) return sys_faccessat(AT_FDCWD, filename, mode); } -SYSCALL_DEFINE1(chdir, const char __user *, filename) +int ksys_chdir(const char __user *filename) { struct path path; int error; @@ -457,6 +457,11 @@ out: return error; } +SYSCALL_DEFINE1(chdir, const char __user *, filename) +{ + return ksys_chdir(filename); +} + SYSCALL_DEFINE1(fchdir, unsigned int, fd) { struct fd f = fdget_raw(fd); diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 80524faa9664..090645b48447 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -952,5 +952,6 @@ int ksys_umount(char __user *name, int flags); int ksys_dup(unsigned int fildes); int ksys_chroot(const char __user *filename); ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count); +int ksys_chdir(const char __user *filename); #endif diff --git a/init/do_mounts.c b/init/do_mounts.c index 2f06f7827b0c..89f18985fa90 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -367,7 +367,7 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data) if (err) return err; - sys_chdir("/root"); + ksys_chdir("/root"); s = current->fs->pwd.dentry->d_sb; ROOT_DEV = s->s_dev; printk(KERN_INFO diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 71293265ac4b..83f396d30b9a 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -42,7 +42,7 @@ static int init_linuxrc(struct subprocess_info *info, struct cred *new) ksys_dup(0); ksys_dup(0); /* move initrd over / and chdir/chroot in initrd root */ - sys_chdir("/root"); + ksys_chdir("/root"); ksys_mount(".", "/", NULL, MS_MOVE, NULL); ksys_chroot("."); sys_setsid(); @@ -61,7 +61,7 @@ static void __init handle_initrd(void) /* mount initrd on rootfs' /root */ mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY); sys_mkdir("/old", 0700); - sys_chdir("/old"); + ksys_chdir("/old"); /* try loading default modules from initrd */ load_default_modules(); @@ -86,11 +86,11 @@ static void __init handle_initrd(void) ksys_chroot(".."); if (new_decode_dev(real_root_dev) == Root_RAM0) { - sys_chdir("/old"); + ksys_chdir("/old"); return; } - sys_chdir("/"); + ksys_chdir("/"); ROOT_DEV = new_decode_dev(real_root_dev); mount_root(); -- cgit v1.2.3-71-gd317 From 0f32ab8cfac478be053cb526ced8918ef6f4df47 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:47 +0100 Subject: fs: add ksys_unlink() wrapper; remove in-kernel calls to sys_unlink() Using this wrapper allows us to avoid the in-kernel calls to the sys_unlink() syscall. The ksys_ prefix denotes that this function is meant s a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_unlink(). In the near future, all callers of ksys_unlink() should be converted to call do_unlinkat() directly or, at least, to operate on regular kernel pointers. 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- include/linux/syscalls.h | 11 +++++++++++ init/do_mounts.h | 2 +- init/do_mounts_initrd.c | 4 ++-- init/do_mounts_rd.c | 2 +- init/initramfs.c | 4 ++-- 5 files changed, 17 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 090645b48447..7cbfb41e666b 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -954,4 +954,15 @@ int ksys_chroot(const char __user *filename); ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count); int ksys_chdir(const char __user *filename); +/* + * The following kernel syscall equivalents are just wrappers to fs-internal + * functions. Therefore, provide stubs to be inlined at the callsites. + */ +extern long do_unlinkat(int dfd, struct filename *name); + +static inline long ksys_unlink(const char __user *pathname) +{ + return do_unlinkat(AT_FDCWD, getname(pathname)); +} + #endif diff --git a/init/do_mounts.h b/init/do_mounts.h index 5b05c8f93f47..401f90ee1eeb 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -16,7 +16,7 @@ extern int root_mountflags; static inline int create_dev(char *name, dev_t dev) { - sys_unlink(name); + ksys_unlink(name); return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev)); } diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 83f396d30b9a..e9e9e1c67d31 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -128,11 +128,11 @@ bool __init initrd_load(void) * mounted in the normal path. */ if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) { - sys_unlink("/initrd.image"); + ksys_unlink("/initrd.image"); handle_initrd(); return true; } } - sys_unlink("/initrd.image"); + ksys_unlink("/initrd.image"); return false; } diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 2d365c398ccc..5b69056f610a 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -288,7 +288,7 @@ noclose_input: sys_close(out_fd); out: kfree(buf); - sys_unlink("/dev/ram"); + ksys_unlink("/dev/ram"); return res; } diff --git a/init/initramfs.c b/init/initramfs.c index 6f972df15bf2..08eb551168a8 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -319,7 +319,7 @@ static void __init clean_path(char *path, umode_t fmode) if (S_ISDIR(st.mode)) sys_rmdir(path); else - sys_unlink(path); + ksys_unlink(path); } } @@ -591,7 +591,7 @@ static void __init clean_rootfs(void) if (S_ISDIR(st.mode)) sys_rmdir(dirp->d_name); else - sys_unlink(dirp->d_name); + ksys_unlink(dirp->d_name); } num -= dirp->d_reclen; -- cgit v1.2.3-71-gd317 From f459dffae1c6026928bbe8e972daecb635b7b5e9 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:48 +0100 Subject: fs: add ksys_rmdir() wrapper; remove in-kernel calls to sys_rmdir() Using this wrapper allows us to avoid the in-kernel calls to the sys_rmdir() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_rmdir(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- fs/internal.h | 1 + fs/namei.c | 2 +- include/linux/syscalls.h | 7 +++++++ init/initramfs.c | 4 ++-- 4 files changed, 11 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/fs/internal.h b/fs/internal.h index df262f41a0ef..0eda35fa1743 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -55,6 +55,7 @@ extern void __init chrdev_init(void); extern int user_path_mountpoint_at(int, const char __user *, unsigned int, struct path *); extern int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, unsigned int, struct path *); +long do_rmdir(int dfd, const char __user *pathname); long do_unlinkat(int dfd, struct filename *name); /* diff --git a/fs/namei.c b/fs/namei.c index 524e829ffc7d..8545151f74e9 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3872,7 +3872,7 @@ out: } EXPORT_SYMBOL(vfs_rmdir); -static long do_rmdir(int dfd, const char __user *pathname) +long do_rmdir(int dfd, const char __user *pathname) { int error = 0; struct filename *name; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 7cbfb41e666b..746043a05884 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -965,4 +965,11 @@ static inline long ksys_unlink(const char __user *pathname) return do_unlinkat(AT_FDCWD, getname(pathname)); } +extern long do_rmdir(int dfd, const char __user *pathname); + +static inline long ksys_rmdir(const char __user *pathname) +{ + return do_rmdir(AT_FDCWD, pathname); +} + #endif diff --git a/init/initramfs.c b/init/initramfs.c index 08eb551168a8..73bbb227f868 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -317,7 +317,7 @@ static void __init clean_path(char *path, umode_t fmode) if (!vfs_lstat(path, &st) && (st.mode ^ fmode) & S_IFMT) { if (S_ISDIR(st.mode)) - sys_rmdir(path); + ksys_rmdir(path); else ksys_unlink(path); } @@ -589,7 +589,7 @@ static void __init clean_rootfs(void) WARN_ON_ONCE(ret); if (!ret) { if (S_ISDIR(st.mode)) - sys_rmdir(dirp->d_name); + ksys_rmdir(dirp->d_name); else ksys_unlink(dirp->d_name); } -- cgit v1.2.3-71-gd317 From 0101db7a301981a008296d522d8c1f456b0fe837 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:49 +0100 Subject: fs: add do_mkdirat() helper and ksys_mkdir() wrapper; remove in-kernel calls to syscall Using the fs-internal do_mkdirat() helper allows us to get rid of fs-internal calls to the sys_mkdirat() syscall. Introducing the ksys_mkdir() wrapper allows us to avoid the in-kernel calls to the sys_mkdir() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_mkdir(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- fs/internal.h | 1 + fs/namei.c | 9 +++++++-- include/linux/syscalls.h | 7 +++++++ init/do_mounts_initrd.c | 2 +- init/initramfs.c | 2 +- init/noinitramfs.c | 4 ++-- 6 files changed, 19 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/fs/internal.h b/fs/internal.h index 0eda35fa1743..53846bd4d9d7 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -55,6 +55,7 @@ extern void __init chrdev_init(void); extern int user_path_mountpoint_at(int, const char __user *, unsigned int, struct path *); extern int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, unsigned int, struct path *); +long do_mkdirat(int dfd, const char __user *pathname, umode_t mode); long do_rmdir(int dfd, const char __user *pathname); long do_unlinkat(int dfd, struct filename *name); diff --git a/fs/namei.c b/fs/namei.c index 8545151f74e9..dcf506227509 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3803,7 +3803,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) } EXPORT_SYMBOL(vfs_mkdir); -SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode) +long do_mkdirat(int dfd, const char __user *pathname, umode_t mode) { struct dentry *dentry; struct path path; @@ -3828,9 +3828,14 @@ retry: return error; } +SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode) +{ + return do_mkdirat(dfd, pathname, mode); +} + SYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode) { - return sys_mkdirat(AT_FDCWD, pathname, mode); + return do_mkdirat(AT_FDCWD, pathname, mode); } int vfs_rmdir(struct inode *dir, struct dentry *dentry) diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 746043a05884..c982cb5f4e50 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -972,4 +972,11 @@ static inline long ksys_rmdir(const char __user *pathname) return do_rmdir(AT_FDCWD, pathname); } +extern long do_mkdirat(int dfd, const char __user *pathname, umode_t mode); + +static inline long ksys_mkdir(const char __user *pathname, umode_t mode) +{ + return do_mkdirat(AT_FDCWD, pathname, mode); +} + #endif diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index e9e9e1c67d31..99922d1ebfe6 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -60,7 +60,7 @@ static void __init handle_initrd(void) create_dev("/dev/root.old", Root_RAM0); /* mount initrd on rootfs' /root */ mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY); - sys_mkdir("/old", 0700); + ksys_mkdir("/old", 0700); ksys_chdir("/old"); /* try loading default modules from initrd */ diff --git a/init/initramfs.c b/init/initramfs.c index 73bbb227f868..ca538a5f9fa9 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -352,7 +352,7 @@ static int __init do_name(void) } } } else if (S_ISDIR(mode)) { - sys_mkdir(collected, mode); + ksys_mkdir(collected, mode); sys_chown(collected, uid, gid); sys_chmod(collected, mode); dir_add(collected, mtime); diff --git a/init/noinitramfs.c b/init/noinitramfs.c index 267739d85179..a08a9d937e60 100644 --- a/init/noinitramfs.c +++ b/init/noinitramfs.c @@ -29,7 +29,7 @@ static int __init default_rootfs(void) { int err; - err = sys_mkdir((const char __user __force *) "/dev", 0755); + err = ksys_mkdir((const char __user __force *) "/dev", 0755); if (err < 0) goto out; @@ -39,7 +39,7 @@ static int __init default_rootfs(void) if (err < 0) goto out; - err = sys_mkdir((const char __user __force *) "/root", 0700); + err = ksys_mkdir((const char __user __force *) "/root", 0700); if (err < 0) goto out; -- cgit v1.2.3-71-gd317 From b724e846b491ef8db943be8086226c9d8da31877 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:49 +0100 Subject: fs: add do_symlinkat() helper and ksys_symlink() wrapper; remove in-kernel calls to syscall Using the fs-internal do_symlinkat() helper allows us to get rid of fs-internal calls to the sys_symlinkat() syscall. Introducing the ksys_symlink() wrapper allows us to avoid the in-kernel calls to the sys_symlink() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_symlink(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- fs/internal.h | 2 ++ fs/namei.c | 12 +++++++++--- include/linux/syscalls.h | 9 +++++++++ init/initramfs.c | 2 +- 4 files changed, 21 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/fs/internal.h b/fs/internal.h index 53846bd4d9d7..a3f04ca2a08b 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -58,6 +58,8 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *, long do_mkdirat(int dfd, const char __user *pathname, umode_t mode); long do_rmdir(int dfd, const char __user *pathname); long do_unlinkat(int dfd, struct filename *name); +long do_symlinkat(const char __user *oldname, int newdfd, + const char __user *newname); /* * namespace.c diff --git a/fs/namei.c b/fs/namei.c index dcf506227509..e15da92209d5 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4113,8 +4113,8 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) } EXPORT_SYMBOL(vfs_symlink); -SYSCALL_DEFINE3(symlinkat, const char __user *, oldname, - int, newdfd, const char __user *, newname) +long do_symlinkat(const char __user *oldname, int newdfd, + const char __user *newname) { int error; struct filename *from; @@ -4144,9 +4144,15 @@ out_putname: return error; } +SYSCALL_DEFINE3(symlinkat, const char __user *, oldname, + int, newdfd, const char __user *, newname) +{ + return do_symlinkat(oldname, newdfd, newname); +} + SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newname) { - return sys_symlinkat(oldname, AT_FDCWD, newname); + return do_symlinkat(oldname, AT_FDCWD, newname); } /** diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index c982cb5f4e50..39c5cef86a10 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -979,4 +979,13 @@ static inline long ksys_mkdir(const char __user *pathname, umode_t mode) return do_mkdirat(AT_FDCWD, pathname, mode); } +extern long do_symlinkat(const char __user *oldname, int newdfd, + const char __user *newname); + +static inline long ksys_symlink(const char __user *oldname, + const char __user *newname) +{ + return do_symlinkat(oldname, AT_FDCWD, newname); +} + #endif diff --git a/init/initramfs.c b/init/initramfs.c index ca538a5f9fa9..cd9571a113b6 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -392,7 +392,7 @@ static int __init do_symlink(void) { collected[N_ALIGN(name_len) + body_len] = '\0'; clean_path(collected, 0); - sys_symlink(collected + N_ALIGN(name_len), collected); + ksys_symlink(collected + N_ALIGN(name_len), collected); sys_lchown(collected, uid, gid); do_utime(collected, mtime); state = SkipIt; -- cgit v1.2.3-71-gd317 From 87c4e19262d81862886207be3c8795f6576d5a52 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:50 +0100 Subject: fs: add do_mknodat() helper and ksys_mknod() wrapper; remove in-kernel calls to syscall Using the fs-internal do_mknodat() helper allows us to get rid of fs-internal calls to the sys_mknodat() syscall. Introducing the ksys_mknod() wrapper allows us to avoid the in-kernel calls to sys_mknod() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_mknod(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- fs/internal.h | 2 ++ fs/namei.c | 12 +++++++++--- include/linux/syscalls.h | 9 +++++++++ init/do_mounts.h | 2 +- init/initramfs.c | 2 +- init/noinitramfs.c | 2 +- 6 files changed, 23 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/fs/internal.h b/fs/internal.h index a3f04ca2a08b..4f0b67054c54 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -55,6 +55,8 @@ extern void __init chrdev_init(void); extern int user_path_mountpoint_at(int, const char __user *, unsigned int, struct path *); extern int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, unsigned int, struct path *); +long do_mknodat(int dfd, const char __user *filename, umode_t mode, + unsigned int dev); long do_mkdirat(int dfd, const char __user *pathname, umode_t mode); long do_rmdir(int dfd, const char __user *pathname); long do_unlinkat(int dfd, struct filename *name); diff --git a/fs/namei.c b/fs/namei.c index e15da92209d5..8459a18cdd18 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3728,8 +3728,8 @@ static int may_mknod(umode_t mode) } } -SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, - unsigned, dev) +long do_mknodat(int dfd, const char __user *filename, umode_t mode, + unsigned int dev) { struct dentry *dentry; struct path path; @@ -3772,9 +3772,15 @@ out: return error; } +SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, + unsigned int, dev) +{ + return do_mknodat(dfd, filename, mode, dev); +} + SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, dev) { - return sys_mknodat(AT_FDCWD, filename, mode, dev); + return do_mknodat(AT_FDCWD, filename, mode, dev); } int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 39c5cef86a10..0b4fd684f0f1 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -988,4 +988,13 @@ static inline long ksys_symlink(const char __user *oldname, return do_symlinkat(oldname, AT_FDCWD, newname); } +extern long do_mknodat(int dfd, const char __user *filename, umode_t mode, + unsigned int dev); + +static inline long ksys_mknod(const char __user *filename, umode_t mode, + unsigned int dev) +{ + return do_mknodat(AT_FDCWD, filename, mode, dev); +} + #endif diff --git a/init/do_mounts.h b/init/do_mounts.h index 401f90ee1eeb..0bb0806de4ce 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -17,7 +17,7 @@ extern int root_mountflags; static inline int create_dev(char *name, dev_t dev) { ksys_unlink(name); - return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev)); + return ksys_mknod(name, S_IFBLK|0600, new_encode_dev(dev)); } static inline u32 bstat(char *name) diff --git a/init/initramfs.c b/init/initramfs.c index cd9571a113b6..2972ed0ab399 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -359,7 +359,7 @@ static int __init do_name(void) } else if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { if (maybe_link() == 0) { - sys_mknod(collected, mode, rdev); + ksys_mknod(collected, mode, rdev); sys_chown(collected, uid, gid); sys_chmod(collected, mode); do_utime(collected, mtime); diff --git a/init/noinitramfs.c b/init/noinitramfs.c index a08a9d937e60..f4bad8436c93 100644 --- a/init/noinitramfs.c +++ b/init/noinitramfs.c @@ -33,7 +33,7 @@ static int __init default_rootfs(void) if (err < 0) goto out; - err = sys_mknod((const char __user __force *) "/dev/console", + err = ksys_mknod((const char __user __force *) "/dev/console", S_IFCHR | S_IRUSR | S_IWUSR, new_encode_dev(MKDEV(5, 1))); if (err < 0) -- cgit v1.2.3-71-gd317 From 46ea89eb652a365e10257016d09dcf1aaf23cf63 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:53 +0100 Subject: fs: add do_linkat() helper and ksys_link() wrapper; remove in-kernel calls to syscall Using the fs-internal do_linkat() helper allows us to get rid of fs-internal calls to the sys_linkat() syscall. Introducing the ksys_link() wrapper allows us to avoid the in-kernel calls to sys_link() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_link(). In the near future, the only fs-external user of ksys_link() should be converted to use vfs_link() instead. 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- fs/internal.h | 2 ++ fs/namei.c | 12 +++++++++--- include/linux/syscalls.h | 9 +++++++++ init/initramfs.c | 2 +- 4 files changed, 21 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/fs/internal.h b/fs/internal.h index 4f0b67054c54..91e6fc93fcb5 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -62,6 +62,8 @@ long do_rmdir(int dfd, const char __user *pathname); long do_unlinkat(int dfd, struct filename *name); long do_symlinkat(const char __user *oldname, int newdfd, const char __user *newname); +int do_linkat(int olddfd, const char __user *oldname, int newdfd, + const char __user *newname, int flags); /* * namespace.c diff --git a/fs/namei.c b/fs/namei.c index 8459a18cdd18..10148235829f 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4250,8 +4250,8 @@ EXPORT_SYMBOL(vfs_link); * with linux 2.0, and to avoid hard-linking to directories * and other special files. --ADM */ -SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, - int, newdfd, const char __user *, newname, int, flags) +int do_linkat(int olddfd, const char __user *oldname, int newdfd, + const char __user *newname, int flags) { struct dentry *new_dentry; struct path old_path, new_path; @@ -4315,9 +4315,15 @@ out: return error; } +SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, + int, newdfd, const char __user *, newname, int, flags) +{ + return do_linkat(olddfd, oldname, newdfd, newname, flags); +} + SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname) { - return sys_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0); + return do_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0); } /** diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 0b4fd684f0f1..827ed917630c 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -997,4 +997,13 @@ static inline long ksys_mknod(const char __user *filename, umode_t mode, return do_mknodat(AT_FDCWD, filename, mode, dev); } +extern int do_linkat(int olddfd, const char __user *oldname, int newdfd, + const char __user *newname, int flags); + +static inline long ksys_link(const char __user *oldname, + const char __user *newname) +{ + return do_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0); +} + #endif diff --git a/init/initramfs.c b/init/initramfs.c index 2972ed0ab399..5855ab632b4e 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -306,7 +306,7 @@ static int __init maybe_link(void) if (nlink >= 2) { char *old = find_link(major, minor, ino, mode, collected); if (old) - return (sys_link(old, collected) < 0) ? -1 : 1; + return (ksys_link(old, collected) < 0) ? -1 : 1; } return 0; } -- cgit v1.2.3-71-gd317 From 03450e271a160bc07a2c48e5769e0ba338582d77 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:53 +0100 Subject: fs: add ksys_fchmod() and do_fchmodat() helpers and ksys_chmod() wrapper; remove in-kernel calls to syscall Using the fs-internal do_fchmodat() helper allows us to get rid of fs-internal calls to the sys_fchmodat() syscall. Introducing the ksys_fchmod() helper and the ksys_chmod() wrapper allows us to avoid the in-kernel calls to the sys_fchmod() and sys_chmod() syscalls. The ksys_ prefix denotes that these functions are meant as a drop-in replacement for the syscalls. In particular, they use the same calling convention as sys_fchmod() and sys_chmod(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- fs/internal.h | 2 ++ fs/open.c | 17 ++++++++++++++--- include/linux/syscalls.h | 8 ++++++++ init/initramfs.c | 6 +++--- 4 files changed, 27 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/fs/internal.h b/fs/internal.h index 91e6fc93fcb5..2474bf460f96 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -119,6 +119,8 @@ extern struct file *do_filp_open(int dfd, struct filename *pathname, extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, const char *, const struct open_flags *); +int do_fchmodat(int dfd, const char __user *filename, umode_t mode); + extern int open_check_o_direct(struct file *f); extern int vfs_open(const struct path *, struct file *, const struct cred *); extern struct file *filp_clone_open(struct file *); diff --git a/fs/open.c b/fs/open.c index a19b8277c439..6037f2bf418c 100644 --- a/fs/open.c +++ b/fs/open.c @@ -551,7 +551,7 @@ out_unlock: return error; } -SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode) +int ksys_fchmod(unsigned int fd, umode_t mode) { struct fd f = fdget(fd); int err = -EBADF; @@ -564,7 +564,12 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode) return err; } -SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode) +SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode) +{ + return ksys_fchmod(fd, mode); +} + +int do_fchmodat(int dfd, const char __user *filename, umode_t mode) { struct path path; int error; @@ -582,9 +587,15 @@ retry: return error; } +SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, + umode_t, mode) +{ + return do_fchmodat(dfd, filename, mode); +} + SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode) { - return sys_fchmodat(AT_FDCWD, filename, mode); + return do_fchmodat(AT_FDCWD, filename, mode); } static int chown_common(const struct path *path, uid_t user, gid_t group) diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 827ed917630c..dd6c306f4f00 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -953,6 +953,7 @@ int ksys_dup(unsigned int fildes); int ksys_chroot(const char __user *filename); ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count); int ksys_chdir(const char __user *filename); +int ksys_fchmod(unsigned int fd, umode_t mode); /* * The following kernel syscall equivalents are just wrappers to fs-internal @@ -1006,4 +1007,11 @@ static inline long ksys_link(const char __user *oldname, return do_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0); } +extern int do_fchmodat(int dfd, const char __user *filename, umode_t mode); + +static inline int ksys_chmod(const char __user *filename, umode_t mode) +{ + return do_fchmodat(AT_FDCWD, filename, mode); +} + #endif diff --git a/init/initramfs.c b/init/initramfs.c index 5855ab632b4e..16c3c23076e2 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -344,7 +344,7 @@ static int __init do_name(void) if (wfd >= 0) { sys_fchown(wfd, uid, gid); - sys_fchmod(wfd, mode); + ksys_fchmod(wfd, mode); if (body_len) sys_ftruncate(wfd, body_len); vcollected = kstrdup(collected, GFP_KERNEL); @@ -354,14 +354,14 @@ static int __init do_name(void) } else if (S_ISDIR(mode)) { ksys_mkdir(collected, mode); sys_chown(collected, uid, gid); - sys_chmod(collected, mode); + ksys_chmod(collected, mode); dir_add(collected, mtime); } else if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { if (maybe_link() == 0) { ksys_mknod(collected, mode, rdev); sys_chown(collected, uid, gid); - sys_chmod(collected, mode); + ksys_chmod(collected, mode); do_utime(collected, mtime); } } -- cgit v1.2.3-71-gd317 From cbfe20f565228966f0249f016752437df95df679 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:54 +0100 Subject: fs: add do_faccessat() helper and ksys_access() wrapper; remove in-kernel calls to syscall Using the fs-internal do_faccessat() helper allows us to get rid of fs-internal calls to the sys_faccessat() syscall. Introducing the ksys_access() wrapper allows us to avoid the in-kernel calls to the sys_access() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_access(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- fs/internal.h | 1 + fs/open.c | 9 +++++++-- include/linux/syscalls.h | 7 +++++++ init/main.c | 3 ++- 4 files changed, 17 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/fs/internal.h b/fs/internal.h index 2474bf460f96..26f4f05b52ef 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -119,6 +119,7 @@ extern struct file *do_filp_open(int dfd, struct filename *pathname, extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, const char *, const struct open_flags *); +long do_faccessat(int dfd, const char __user *filename, int mode); int do_fchmodat(int dfd, const char __user *filename, umode_t mode); extern int open_check_o_direct(struct file *f); diff --git a/fs/open.c b/fs/open.c index 6037f2bf418c..0fc8188be31a 100644 --- a/fs/open.c +++ b/fs/open.c @@ -350,7 +350,7 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) * We do this by temporarily clearing all FS-related capabilities and * switching the fsuid/fsgid around to the real ones. */ -SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) +long do_faccessat(int dfd, const char __user *filename, int mode) { const struct cred *old_cred; struct cred *override_cred; @@ -426,9 +426,14 @@ out: return res; } +SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) +{ + return do_faccessat(dfd, filename, mode); +} + SYSCALL_DEFINE2(access, const char __user *, filename, int, mode) { - return sys_faccessat(AT_FDCWD, filename, mode); + return do_faccessat(AT_FDCWD, filename, mode); } int ksys_chdir(const char __user *filename) diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index dd6c306f4f00..33f06de090ea 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -1014,4 +1014,11 @@ static inline int ksys_chmod(const char __user *filename, umode_t mode) return do_fchmodat(AT_FDCWD, filename, mode); } +extern long do_faccessat(int dfd, const char __user *filename, int mode); + +static inline long ksys_access(const char __user *filename, int mode) +{ + return do_faccessat(AT_FDCWD, filename, mode); +} + #endif diff --git a/init/main.c b/init/main.c index b8649d1466e1..d0ded4322c6b 100644 --- a/init/main.c +++ b/init/main.c @@ -1087,7 +1087,8 @@ static noinline void __init kernel_init_freeable(void) if (!ramdisk_execute_command) ramdisk_execute_command = "/init"; - if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) { + if (ksys_access((const char __user *) + ramdisk_execute_command, 0) != 0) { ramdisk_execute_command = NULL; prepare_namespace(); } -- cgit v1.2.3-71-gd317 From 55731b3cda3a85ee888dac3bf1f36489f275c187 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:55 +0100 Subject: fs: add do_fchownat(), ksys_fchown() helpers and ksys_{,l}chown() wrappers Using the fs-interal do_fchownat() wrapper allows us to get rid of fs-internal calls to the sys_fchownat() syscall. Introducing the ksys_fchown() helper and the ksys_{,}chown() wrappers allows us to avoid the in-kernel calls to the sys_{,l,f}chown() syscalls. The ksys_ prefix denotes that these functions are meant as a drop-in replacement for the syscalls. In particular, they use the same calling convention as sys_{,l,f}chown(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- arch/s390/kernel/compat_linux.c | 6 +++--- fs/internal.h | 2 ++ fs/open.c | 23 +++++++++++++++++------ include/linux/syscalls.h | 17 +++++++++++++++++ init/initramfs.c | 8 ++++---- kernel/uid16.c | 6 +++--- 6 files changed, 46 insertions(+), 16 deletions(-) (limited to 'include/linux') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 5a9cfde5fc28..9a9bb395359c 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -89,18 +89,18 @@ COMPAT_SYSCALL_DEFINE3(s390_chown16, const char __user *, filename, u16, user, u16, group) { - return sys_chown(filename, low2highuid(user), low2highgid(group)); + return ksys_chown(filename, low2highuid(user), low2highgid(group)); } COMPAT_SYSCALL_DEFINE3(s390_lchown16, const char __user *, filename, u16, user, u16, group) { - return sys_lchown(filename, low2highuid(user), low2highgid(group)); + return ksys_lchown(filename, low2highuid(user), low2highgid(group)); } COMPAT_SYSCALL_DEFINE3(s390_fchown16, unsigned int, fd, u16, user, u16, group) { - return sys_fchown(fd, low2highuid(user), low2highgid(group)); + return ksys_fchown(fd, low2highuid(user), low2highgid(group)); } COMPAT_SYSCALL_DEFINE2(s390_setregid16, u16, rgid, u16, egid) diff --git a/fs/internal.h b/fs/internal.h index 26f4f05b52ef..c797480cbd6f 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -121,6 +121,8 @@ extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, long do_faccessat(int dfd, const char __user *filename, int mode); int do_fchmodat(int dfd, const char __user *filename, umode_t mode); +int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group, + int flag); extern int open_check_o_direct(struct file *f); extern int vfs_open(const struct path *, struct file *, const struct cred *); diff --git a/fs/open.c b/fs/open.c index 0fc8188be31a..7b2eccb541f2 100644 --- a/fs/open.c +++ b/fs/open.c @@ -645,8 +645,8 @@ retry_deleg: return error; } -SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user, - gid_t, group, int, flag) +int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group, + int flag) { struct path path; int error = -EINVAL; @@ -677,18 +677,24 @@ out: return error; } +SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user, + gid_t, group, int, flag) +{ + return do_fchownat(dfd, filename, user, group, flag); +} + SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group) { - return sys_fchownat(AT_FDCWD, filename, user, group, 0); + return do_fchownat(AT_FDCWD, filename, user, group, 0); } SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group) { - return sys_fchownat(AT_FDCWD, filename, user, group, - AT_SYMLINK_NOFOLLOW); + return do_fchownat(AT_FDCWD, filename, user, group, + AT_SYMLINK_NOFOLLOW); } -SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) +int ksys_fchown(unsigned int fd, uid_t user, gid_t group) { struct fd f = fdget(fd); int error = -EBADF; @@ -708,6 +714,11 @@ out: return error; } +SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) +{ + return ksys_fchown(fd, user, group); +} + int open_check_o_direct(struct file *f) { /* NB: we're sure to have correct a_ops only after f_op->open */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 33f06de090ea..df0d1e818a6e 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -954,6 +954,7 @@ int ksys_chroot(const char __user *filename); ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count); int ksys_chdir(const char __user *filename); int ksys_fchmod(unsigned int fd, umode_t mode); +int ksys_fchown(unsigned int fd, uid_t user, gid_t group); /* * The following kernel syscall equivalents are just wrappers to fs-internal @@ -1021,4 +1022,20 @@ static inline long ksys_access(const char __user *filename, int mode) return do_faccessat(AT_FDCWD, filename, mode); } +extern int do_fchownat(int dfd, const char __user *filename, uid_t user, + gid_t group, int flag); + +static inline long ksys_chown(const char __user *filename, uid_t user, + gid_t group) +{ + return do_fchownat(AT_FDCWD, filename, user, group, 0); +} + +static inline long ksys_lchown(const char __user *filename, uid_t user, + gid_t group) +{ + return do_fchownat(AT_FDCWD, filename, user, group, + AT_SYMLINK_NOFOLLOW); +} + #endif diff --git a/init/initramfs.c b/init/initramfs.c index 16c3c23076e2..35173bef7c00 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -343,7 +343,7 @@ static int __init do_name(void) wfd = sys_open(collected, openflags, mode); if (wfd >= 0) { - sys_fchown(wfd, uid, gid); + ksys_fchown(wfd, uid, gid); ksys_fchmod(wfd, mode); if (body_len) sys_ftruncate(wfd, body_len); @@ -353,14 +353,14 @@ static int __init do_name(void) } } else if (S_ISDIR(mode)) { ksys_mkdir(collected, mode); - sys_chown(collected, uid, gid); + ksys_chown(collected, uid, gid); ksys_chmod(collected, mode); dir_add(collected, mtime); } else if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { if (maybe_link() == 0) { ksys_mknod(collected, mode, rdev); - sys_chown(collected, uid, gid); + ksys_chown(collected, uid, gid); ksys_chmod(collected, mode); do_utime(collected, mtime); } @@ -393,7 +393,7 @@ static int __init do_symlink(void) collected[N_ALIGN(name_len) + body_len] = '\0'; clean_path(collected, 0); ksys_symlink(collected + N_ALIGN(name_len), collected); - sys_lchown(collected, uid, gid); + ksys_lchown(collected, uid, gid); do_utime(collected, mtime); state = SkipIt; next_state = Reset; diff --git a/kernel/uid16.c b/kernel/uid16.c index 7b930edfe461..af6925d8599b 100644 --- a/kernel/uid16.c +++ b/kernel/uid16.c @@ -22,17 +22,17 @@ SYSCALL_DEFINE3(chown16, const char __user *, filename, old_uid_t, user, old_gid_t, group) { - return sys_chown(filename, low2highuid(user), low2highgid(group)); + return ksys_chown(filename, low2highuid(user), low2highgid(group)); } SYSCALL_DEFINE3(lchown16, const char __user *, filename, old_uid_t, user, old_gid_t, group) { - return sys_lchown(filename, low2highuid(user), low2highgid(group)); + return ksys_lchown(filename, low2highuid(user), low2highgid(group)); } SYSCALL_DEFINE3(fchown16, unsigned int, fd, old_uid_t, user, old_gid_t, group) { - return sys_fchown(fd, low2highuid(user), low2highgid(group)); + return ksys_fchown(fd, low2highuid(user), low2highgid(group)); } SYSCALL_DEFINE2(setregid16, old_gid_t, rgid, old_gid_t, egid) -- cgit v1.2.3-71-gd317 From 411d9475cf901b5a6d2996b46cb5726184a4fa50 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:54 +0100 Subject: fs: add ksys_ftruncate() wrapper; remove in-kernel calls to sys_ftruncate() Using the ksys_ftruncate() wrapper allows us to get rid of in-kernel calls to the sys_ftruncate() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_ftruncate(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- arch/mips/kernel/linux32.c | 2 +- arch/parisc/kernel/sys_parisc.c | 4 ++-- arch/powerpc/kernel/sys_ppc32.c | 2 +- arch/s390/kernel/compat_linux.c | 2 +- arch/sparc/kernel/sys_sparc32.c | 2 +- arch/x86/ia32/sys_ia32.c | 2 +- fs/internal.h | 1 + fs/open.c | 2 +- include/linux/syscalls.h | 7 +++++++ init/initramfs.c | 2 +- 10 files changed, 17 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index b332f6fc1e72..3c90449742a0 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -88,7 +88,7 @@ SYSCALL_DEFINE4(32_truncate64, const char __user *, path, SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy, unsigned long, a2, unsigned long, a3) { - return sys_ftruncate(fd, merge_64(a2, a3)); + return ksys_ftruncate(fd, merge_64(a2, a3)); } SYSCALL_DEFINE5(32_llseek, unsigned int, fd, unsigned int, offset_high, diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 378a754ca186..6d2a64859c22 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -298,7 +298,7 @@ asmlinkage long parisc_truncate64(const char __user * path, asmlinkage long parisc_ftruncate64(unsigned int fd, unsigned int high, unsigned int low) { - return sys_ftruncate(fd, (long)high << 32 | low); + return ksys_ftruncate(fd, (long)high << 32 | low); } /* stubs for the benefit of the syscall_table since truncate64 and truncate @@ -309,7 +309,7 @@ asmlinkage long sys_truncate64(const char __user * path, unsigned long length) } asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length) { - return sys_ftruncate(fd, length); + return ksys_ftruncate(fd, length); } asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) { diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 15f216d022e2..e0c9b7f1bf38 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -107,7 +107,7 @@ asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long high, unsigned long low) { - return sys_ftruncate(fd, (high << 32) | low); + return ksys_ftruncate(fd, (high << 32) | low); } long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low, diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 9a9bb395359c..9c5e975f71a6 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -307,7 +307,7 @@ COMPAT_SYSCALL_DEFINE3(s390_truncate64, const char __user *, path, u32, high, u3 COMPAT_SYSCALL_DEFINE3(s390_ftruncate64, unsigned int, fd, u32, high, u32, low) { - return sys_ftruncate(fd, (unsigned long)high << 32 | low); + return ksys_ftruncate(fd, (unsigned long)high << 32 | low); } COMPAT_SYSCALL_DEFINE5(s390_pread64, unsigned int, fd, char __user *, ubuf, diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index 6d964bdefbaa..d64b425fff93 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -65,7 +65,7 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned if ((int)high < 0) return -EINVAL; else - return sys_ftruncate(fd, (high << 32) | low); + return ksys_ftruncate(fd, (high << 32) | low); } static int cp_compat_stat64(struct kstat *stat, diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index 23a5260eae67..1979e5b4ad9a 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -61,7 +61,7 @@ COMPAT_SYSCALL_DEFINE3(x86_truncate64, const char __user *, filename, COMPAT_SYSCALL_DEFINE3(x86_ftruncate64, unsigned int, fd, unsigned long, offset_low, unsigned long, offset_high) { - return sys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low); + return ksys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low); } /* diff --git a/fs/internal.h b/fs/internal.h index c797480cbd6f..980d005b21b4 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -119,6 +119,7 @@ extern struct file *do_filp_open(int dfd, struct filename *pathname, extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, const char *, const struct open_flags *); +long do_sys_ftruncate(unsigned int fd, loff_t length, int small); long do_faccessat(int dfd, const char __user *filename, int mode); int do_fchmodat(int dfd, const char __user *filename, umode_t mode); int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group, diff --git a/fs/open.c b/fs/open.c index 7b2eccb541f2..b3f3b2cd9f19 100644 --- a/fs/open.c +++ b/fs/open.c @@ -162,7 +162,7 @@ COMPAT_SYSCALL_DEFINE2(truncate, const char __user *, path, compat_off_t, length } #endif -static long do_sys_ftruncate(unsigned int fd, loff_t length, int small) +long do_sys_ftruncate(unsigned int fd, loff_t length, int small) { struct inode *inode; struct dentry *dentry; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index df0d1e818a6e..41023177c8ec 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -1038,4 +1038,11 @@ static inline long ksys_lchown(const char __user *filename, uid_t user, AT_SYMLINK_NOFOLLOW); } +extern long do_sys_ftruncate(unsigned int fd, loff_t length, int small); + +static inline long ksys_ftruncate(unsigned int fd, unsigned long length) +{ + return do_sys_ftruncate(fd, length, 1); +} + #endif diff --git a/init/initramfs.c b/init/initramfs.c index 35173bef7c00..0d3b001b0dc5 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -346,7 +346,7 @@ static int __init do_name(void) ksys_fchown(wfd, uid, gid); ksys_fchmod(wfd, mode); if (body_len) - sys_ftruncate(wfd, body_len); + ksys_ftruncate(wfd, body_len); vcollected = kstrdup(collected, GFP_KERNEL); state = CopyFile; } -- cgit v1.2.3-71-gd317 From 2ca2a09d6215fd9621aa3e2db7cc9428a61f2911 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:55 +0100 Subject: fs: add ksys_close() wrapper; remove in-kernel calls to sys_close() Using the ksys_close() wrapper allows us to get rid of in-kernel calls to the sys_close() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_close(), with one subtle difference: The few places which checked the return value did not care about the return value re-writing in sys_close(), so simply use a wrapper around __close_fd(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- fs/autofs4/dev-ioctl.c | 2 +- fs/binfmt_misc.c | 2 +- fs/file.c | 1 + fs/open.c | 1 - include/linux/syscalls.h | 12 ++++++++++++ init/do_mounts.c | 4 ++-- init/do_mounts_initrd.c | 2 +- init/do_mounts_md.c | 8 ++++---- init/do_mounts_rd.c | 6 +++--- init/initramfs.c | 8 ++++---- 10 files changed, 29 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index b7c816f39404..26f6b4f41ce6 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c @@ -310,7 +310,7 @@ static int autofs_dev_ioctl_closemount(struct file *fp, struct autofs_sb_info *sbi, struct autofs_dev_ioctl *param) { - return sys_close(param->ioctlfd); + return ksys_close(param->ioctlfd); } /* diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index a7c5a9861bef..a41b48f82a70 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -241,7 +241,7 @@ ret: return retval; error: if (fd_binary > 0) - sys_close(fd_binary); + ksys_close(fd_binary); bprm->interp_flags = 0; bprm->interp_data = 0; goto ret; diff --git a/fs/file.c b/fs/file.c index d304004f0b65..7ffd6e9d103d 100644 --- a/fs/file.c +++ b/fs/file.c @@ -638,6 +638,7 @@ out_unlock: spin_unlock(&files->file_lock); return -EBADF; } +EXPORT_SYMBOL(__close_fd); /* for ksys_close() */ void do_close_on_exec(struct files_struct *files) { diff --git a/fs/open.c b/fs/open.c index b3f3b2cd9f19..710102fc262b 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1200,7 +1200,6 @@ SYSCALL_DEFINE1(close, unsigned int, fd) return retval; } -EXPORT_SYMBOL(sys_close); /* * This routine simulates a hangup on the tty, to arrange that users diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 41023177c8ec..38805f3447ea 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -1045,4 +1045,16 @@ static inline long ksys_ftruncate(unsigned int fd, unsigned long length) return do_sys_ftruncate(fd, length, 1); } +extern int __close_fd(struct files_struct *files, unsigned int fd); + +/* + * In contrast to sys_close(), this stub does not check whether the syscall + * should or should not be restarted, but returns the raw error codes from + * __close_fd(). + */ +static inline int ksys_close(unsigned int fd) +{ + return __close_fd(current->files, fd); +} + #endif diff --git a/init/do_mounts.c b/init/do_mounts.c index 89f18985fa90..a28dd42d1f84 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -492,7 +492,7 @@ void __init change_floppy(char *fmt, ...) fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); if (fd >= 0) { sys_ioctl(fd, FDEJECT, 0); - sys_close(fd); + ksys_close(fd); } printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); fd = sys_open("/dev/console", O_RDWR, 0); @@ -503,7 +503,7 @@ void __init change_floppy(char *fmt, ...) sys_read(fd, &c, 1); termios.c_lflag |= ICANON; sys_ioctl(fd, TCSETSF, (long)&termios); - sys_close(fd); + ksys_close(fd); } } #endif diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 99922d1ebfe6..6907c6dbc443 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -111,7 +111,7 @@ static void __init handle_initrd(void) error = fd; } else { error = sys_ioctl(fd, BLKFLSBUF, 0); - sys_close(fd); + ksys_close(fd); } printk(!error ? "okay\n" : "failed\n"); } diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c index 3f733c760a8c..ebd4013d589e 100644 --- a/init/do_mounts_md.c +++ b/init/do_mounts_md.c @@ -191,7 +191,7 @@ static void __init md_setup_drive(void) printk(KERN_WARNING "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n", minor); - sys_close(fd); + ksys_close(fd); continue; } @@ -243,11 +243,11 @@ static void __init md_setup_drive(void) * boot a kernel with devfs compiled in from partitioned md * array without it */ - sys_close(fd); + ksys_close(fd); fd = sys_open(name, 0, 0); sys_ioctl(fd, BLKRRPART, 0); } - sys_close(fd); + ksys_close(fd); } } @@ -297,7 +297,7 @@ static void __init autodetect_raid(void) fd = sys_open("/dev/md0", 0, 0); if (fd >= 0) { sys_ioctl(fd, RAID_AUTORUN, raid_autopart); - sys_close(fd); + ksys_close(fd); } } diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 5b69056f610a..f1aa341862d3 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -257,7 +257,7 @@ int __init rd_load_image(char *from) if (i && (i % devblocks == 0)) { printk("done disk #%d.\n", disk++); rotate = 0; - if (sys_close(in_fd)) { + if (ksys_close(in_fd)) { printk("Error closing the disk.\n"); goto noclose_input; } @@ -283,9 +283,9 @@ int __init rd_load_image(char *from) successful_load: res = 1; done: - sys_close(in_fd); + ksys_close(in_fd); noclose_input: - sys_close(out_fd); + ksys_close(out_fd); out: kfree(buf); ksys_unlink("/dev/ram"); diff --git a/init/initramfs.c b/init/initramfs.c index 0d3b001b0dc5..ce2bcad97cdf 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -373,7 +373,7 @@ static int __init do_copy(void) if (byte_count >= body_len) { if (xwrite(wfd, victim, body_len) != body_len) error("write error"); - sys_close(wfd); + ksys_close(wfd); do_utime(vcollected, mtime); kfree(vcollected); eat(body_len); @@ -574,7 +574,7 @@ static void __init clean_rootfs(void) buf = kzalloc(BUF_SIZE, GFP_KERNEL); WARN_ON(!buf); if (!buf) { - sys_close(fd); + ksys_close(fd); return; } @@ -602,7 +602,7 @@ static void __init clean_rootfs(void) num = sys_getdents64(fd, dirp, BUF_SIZE); } - sys_close(fd); + ksys_close(fd); kfree(buf); } #endif @@ -639,7 +639,7 @@ static int __init populate_rootfs(void) pr_err("/initrd.image: incomplete write (%zd != %ld)\n", written, initrd_end - initrd_start); - sys_close(fd); + ksys_close(fd); free_initrd(); } done: -- cgit v1.2.3-71-gd317 From bae217ea8c7e123ed3fb1064909a262924771bbb Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:56 +0100 Subject: fs: add ksys_open() wrapper; remove in-kernel calls to sys_open() Using this wrapper allows us to avoid the in-kernel calls to the sys_open() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_open(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- fs/open.c | 2 +- include/linux/syscalls.h | 11 +++++++++++ init/do_mounts.c | 4 ++-- init/do_mounts_initrd.c | 4 ++-- init/do_mounts_md.c | 6 +++--- init/do_mounts_rd.c | 6 +++--- init/initramfs.c | 6 +++--- init/main.c | 2 +- 8 files changed, 26 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/fs/open.c b/fs/open.c index 710102fc262b..8a42a2961130 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1151,7 +1151,7 @@ COMPAT_SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, fla */ SYSCALL_DEFINE2(creat, const char __user *, pathname, umode_t, mode) { - return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); + return ksys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); } #endif diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 38805f3447ea..f9df17dcec1c 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -1057,4 +1057,15 @@ static inline int ksys_close(unsigned int fd) return __close_fd(current->files, fd); } +extern long do_sys_open(int dfd, const char __user *filename, int flags, + umode_t mode); + +static inline long ksys_open(const char __user *filename, int flags, + umode_t mode) +{ + if (force_o_largefile()) + flags |= O_LARGEFILE; + return do_sys_open(AT_FDCWD, filename, flags, mode); +} + #endif diff --git a/init/do_mounts.c b/init/do_mounts.c index a28dd42d1f84..cc1103477071 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -489,13 +489,13 @@ void __init change_floppy(char *fmt, ...) va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); - fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); + fd = ksys_open("/dev/root", O_RDWR | O_NDELAY, 0); if (fd >= 0) { sys_ioctl(fd, FDEJECT, 0); ksys_close(fd); } printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); - fd = sys_open("/dev/console", O_RDWR, 0); + fd = ksys_open("/dev/console", O_RDWR, 0); if (fd >= 0) { sys_ioctl(fd, TCGETS, (long)&termios); termios.c_lflag &= ~ICANON; diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 6907c6dbc443..cedca8fd2590 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -38,7 +38,7 @@ static int init_linuxrc(struct subprocess_info *info, struct cred *new) { sys_unshare(CLONE_FS | CLONE_FILES); /* stdin/stdout/stderr for /linuxrc */ - sys_open("/dev/console", O_RDWR, 0); + ksys_open("/dev/console", O_RDWR, 0); ksys_dup(0); ksys_dup(0); /* move initrd over / and chdir/chroot in initrd root */ @@ -99,7 +99,7 @@ static void __init handle_initrd(void) if (!error) printk("okay\n"); else { - int fd = sys_open("/dev/root.old", O_RDWR, 0); + int fd = ksys_open("/dev/root.old", O_RDWR, 0); if (error == -ENOENT) printk("/initrd does not exist. Ignored.\n"); else diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c index ebd4013d589e..76dcfaada3ed 100644 --- a/init/do_mounts_md.c +++ b/init/do_mounts_md.c @@ -181,7 +181,7 @@ static void __init md_setup_drive(void) partitioned ? "_d" : "", minor, md_setup_args[ent].device_names); - fd = sys_open(name, 0, 0); + fd = ksys_open(name, 0, 0); if (fd < 0) { printk(KERN_ERR "md: open failed - cannot start " "array %s\n", name); @@ -244,7 +244,7 @@ static void __init md_setup_drive(void) * array without it */ ksys_close(fd); - fd = sys_open(name, 0, 0); + fd = ksys_open(name, 0, 0); sys_ioctl(fd, BLKRRPART, 0); } ksys_close(fd); @@ -294,7 +294,7 @@ static void __init autodetect_raid(void) wait_for_device_probe(); - fd = sys_open("/dev/md0", 0, 0); + fd = ksys_open("/dev/md0", 0, 0); if (fd >= 0) { sys_ioctl(fd, RAID_AUTORUN, raid_autopart); ksys_close(fd); diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index f1aa341862d3..a6706314baa7 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -196,11 +196,11 @@ int __init rd_load_image(char *from) char rotator[4] = { '|' , '/' , '-' , '\\' }; #endif - out_fd = sys_open("/dev/ram", O_RDWR, 0); + out_fd = ksys_open("/dev/ram", O_RDWR, 0); if (out_fd < 0) goto out; - in_fd = sys_open(from, O_RDONLY, 0); + in_fd = ksys_open(from, O_RDONLY, 0); if (in_fd < 0) goto noclose_input; @@ -262,7 +262,7 @@ int __init rd_load_image(char *from) goto noclose_input; } change_floppy("disk #%d", disk); - in_fd = sys_open(from, O_RDONLY, 0); + in_fd = ksys_open(from, O_RDONLY, 0); if (in_fd < 0) { printk("Error opening disk.\n"); goto noclose_input; diff --git a/init/initramfs.c b/init/initramfs.c index ce2bcad97cdf..5f2ff1d2370e 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -340,7 +340,7 @@ static int __init do_name(void) int openflags = O_WRONLY|O_CREAT; if (ml != 1) openflags |= O_TRUNC; - wfd = sys_open(collected, openflags, mode); + wfd = ksys_open(collected, openflags, mode); if (wfd >= 0) { ksys_fchown(wfd, uid, gid); @@ -567,7 +567,7 @@ static void __init clean_rootfs(void) struct linux_dirent64 *dirp; int num; - fd = sys_open("/", O_RDONLY, 0); + fd = ksys_open("/", O_RDONLY, 0); WARN_ON(fd < 0); if (fd < 0) return; @@ -629,7 +629,7 @@ static int __init populate_rootfs(void) } printk(KERN_INFO "rootfs image is not initramfs (%s)" "; looks like an initrd\n", err); - fd = sys_open("/initrd.image", + fd = ksys_open("/initrd.image", O_WRONLY|O_CREAT, 0700); if (fd >= 0) { ssize_t written = xwrite(fd, (char *)initrd_start, diff --git a/init/main.c b/init/main.c index d0ded4322c6b..e77951ae2c19 100644 --- a/init/main.c +++ b/init/main.c @@ -1074,7 +1074,7 @@ static noinline void __init kernel_init_freeable(void) do_basic_setup(); /* Open the /dev/console on the rootfs, this should never fail */ - if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) + if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) pr_err("Warning: unable to open an initial console.\n"); (void) ksys_dup(0); -- cgit v1.2.3-71-gd317 From 454dab3f965ec24fda8fbe135c8dad4c5b238a86 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 21:34:04 +0100 Subject: fs: add ksys_getdents64() helper; remove in-kernel calls to sys_getdents64() Using this helper allows us to avoid the in-kernel calls to the sys_getdents64() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_getdents64(). 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: Alexander Viro Signed-off-by: Dominik Brodowski --- fs/readdir.c | 11 +++++++++-- include/linux/syscalls.h | 2 ++ init/initramfs.c | 4 ++-- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/fs/readdir.c b/fs/readdir.c index 1b83b0ad183b..d97f548e6323 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -292,8 +292,8 @@ efault: return -EFAULT; } -SYSCALL_DEFINE3(getdents64, unsigned int, fd, - struct linux_dirent64 __user *, dirent, unsigned int, count) +int ksys_getdents64(unsigned int fd, struct linux_dirent64 __user *dirent, + unsigned int count) { struct fd f; struct linux_dirent64 __user * lastdirent; @@ -326,6 +326,13 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd, return error; } + +SYSCALL_DEFINE3(getdents64, unsigned int, fd, + struct linux_dirent64 __user *, dirent, unsigned int, count) +{ + return ksys_getdents64(fd, dirent, count); +} + #ifdef CONFIG_COMPAT struct compat_old_linux_dirent { compat_ulong_t d_ino; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index f9df17dcec1c..c056aff6d7ad 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -955,6 +955,8 @@ ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count); int ksys_chdir(const char __user *filename); int ksys_fchmod(unsigned int fd, umode_t mode); int ksys_fchown(unsigned int fd, uid_t user, gid_t group); +int ksys_getdents64(unsigned int fd, struct linux_dirent64 __user *dirent, + unsigned int count); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/init/initramfs.c b/init/initramfs.c index 5f2ff1d2370e..13643c46ebab 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -579,7 +579,7 @@ static void __init clean_rootfs(void) } dirp = buf; - num = sys_getdents64(fd, dirp, BUF_SIZE); + num = ksys_getdents64(fd, dirp, BUF_SIZE); while (num > 0) { while (num > 0) { struct kstat st; @@ -599,7 +599,7 @@ static void __init clean_rootfs(void) } dirp = buf; memset(buf, 0, BUF_SIZE); - num = sys_getdents64(fd, dirp, BUF_SIZE); + num = ksys_getdents64(fd, dirp, BUF_SIZE); } ksys_close(fd); -- cgit v1.2.3-71-gd317 From cbb60b924b9f3e4d7c67a1c9dcf981718f926e4e Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 21:43:59 +0100 Subject: fs: add ksys_ioctl() helper; remove in-kernel calls to sys_ioctl() Using this helper allows us to avoid the in-kernel calls to the sys_ioctl() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_ioctl(). After careful review, at least some of these calls could be converted to do_vfs_ioctl() in future. 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: Alexander Viro Signed-off-by: Dominik Brodowski --- fs/ioctl.c | 7 ++++++- include/linux/syscalls.h | 1 + init/do_mounts.c | 8 ++++---- init/do_mounts_initrd.c | 2 +- init/do_mounts_md.c | 15 ++++++++------- init/do_mounts_rd.c | 4 ++-- 6 files changed, 22 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/fs/ioctl.c b/fs/ioctl.c index 5ace7efb0d04..4823431d1c9d 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -689,7 +689,7 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, return error; } -SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) +int ksys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { int error; struct fd f = fdget(fd); @@ -702,3 +702,8 @@ SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) fdput(f); return error; } + +SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) +{ + return ksys_ioctl(fd, cmd, arg); +} diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index c056aff6d7ad..5a959efd8fb7 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -957,6 +957,7 @@ int ksys_fchmod(unsigned int fd, umode_t mode); int ksys_fchown(unsigned int fd, uid_t user, gid_t group); int ksys_getdents64(unsigned int fd, struct linux_dirent64 __user *dirent, unsigned int count); +int ksys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/init/do_mounts.c b/init/do_mounts.c index cc1103477071..b17e0095eb4e 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -491,18 +491,18 @@ void __init change_floppy(char *fmt, ...) va_end(args); fd = ksys_open("/dev/root", O_RDWR | O_NDELAY, 0); if (fd >= 0) { - sys_ioctl(fd, FDEJECT, 0); + ksys_ioctl(fd, FDEJECT, 0); ksys_close(fd); } printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); fd = ksys_open("/dev/console", O_RDWR, 0); if (fd >= 0) { - sys_ioctl(fd, TCGETS, (long)&termios); + ksys_ioctl(fd, TCGETS, (long)&termios); termios.c_lflag &= ~ICANON; - sys_ioctl(fd, TCSETSF, (long)&termios); + ksys_ioctl(fd, TCSETSF, (long)&termios); sys_read(fd, &c, 1); termios.c_lflag |= ICANON; - sys_ioctl(fd, TCSETSF, (long)&termios); + ksys_ioctl(fd, TCSETSF, (long)&termios); ksys_close(fd); } } diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index cedca8fd2590..03ec0c1b7553 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -110,7 +110,7 @@ static void __init handle_initrd(void) if (fd < 0) { error = fd; } else { - error = sys_ioctl(fd, BLKFLSBUF, 0); + error = ksys_ioctl(fd, BLKFLSBUF, 0); ksys_close(fd); } printk(!error ? "okay\n" : "failed\n"); diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c index 76dcfaada3ed..7d85d172bc7e 100644 --- a/init/do_mounts_md.c +++ b/init/do_mounts_md.c @@ -187,7 +187,7 @@ static void __init md_setup_drive(void) "array %s\n", name); continue; } - if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) { + if (ksys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) { printk(KERN_WARNING "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n", minor); @@ -210,7 +210,7 @@ static void __init md_setup_drive(void) ainfo.state = (1 << MD_SB_CLEAN); ainfo.layout = 0; ainfo.chunk_size = md_setup_args[ent].chunk; - err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo); + err = ksys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo); for (i = 0; !err && i <= MD_SB_DISKS; i++) { dev = devices[i]; if (!dev) @@ -220,7 +220,8 @@ static void __init md_setup_drive(void) dinfo.state = (1<= 0) { - sys_ioctl(fd, RAID_AUTORUN, raid_autopart); + ksys_ioctl(fd, RAID_AUTORUN, raid_autopart); ksys_close(fd); } } diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index a6706314baa7..4dafaed5736f 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -218,7 +218,7 @@ int __init rd_load_image(char *from) * NOTE NOTE: nblocks is not actually blocks but * the number of kibibytes of data to load into a ramdisk. */ - if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0) + if (ksys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0) rd_blocks = 0; else rd_blocks >>= 1; @@ -232,7 +232,7 @@ int __init rd_load_image(char *from) /* * OK, time to copy in the data */ - if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0) + if (ksys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0) devblocks = 0; else devblocks >>= 1; -- cgit v1.2.3-71-gd317 From 76847e4344350970e1c2e27c28b5abb3c588c5b3 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 21:51:17 +0100 Subject: fs: add ksys_lseek() helper; remove in-kernel calls to sys_lseek() Using this helper allows us to avoid the in-kernel calls to the sys_lseek() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_lseek(). 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: Alexander Viro Signed-off-by: Dominik Brodowski --- fs/read_write.c | 9 +++++++-- include/linux/syscalls.h | 1 + init/do_mounts_rd.c | 8 ++++---- 3 files changed, 12 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/fs/read_write.c b/fs/read_write.c index 8e8f0b4f52e2..b38b008a078e 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -301,7 +301,7 @@ loff_t vfs_llseek(struct file *file, loff_t offset, int whence) } EXPORT_SYMBOL(vfs_llseek); -SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence) +off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence) { off_t retval; struct fd f = fdget_pos(fd); @@ -319,10 +319,15 @@ SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence) return retval; } +SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence) +{ + return ksys_lseek(fd, offset, whence); +} + #ifdef CONFIG_COMPAT COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, compat_off_t, offset, unsigned int, whence) { - return sys_lseek(fd, offset, whence); + return ksys_lseek(fd, offset, whence); } #endif diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 5a959efd8fb7..0f24e5334569 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -958,6 +958,7 @@ int ksys_fchown(unsigned int fd, uid_t user, gid_t group); int ksys_getdents64(unsigned int fd, struct linux_dirent64 __user *dirent, unsigned int count); int ksys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); +off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 4dafaed5736f..13e54148c0e0 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -90,7 +90,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) /* * Read block 0 to test for compressed kernel */ - sys_lseek(fd, start_block * BLOCK_SIZE, 0); + ksys_lseek(fd, start_block * BLOCK_SIZE, 0); sys_read(fd, buf, size); *decompressor = decompress_method(buf, size, &compress_name); @@ -136,7 +136,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) /* * Read 512 bytes further to check if cramfs is padded */ - sys_lseek(fd, start_block * BLOCK_SIZE + 0x200, 0); + ksys_lseek(fd, start_block * BLOCK_SIZE + 0x200, 0); sys_read(fd, buf, size); if (cramfsb->magic == CRAMFS_MAGIC) { @@ -150,7 +150,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) /* * Read block 1 to test for minix and ext2 superblock */ - sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0); + ksys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0); sys_read(fd, buf, size); /* Try minix */ @@ -178,7 +178,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) start_block); done: - sys_lseek(fd, start_block * BLOCK_SIZE, 0); + ksys_lseek(fd, start_block * BLOCK_SIZE, 0); kfree(buf); return nblocks; } -- cgit v1.2.3-71-gd317 From 3ce4a7bf66263748194b77ccefd284be963c6304 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 21:56:26 +0100 Subject: fs: add ksys_read() helper; remove in-kernel calls to sys_read() Using this helper allows us to avoid the in-kernel calls to the sys_read() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_read(). 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: Alexander Viro Signed-off-by: Dominik Brodowski --- arch/s390/kernel/compat_linux.c | 2 +- fs/read_write.c | 7 ++++++- include/linux/syscalls.h | 1 + init/do_mounts.c | 2 +- init/do_mounts_rd.c | 10 +++++----- 5 files changed, 14 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 9c5e975f71a6..af0469f204fd 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -460,7 +460,7 @@ COMPAT_SYSCALL_DEFINE3(s390_read, unsigned int, fd, char __user *, buf, compat_s if ((compat_ssize_t) count < 0) return -EINVAL; - return sys_read(fd, buf, count); + return ksys_read(fd, buf, count); } COMPAT_SYSCALL_DEFINE3(s390_write, unsigned int, fd, const char __user *, buf, compat_size_t, count) diff --git a/fs/read_write.c b/fs/read_write.c index b38b008a078e..fc441e1ac683 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -568,7 +568,7 @@ static inline void file_pos_write(struct file *file, loff_t pos) file->f_pos = pos; } -SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) +ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count) { struct fd f = fdget_pos(fd); ssize_t ret = -EBADF; @@ -583,6 +583,11 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) return ret; } +SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) +{ + return ksys_read(fd, buf, count); +} + ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count) { struct fd f = fdget_pos(fd); diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 0f24e5334569..3a2e90842ff8 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -959,6 +959,7 @@ int ksys_getdents64(unsigned int fd, struct linux_dirent64 __user *dirent, unsigned int count); int ksys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence); +ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/init/do_mounts.c b/init/do_mounts.c index b17e0095eb4e..2c71dabe5626 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -500,7 +500,7 @@ void __init change_floppy(char *fmt, ...) ksys_ioctl(fd, TCGETS, (long)&termios); termios.c_lflag &= ~ICANON; ksys_ioctl(fd, TCSETSF, (long)&termios); - sys_read(fd, &c, 1); + ksys_read(fd, &c, 1); termios.c_lflag |= ICANON; ksys_ioctl(fd, TCSETSF, (long)&termios); ksys_close(fd); diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 13e54148c0e0..12c159824c7b 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -91,7 +91,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) * Read block 0 to test for compressed kernel */ ksys_lseek(fd, start_block * BLOCK_SIZE, 0); - sys_read(fd, buf, size); + ksys_read(fd, buf, size); *decompressor = decompress_method(buf, size, &compress_name); if (compress_name) { @@ -137,7 +137,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) * Read 512 bytes further to check if cramfs is padded */ ksys_lseek(fd, start_block * BLOCK_SIZE + 0x200, 0); - sys_read(fd, buf, size); + ksys_read(fd, buf, size); if (cramfsb->magic == CRAMFS_MAGIC) { printk(KERN_NOTICE @@ -151,7 +151,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) * Read block 1 to test for minix and ext2 superblock */ ksys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0); - sys_read(fd, buf, size); + ksys_read(fd, buf, size); /* Try minix */ if (minixsb->s_magic == MINIX_SUPER_MAGIC || @@ -269,7 +269,7 @@ int __init rd_load_image(char *from) } printk("Loading disk #%d... ", disk); } - sys_read(in_fd, buf, BLOCK_SIZE); + ksys_read(in_fd, buf, BLOCK_SIZE); ksys_write(out_fd, buf, BLOCK_SIZE); #if !defined(CONFIG_S390) if (!(i % 16)) { @@ -307,7 +307,7 @@ static int crd_infd, crd_outfd; static long __init compr_fill(void *buf, unsigned long len) { - long r = sys_read(crd_infd, buf, len); + long r = ksys_read(crd_infd, buf, len); if (r < 0) printk(KERN_ERR "RAMDISK: error while reading compressed data"); else if (r == 0) -- cgit v1.2.3-71-gd317 From 70f68ee81e2e9ad5105b8d2bd324e890e94c6ad9 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Wed, 14 Mar 2018 22:35:11 +0100 Subject: fs: add ksys_sync() helper; remove in-kernel calls to sys_sync() Using this helper allows us to avoid the in-kernel calls to the sys_sync() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_sync(). 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: Alexander Viro Signed-off-by: Dominik Brodowski --- arch/sparc/kernel/setup_32.c | 2 +- drivers/tty/sysrq.c | 2 +- fs/sync.c | 7 ++++++- include/linux/syscalls.h | 1 + kernel/power/hibernate.c | 2 +- kernel/power/suspend.c | 2 +- kernel/power/user.c | 2 +- 7 files changed, 12 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 2e3a3e203061..13664c377196 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -86,7 +86,7 @@ static void prom_sync_me(void) show_free_areas(0, NULL); if (!is_idle_task(current)) { local_irq_enable(); - sys_sync(); + ksys_sync(); local_irq_disable(); } prom_printf("Returning to prom\n"); diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index b674793be478..6364890575ec 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -660,7 +660,7 @@ static void sysrq_do_reset(struct timer_list *t) state->reset_requested = true; - sys_sync(); + ksys_sync(); kernel_restart(NULL); } diff --git a/fs/sync.c b/fs/sync.c index 6e0a2cbaf6de..602ae94bb67e 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -105,7 +105,7 @@ static void fdatawait_one_bdev(struct block_device *bdev, void *arg) * just write metadata (such as inodes or bitmaps) to block device page cache * and do not sync it on their own in ->sync_fs(). */ -SYSCALL_DEFINE0(sync) +void ksys_sync(void) { int nowait = 0, wait = 1; @@ -117,6 +117,11 @@ SYSCALL_DEFINE0(sync) iterate_bdevs(fdatawait_one_bdev, NULL); if (unlikely(laptop_mode)) laptop_sync_completion(); +} + +SYSCALL_DEFINE0(sync) +{ + ksys_sync(); return 0; } diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 3a2e90842ff8..0a9942b3e718 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -960,6 +960,7 @@ int ksys_getdents64(unsigned int fd, struct linux_dirent64 __user *dirent, int ksys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence); ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count); +void ksys_sync(void); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index a5c36e9c56a6..4710f1b142fc 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -701,7 +701,7 @@ int hibernate(void) } pr_info("Syncing filesystems ... \n"); - sys_sync(); + ksys_sync(); pr_info("done.\n"); error = freeze_processes(); diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 0685c4499431..4c10be0f4843 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -560,7 +560,7 @@ static int enter_state(suspend_state_t state) #ifndef CONFIG_SUSPEND_SKIP_SYNC trace_suspend_resume(TPS("sync_filesystems"), 0, true); pr_info("Syncing filesystems ... "); - sys_sync(); + ksys_sync(); pr_cont("done.\n"); trace_suspend_resume(TPS("sync_filesystems"), 0, false); #endif diff --git a/kernel/power/user.c b/kernel/power/user.c index 22df9f7ff672..75c959de4b29 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -224,7 +224,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, break; printk("Syncing filesystems ... "); - sys_sync(); + ksys_sync(); printk("done.\n"); error = freeze_processes(); -- cgit v1.2.3-71-gd317 From 9b32105ec6b13d32d5db6a6e7992c97ce54b5ea7 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:42 +0100 Subject: kernel: add ksys_unshare() helper; remove in-kernel calls to sys_unshare() Using this helper allows us to avoid the in-kernel calls to the sys_unshare() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_unshare(). 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: Al Viro Cc: Andrew Morton Cc: Ingo Molnar Signed-off-by: Dominik Brodowski --- drivers/base/devtmpfs.c | 2 +- include/linux/syscalls.h | 1 + init/do_mounts_initrd.c | 2 +- kernel/fork.c | 7 ++++++- 4 files changed, 9 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 3f7ee954fd2c..f7768077e817 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -380,7 +380,7 @@ static int devtmpfsd(void *p) { char options[] = "mode=0755"; int *err = p; - *err = sys_unshare(CLONE_NEWNS); + *err = ksys_unshare(CLONE_NEWNS); if (*err) goto out; *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 0a9942b3e718..e724dda509e0 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -961,6 +961,7 @@ int ksys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence); ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count); void ksys_sync(void); +int ksys_unshare(unsigned long unshare_flags); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 03ec0c1b7553..d1d3e53bdeef 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -36,7 +36,7 @@ __setup("noinitrd", no_initrd); static int init_linuxrc(struct subprocess_info *info, struct cred *new) { - sys_unshare(CLONE_FS | CLONE_FILES); + ksys_unshare(CLONE_FS | CLONE_FILES); /* stdin/stdout/stderr for /linuxrc */ ksys_open("/dev/console", O_RDWR, 0); ksys_dup(0); diff --git a/kernel/fork.c b/kernel/fork.c index b1e031aac9db..f71b67dc156d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -2354,7 +2354,7 @@ static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp * constructed. Here we are modifying the current, active, * task_struct. */ -SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) +int ksys_unshare(unsigned long unshare_flags) { struct fs_struct *fs, *new_fs = NULL; struct files_struct *fd, *new_fd = NULL; @@ -2470,6 +2470,11 @@ bad_unshare_out: return err; } +SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) +{ + return ksys_unshare(unshare_flags); +} + /* * Helper to unshare the files of the current task. * We don't want to expose copy_files internals to -- cgit v1.2.3-71-gd317 From e2aaa9f423367ee03755d632555c242629a08d00 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Fri, 16 Mar 2018 12:36:06 +0100 Subject: kernel: add ksys_setsid() helper; remove in-kernel call to sys_setsid() Using this helper allows us to avoid the in-kernel call to the sys_setsid() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_setsid(). 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: Al Viro Signed-off-by: Dominik Brodowski --- include/linux/syscalls.h | 1 + init/do_mounts_initrd.c | 2 +- kernel/sys.c | 7 ++++++- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index e724dda509e0..4dd685ee425d 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -962,6 +962,7 @@ off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence); ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count); void ksys_sync(void); int ksys_unshare(unsigned long unshare_flags); +int ksys_setsid(void); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index d1d3e53bdeef..5a91aefa7305 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -45,7 +45,7 @@ static int init_linuxrc(struct subprocess_info *info, struct cred *new) ksys_chdir("/root"); ksys_mount(".", "/", NULL, MS_MOVE, NULL); ksys_chroot("."); - sys_setsid(); + ksys_setsid(); return 0; } diff --git a/kernel/sys.c b/kernel/sys.c index 550f47788ae4..ad692183dfe9 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1150,7 +1150,7 @@ static void set_special_pids(struct pid *pid) change_pid(curr, PIDTYPE_PGID, pid); } -SYSCALL_DEFINE0(setsid) +int ksys_setsid(void) { struct task_struct *group_leader = current->group_leader; struct pid *sid = task_pid(group_leader); @@ -1183,6 +1183,11 @@ out: return err; } +SYSCALL_DEFINE0(setsid) +{ + return ksys_setsid(); +} + DECLARE_RWSEM(uts_sem); #ifdef COMPAT_UTS_MACHINE -- cgit v1.2.3-71-gd317 From 806cbae1228cc1a19b978c4513f6851e9ab7f388 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:47 +0100 Subject: fs: add ksys_sync_file_range helper(); remove in-kernel calls to syscall Using this helper allows us to avoid the in-kernel calls to the sys_sync_file_range() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_sync_file_range(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- arch/mips/kernel/linux32.c | 2 +- arch/parisc/kernel/sys_parisc.c | 2 +- arch/powerpc/kernel/sys_ppc32.c | 2 +- arch/s390/kernel/compat_linux.c | 2 +- arch/sparc/kernel/sys_sparc32.c | 2 +- arch/x86/ia32/sys_ia32.c | 6 +++--- fs/sync.c | 12 +++++++++--- include/linux/syscalls.h | 2 ++ 8 files changed, 19 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 3c90449742a0..57b3310873f0 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -139,7 +139,7 @@ asmlinkage long sys32_sync_file_range(int fd, int __pad, unsigned long a4, unsigned long a5, int flags) { - return sys_sync_file_range(fd, + return ksys_sync_file_range(fd, merge_64(a2, a3), merge_64(a4, a5), flags); } diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 6d2a64859c22..ef995b5d97ef 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -360,7 +360,7 @@ asmlinkage long parisc_sync_file_range(int fd, u32 hi_off, u32 lo_off, u32 hi_nbytes, u32 lo_nbytes, unsigned int flags) { - return sys_sync_file_range(fd, (loff_t)hi_off << 32 | lo_off, + return ksys_sync_file_range(fd, (loff_t)hi_off << 32 | lo_off, (loff_t)hi_nbytes << 32 | lo_nbytes, flags); } diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index e0c9b7f1bf38..664e4c5b5855 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -124,5 +124,5 @@ asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags, loff_t offset = ((loff_t)offset_hi << 32) | offset_lo; loff_t nbytes = ((loff_t)nbytes_hi << 32) | nbytes_lo; - return sys_sync_file_range(fd, offset, nbytes, flags); + return ksys_sync_file_range(fd, offset, nbytes, flags); } diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index af0469f204fd..605f6f026e44 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -509,7 +509,7 @@ COMPAT_SYSCALL_DEFINE1(s390_fadvise64_64, struct fadvise64_64_args __user *, arg COMPAT_SYSCALL_DEFINE6(s390_sync_file_range, int, fd, u32, offhigh, u32, offlow, u32, nhigh, u32, nlow, unsigned int, flags) { - return sys_sync_file_range(fd, ((loff_t)offhigh << 32) + offlow, + return ksys_sync_file_range(fd, ((loff_t)offhigh << 32) + offlow, ((u64)nhigh << 32) + nlow, flags); } diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index d64b425fff93..af18b9ff86be 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -241,7 +241,7 @@ long compat_sys_fadvise64_64(int fd, long sys32_sync_file_range(unsigned int fd, unsigned long off_high, unsigned long off_low, unsigned long nb_high, unsigned long nb_low, unsigned int flags) { - return sys_sync_file_range(fd, + return ksys_sync_file_range(fd, (off_high << 32) | off_low, (nb_high << 32) | nb_low, flags); diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index 1979e5b4ad9a..0c5f8932c136 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -209,9 +209,9 @@ COMPAT_SYSCALL_DEFINE6(x86_sync_file_range, int, fd, unsigned int, off_low, unsigned int, off_hi, unsigned int, n_low, unsigned int, n_hi, int, flags) { - return sys_sync_file_range(fd, - ((u64)off_hi << 32) | off_low, - ((u64)n_hi << 32) | n_low, flags); + return ksys_sync_file_range(fd, + ((u64)off_hi << 32) | off_low, + ((u64)n_hi << 32) | n_low, flags); } COMPAT_SYSCALL_DEFINE5(x86_fadvise64, int, fd, unsigned int, offset_lo, diff --git a/fs/sync.c b/fs/sync.c index 602ae94bb67e..9908a114d506 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -285,8 +285,8 @@ SYSCALL_DEFINE1(fdatasync, unsigned int, fd) * already-instantiated disk blocks, there are no guarantees here that the data * will be available after a crash. */ -SYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes, - unsigned int, flags) +int ksys_sync_file_range(int fd, loff_t offset, loff_t nbytes, + unsigned int flags) { int ret; struct fd f; @@ -364,10 +364,16 @@ out: return ret; } +SYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes, + unsigned int, flags) +{ + return ksys_sync_file_range(fd, offset, nbytes, flags); +} + /* It would be nice if people remember that not all the world's an i386 when they introduce new system calls */ SYSCALL_DEFINE4(sync_file_range2, int, fd, unsigned int, flags, loff_t, offset, loff_t, nbytes) { - return sys_sync_file_range(fd, offset, nbytes, flags); + return ksys_sync_file_range(fd, offset, nbytes, flags); } diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 4dd685ee425d..331da76f66e2 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -963,6 +963,8 @@ ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count); void ksys_sync(void); int ksys_unshare(unsigned long unshare_flags); int ksys_setsid(void); +int ksys_sync_file_range(int fd, loff_t offset, loff_t nbytes, + unsigned int flags); /* * The following kernel syscall equivalents are just wrappers to fs-internal -- cgit v1.2.3-71-gd317 From df260e21e6cd5d2dfc1fe9b6a3bbf747e72b3bed Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 19 Mar 2018 17:32:11 +0100 Subject: fs: add ksys_truncate() wrapper; remove in-kernel calls to sys_truncate() Using the ksys_truncate() wrapper allows us to get rid of in-kernel calls to the sys_truncate() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_truncate(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- arch/mips/kernel/linux32.c | 2 +- arch/parisc/kernel/sys_parisc.c | 6 +++--- arch/powerpc/kernel/sys_ppc32.c | 2 +- arch/s390/kernel/compat_linux.c | 2 +- arch/sparc/kernel/sys_sparc32.c | 2 +- arch/x86/ia32/sys_ia32.c | 3 ++- fs/open.c | 2 +- include/linux/syscalls.h | 7 +++++++ 8 files changed, 17 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 57b3310873f0..58e7dd27f106 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -82,7 +82,7 @@ struct rlimit32 { SYSCALL_DEFINE4(32_truncate64, const char __user *, path, unsigned long, __dummy, unsigned long, a2, unsigned long, a3) { - return sys_truncate(path, merge_64(a2, a3)); + return ksys_truncate(path, merge_64(a2, a3)); } SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy, diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index ef995b5d97ef..3377a00163c3 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -292,7 +292,7 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, asmlinkage long parisc_truncate64(const char __user * path, unsigned int high, unsigned int low) { - return sys_truncate(path, (long)high << 32 | low); + return ksys_truncate(path, (long)high << 32 | low); } asmlinkage long parisc_ftruncate64(unsigned int fd, @@ -305,7 +305,7 @@ asmlinkage long parisc_ftruncate64(unsigned int fd, * are identical on LP64 */ asmlinkage long sys_truncate64(const char __user * path, unsigned long length) { - return sys_truncate(path, length); + return ksys_truncate(path, length); } asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length) { @@ -320,7 +320,7 @@ asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg asmlinkage long parisc_truncate64(const char __user * path, unsigned int high, unsigned int low) { - return sys_truncate64(path, (loff_t)high << 32 | low); + return ksys_truncate(path, (loff_t)high << 32 | low); } asmlinkage long parisc_ftruncate64(unsigned int fd, diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 664e4c5b5855..a0a251d7c9c5 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -94,7 +94,7 @@ compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 co asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4, unsigned long high, unsigned long low) { - return sys_truncate(path, (high << 32) | low); + return ksys_truncate(path, (high << 32) | low); } asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 605f6f026e44..e4092ec17ea5 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -302,7 +302,7 @@ COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, compat_ulong_t, second, COMPAT_SYSCALL_DEFINE3(s390_truncate64, const char __user *, path, u32, high, u32, low) { - return sys_truncate(path, (unsigned long)high << 32 | low); + return ksys_truncate(path, (unsigned long)high << 32 | low); } COMPAT_SYSCALL_DEFINE3(s390_ftruncate64, unsigned int, fd, u32, high, u32, low) diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index af18b9ff86be..aab2428b17b5 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -57,7 +57,7 @@ asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, u if ((int)high < 0) return -EINVAL; else - return sys_truncate(path, (high << 32) | low); + return ksys_truncate(path, (high << 32) | low); } asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low) diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index 0c5f8932c136..90e7a2b3dc5b 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -55,7 +55,8 @@ COMPAT_SYSCALL_DEFINE3(x86_truncate64, const char __user *, filename, unsigned long, offset_low, unsigned long, offset_high) { - return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low); + return ksys_truncate(filename, + ((loff_t) offset_high << 32) | offset_low); } COMPAT_SYSCALL_DEFINE3(x86_ftruncate64, unsigned int, fd, diff --git a/fs/open.c b/fs/open.c index 8a42a2961130..2e816fc7bd56 100644 --- a/fs/open.c +++ b/fs/open.c @@ -128,7 +128,7 @@ out: } EXPORT_SYMBOL_GPL(vfs_truncate); -static long do_sys_truncate(const char __user *pathname, loff_t length) +long do_sys_truncate(const char __user *pathname, loff_t length) { unsigned int lookup_flags = LOOKUP_FOLLOW; struct path path; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 331da76f66e2..78b79e3a1279 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -1078,4 +1078,11 @@ static inline long ksys_open(const char __user *filename, int flags, return do_sys_open(AT_FDCWD, filename, flags, mode); } +extern long do_sys_truncate(const char __user *pathname, loff_t length); + +static inline long ksys_truncate(const char __user *pathname, loff_t length) +{ + return do_sys_truncate(pathname, length); +} + #endif -- cgit v1.2.3-71-gd317 From 36028d5dd71175c332ab634e089e16dbdfe3812b Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 19 Mar 2018 17:38:31 +0100 Subject: fs: add ksys_p{read,write}64() helpers; remove in-kernel calls to syscalls Using the ksys_p{read,write}64() wrappers allows us to get rid of in-kernel calls to the sys_pread64() and sys_pwrite64() syscalls. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_p{read,write}64(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- arch/mips/kernel/linux32.c | 4 ++-- arch/parisc/kernel/sys_parisc.c | 4 ++-- arch/powerpc/kernel/sys_ppc32.c | 4 ++-- arch/s390/kernel/compat_linux.c | 4 ++-- arch/sh/kernel/sys_sh32.c | 4 ++-- arch/sparc/kernel/sys_sparc32.c | 4 ++-- arch/x86/ia32/sys_ia32.c | 8 ++++---- fs/read_write.c | 20 ++++++++++++++++---- include/linux/syscalls.h | 4 ++++ 9 files changed, 36 insertions(+), 20 deletions(-) (limited to 'include/linux') diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 58e7dd27f106..91e85e2f8aa5 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -105,13 +105,13 @@ SYSCALL_DEFINE5(32_llseek, unsigned int, fd, unsigned int, offset_high, SYSCALL_DEFINE6(32_pread, unsigned long, fd, char __user *, buf, size_t, count, unsigned long, unused, unsigned long, a4, unsigned long, a5) { - return sys_pread64(fd, buf, count, merge_64(a4, a5)); + return ksys_pread64(fd, buf, count, merge_64(a4, a5)); } SYSCALL_DEFINE6(32_pwrite, unsigned int, fd, const char __user *, buf, size_t, count, u32, unused, u64, a4, u64, a5) { - return sys_pwrite64(fd, buf, count, merge_64(a4, a5)); + return ksys_pwrite64(fd, buf, count, merge_64(a4, a5)); } SYSCALL_DEFINE1(32_personality, unsigned long, personality) diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 3377a00163c3..4f47e8379854 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -333,13 +333,13 @@ asmlinkage long parisc_ftruncate64(unsigned int fd, asmlinkage ssize_t parisc_pread64(unsigned int fd, char __user *buf, size_t count, unsigned int high, unsigned int low) { - return sys_pread64(fd, buf, count, (loff_t)high << 32 | low); + return ksys_pread64(fd, buf, count, (loff_t)high << 32 | low); } asmlinkage ssize_t parisc_pwrite64(unsigned int fd, const char __user *buf, size_t count, unsigned int high, unsigned int low) { - return sys_pwrite64(fd, buf, count, (loff_t)high << 32 | low); + return ksys_pwrite64(fd, buf, count, (loff_t)high << 32 | low); } asmlinkage ssize_t parisc_readahead(int fd, unsigned int high, unsigned int low, diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index a0a251d7c9c5..36a651e6e033 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -77,13 +77,13 @@ unsigned long compat_sys_mmap2(unsigned long addr, size_t len, compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, u32 reg6, u32 poshi, u32 poslo) { - return sys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); + return ksys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); } compat_ssize_t compat_sys_pwrite64(unsigned int fd, const char __user *ubuf, compat_size_t count, u32 reg6, u32 poshi, u32 poslo) { - return sys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); + return ksys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); } compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count) diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index e4092ec17ea5..71e2c5bc4926 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -315,7 +315,7 @@ COMPAT_SYSCALL_DEFINE5(s390_pread64, unsigned int, fd, char __user *, ubuf, { if ((compat_ssize_t) count < 0) return -EINVAL; - return sys_pread64(fd, ubuf, count, (unsigned long)high << 32 | low); + return ksys_pread64(fd, ubuf, count, (unsigned long)high << 32 | low); } COMPAT_SYSCALL_DEFINE5(s390_pwrite64, unsigned int, fd, const char __user *, ubuf, @@ -323,7 +323,7 @@ COMPAT_SYSCALL_DEFINE5(s390_pwrite64, unsigned int, fd, const char __user *, ubu { if ((compat_ssize_t) count < 0) return -EINVAL; - return sys_pwrite64(fd, ubuf, count, (unsigned long)high << 32 | low); + return ksys_pwrite64(fd, ubuf, count, (unsigned long)high << 32 | low); } COMPAT_SYSCALL_DEFINE4(s390_readahead, int, fd, u32, high, u32, low, s32, count) diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c index f8dc8bfd4606..c37ee3d0c803 100644 --- a/arch/sh/kernel/sys_sh32.c +++ b/arch/sh/kernel/sys_sh32.c @@ -39,13 +39,13 @@ asmlinkage int sys_sh_pipe(void) asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char __user *buf, size_t count, long dummy, loff_t pos) { - return sys_pread64(fd, buf, count, pos); + return ksys_pread64(fd, buf, count, pos); } asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char __user *buf, size_t count, long dummy, loff_t pos) { - return sys_pwrite64(fd, buf, count, pos); + return ksys_pwrite64(fd, buf, count, pos); } asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1, diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index aab2428b17b5..40c0d2e1db1d 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -200,7 +200,7 @@ asmlinkage compat_ssize_t sys32_pread64(unsigned int fd, unsigned long poshi, unsigned long poslo) { - return sys_pread64(fd, ubuf, count, (poshi << 32) | poslo); + return ksys_pread64(fd, ubuf, count, (poshi << 32) | poslo); } asmlinkage compat_ssize_t sys32_pwrite64(unsigned int fd, @@ -209,7 +209,7 @@ asmlinkage compat_ssize_t sys32_pwrite64(unsigned int fd, unsigned long poshi, unsigned long poslo) { - return sys_pwrite64(fd, ubuf, count, (poshi << 32) | poslo); + return ksys_pwrite64(fd, ubuf, count, (poshi << 32) | poslo); } asmlinkage long compat_sys_readahead(int fd, diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index 90e7a2b3dc5b..c08c25f73d79 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -174,15 +174,15 @@ COMPAT_SYSCALL_DEFINE1(x86_mmap, struct mmap_arg_struct32 __user *, arg) COMPAT_SYSCALL_DEFINE5(x86_pread, unsigned int, fd, char __user *, ubuf, u32, count, u32, poslo, u32, poshi) { - return sys_pread64(fd, ubuf, count, - ((loff_t)AA(poshi) << 32) | AA(poslo)); + return ksys_pread64(fd, ubuf, count, + ((loff_t)AA(poshi) << 32) | AA(poslo)); } COMPAT_SYSCALL_DEFINE5(x86_pwrite, unsigned int, fd, const char __user *, ubuf, u32, count, u32, poslo, u32, poshi) { - return sys_pwrite64(fd, ubuf, count, - ((loff_t)AA(poshi) << 32) | AA(poslo)); + return ksys_pwrite64(fd, ubuf, count, + ((loff_t)AA(poshi) << 32) | AA(poslo)); } diff --git a/fs/read_write.c b/fs/read_write.c index fc441e1ac683..c4eabbfc90df 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -610,8 +610,8 @@ SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, return ksys_write(fd, buf, count); } -SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf, - size_t, count, loff_t, pos) +ssize_t ksys_pread64(unsigned int fd, char __user *buf, size_t count, + loff_t pos) { struct fd f; ssize_t ret = -EBADF; @@ -630,8 +630,14 @@ SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf, return ret; } -SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf, - size_t, count, loff_t, pos) +SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf, + size_t, count, loff_t, pos) +{ + return ksys_pread64(fd, buf, count, pos); +} + +ssize_t ksys_pwrite64(unsigned int fd, const char __user *buf, + size_t count, loff_t pos) { struct fd f; ssize_t ret = -EBADF; @@ -650,6 +656,12 @@ SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf, return ret; } +SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf, + size_t, count, loff_t, pos) +{ + return ksys_pwrite64(fd, buf, count, pos); +} + static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, loff_t *ppos, int type, rwf_t flags) { diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 78b79e3a1279..a30e4c2d0c27 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -965,6 +965,10 @@ int ksys_unshare(unsigned long unshare_flags); int ksys_setsid(void); int ksys_sync_file_range(int fd, loff_t offset, loff_t nbytes, unsigned int flags); +ssize_t ksys_pread64(unsigned int fd, char __user *buf, size_t count, + loff_t pos); +ssize_t ksys_pwrite64(unsigned int fd, const char __user *buf, + size_t count, loff_t pos); /* * The following kernel syscall equivalents are just wrappers to fs-internal -- cgit v1.2.3-71-gd317 From edf292c76b884a499cc60ad5cdada2663cc39a2f Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 19 Mar 2018 17:46:32 +0100 Subject: fs: add ksys_fallocate() wrapper; remove in-kernel calls to sys_fallocate() Using the ksys_fallocate() wrapper allows us to get rid of in-kernel calls to the sys_fallocate() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_fallocate(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- arch/mips/kernel/linux32.c | 4 ++-- arch/parisc/kernel/sys_parisc.c | 4 ++-- arch/powerpc/kernel/sys_ppc32.c | 2 +- arch/s390/kernel/compat_linux.c | 4 ++-- arch/sparc/kernel/sys_sparc32.c | 4 ++-- arch/x86/ia32/sys_ia32.c | 4 ++-- fs/open.c | 7 ++++++- include/linux/syscalls.h | 1 + 8 files changed, 18 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 91e85e2f8aa5..0779d474c8ad 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -157,6 +157,6 @@ asmlinkage long sys32_fadvise64_64(int fd, int __pad, asmlinkage long sys32_fallocate(int fd, int mode, unsigned offset_a2, unsigned offset_a3, unsigned len_a4, unsigned len_a5) { - return sys_fallocate(fd, mode, merge_64(offset_a2, offset_a3), - merge_64(len_a4, len_a5)); + return ksys_fallocate(fd, mode, merge_64(offset_a2, offset_a3), + merge_64(len_a4, len_a5)); } diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 4f47e8379854..588fab336ddd 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -367,8 +367,8 @@ asmlinkage long parisc_sync_file_range(int fd, asmlinkage long parisc_fallocate(int fd, int mode, u32 offhi, u32 offlo, u32 lenhi, u32 lenlo) { - return sys_fallocate(fd, mode, ((u64)offhi << 32) | offlo, - ((u64)lenhi << 32) | lenlo); + return ksys_fallocate(fd, mode, ((u64)offhi << 32) | offlo, + ((u64)lenhi << 32) | lenlo); } long parisc_personality(unsigned long personality) diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 36a651e6e033..68f11e1065f8 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -100,7 +100,7 @@ asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4, asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, u32 lenhi, u32 lenlo) { - return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, + return ksys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, ((loff_t)lenhi << 32) | lenlo); } diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 71e2c5bc4926..039858f9f128 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -516,6 +516,6 @@ COMPAT_SYSCALL_DEFINE6(s390_sync_file_range, int, fd, u32, offhigh, u32, offlow, COMPAT_SYSCALL_DEFINE6(s390_fallocate, int, fd, int, mode, u32, offhigh, u32, offlow, u32, lenhigh, u32, lenlow) { - return sys_fallocate(fd, mode, ((loff_t)offhigh << 32) + offlow, - ((u64)lenhigh << 32) + lenlow); + return ksys_fallocate(fd, mode, ((loff_t)offhigh << 32) + offlow, + ((u64)lenhigh << 32) + lenlow); } diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index 40c0d2e1db1d..4ba62d676632 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -250,6 +250,6 @@ long sys32_sync_file_range(unsigned int fd, unsigned long off_high, unsigned lon asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, u32 lenhi, u32 lenlo) { - return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, - ((loff_t)lenhi << 32) | lenlo); + return ksys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, + ((loff_t)lenhi << 32) | lenlo); } diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index c08c25f73d79..df2acb13623f 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -226,8 +226,8 @@ COMPAT_SYSCALL_DEFINE6(x86_fallocate, int, fd, int, mode, unsigned int, offset_lo, unsigned int, offset_hi, unsigned int, len_lo, unsigned int, len_hi) { - return sys_fallocate(fd, mode, ((u64)offset_hi << 32) | offset_lo, - ((u64)len_hi << 32) | len_lo); + return ksys_fallocate(fd, mode, ((u64)offset_hi << 32) | offset_lo, + ((u64)len_hi << 32) | len_lo); } /* diff --git a/fs/open.c b/fs/open.c index 2e816fc7bd56..d0e955b558ad 100644 --- a/fs/open.c +++ b/fs/open.c @@ -333,7 +333,7 @@ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) } EXPORT_SYMBOL_GPL(vfs_fallocate); -SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) +int ksys_fallocate(int fd, int mode, loff_t offset, loff_t len) { struct fd f = fdget(fd); int error = -EBADF; @@ -345,6 +345,11 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) return error; } +SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) +{ + return ksys_fallocate(fd, mode, offset, len); +} + /* * access() needs to use the real uid/gid, not the effective uid/gid. * We do this by temporarily clearing all FS-related capabilities and diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index a30e4c2d0c27..613b8127834d 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -969,6 +969,7 @@ ssize_t ksys_pread64(unsigned int fd, char __user *buf, size_t count, loff_t pos); ssize_t ksys_pwrite64(unsigned int fd, const char __user *buf, size_t count, loff_t pos); +int ksys_fallocate(int fd, int mode, loff_t offset, loff_t len); /* * The following kernel syscall equivalents are just wrappers to fs-internal -- cgit v1.2.3-71-gd317 From 9d5b7c956b09daab955fb2a42447d5d89ff15093 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:45 +0100 Subject: mm: add ksys_fadvise64_64() helper; remove in-kernel call to sys_fadvise64_64() Using the ksys_fadvise64_64() helper allows us to avoid the in-kernel calls to the sys_fadvise64_64() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as ksys_fadvise64_64(). Some compat stubs called sys_fadvise64(), which then just passed through the arguments to sys_fadvise64_64(). Get rid of this indirection, and call ksys_fadvise64_64() directly. 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: Andrew Morton Cc: linux-mm@kvack.org Signed-off-by: Dominik Brodowski --- arch/arm/kernel/sys_arm.c | 2 +- arch/mips/kernel/linux32.c | 2 +- arch/parisc/kernel/sys_parisc.c | 2 +- arch/powerpc/kernel/sys_ppc32.c | 4 ++-- arch/powerpc/kernel/syscalls.c | 4 ++-- arch/s390/kernel/compat_linux.c | 5 +++-- arch/sh/kernel/sys_sh32.c | 8 ++++---- arch/sparc/kernel/sys_sparc32.c | 10 +++++----- arch/x86/ia32/sys_ia32.c | 12 ++++++------ arch/xtensa/kernel/syscall.c | 2 +- include/linux/syscalls.h | 9 +++++++++ mm/fadvise.c | 10 ++++++++-- 12 files changed, 43 insertions(+), 27 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 3151f5623d0e..bdf7514204ab 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -35,5 +35,5 @@ asmlinkage long sys_arm_fadvise64_64(int fd, int advice, loff_t offset, loff_t len) { - return sys_fadvise64_64(fd, offset, len, advice); + return ksys_fadvise64_64(fd, offset, len, advice); } diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 0779d474c8ad..1c5785e72db4 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -149,7 +149,7 @@ asmlinkage long sys32_fadvise64_64(int fd, int __pad, unsigned long a4, unsigned long a5, int flags) { - return sys_fadvise64_64(fd, + return ksys_fadvise64_64(fd, merge_64(a2, a3), merge_64(a4, a5), flags); } diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 588fab336ddd..f36ab1f09595 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -352,7 +352,7 @@ asmlinkage long parisc_fadvise64_64(int fd, unsigned int high_off, unsigned int low_off, unsigned int high_len, unsigned int low_len, int advice) { - return sys_fadvise64_64(fd, (loff_t)high_off << 32 | low_off, + return ksys_fadvise64_64(fd, (loff_t)high_off << 32 | low_off, (loff_t)high_len << 32 | low_len, advice); } diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 68f11e1065f8..0b95fa13307f 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -113,8 +113,8 @@ asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long h long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low, size_t len, int advice) { - return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low, len, - advice); + return ksys_fadvise64_64(fd, (u64)offset_high << 32 | offset_low, len, + advice); } asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags, diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index a877bf8269fe..ecb981eea74b 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -119,8 +119,8 @@ long ppc64_personality(unsigned long personality) long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low, u32 len_high, u32 len_low) { - return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low, - (u64)len_high << 32 | len_low, advice); + return ksys_fadvise64_64(fd, (u64)offset_high << 32 | offset_low, + (u64)len_high << 32 | len_low, advice); } long sys_switch_endian(void) diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 039858f9f128..9bb897e443a6 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -483,7 +483,8 @@ COMPAT_SYSCALL_DEFINE5(s390_fadvise64, int, fd, u32, high, u32, low, compat_size advise = POSIX_FADV_DONTNEED; else if (advise == 5) advise = POSIX_FADV_NOREUSE; - return sys_fadvise64(fd, (unsigned long)high << 32 | low, len, advise); + return ksys_fadvise64_64(fd, (unsigned long)high << 32 | low, len, + advise); } struct fadvise64_64_args { @@ -503,7 +504,7 @@ COMPAT_SYSCALL_DEFINE1(s390_fadvise64_64, struct fadvise64_64_args __user *, arg a.advice = POSIX_FADV_DONTNEED; else if (a.advice == 5) a.advice = POSIX_FADV_NOREUSE; - return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); + return ksys_fadvise64_64(a.fd, a.offset, a.len, a.advice); } COMPAT_SYSCALL_DEFINE6(s390_sync_file_range, int, fd, u32, offhigh, u32, offlow, diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c index c37ee3d0c803..9dca568509a5 100644 --- a/arch/sh/kernel/sys_sh32.c +++ b/arch/sh/kernel/sys_sh32.c @@ -52,10 +52,10 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1, u32 len0, u32 len1, int advice) { #ifdef __LITTLE_ENDIAN__ - return sys_fadvise64_64(fd, (u64)offset1 << 32 | offset0, - (u64)len1 << 32 | len0, advice); + return ksys_fadvise64_64(fd, (u64)offset1 << 32 | offset0, + (u64)len1 << 32 | len0, advice); #else - return sys_fadvise64_64(fd, (u64)offset0 << 32 | offset1, - (u64)len0 << 32 | len1, advice); + return ksys_fadvise64_64(fd, (u64)offset0 << 32 | offset1, + (u64)len0 << 32 | len1, advice); #endif } diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index 4ba62d676632..4da66aed50b4 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -225,7 +225,7 @@ long compat_sys_fadvise64(int fd, unsigned long offlo, compat_size_t len, int advice) { - return sys_fadvise64_64(fd, (offhi << 32) | offlo, len, advice); + return ksys_fadvise64_64(fd, (offhi << 32) | offlo, len, advice); } long compat_sys_fadvise64_64(int fd, @@ -233,10 +233,10 @@ long compat_sys_fadvise64_64(int fd, unsigned long lenhi, unsigned long lenlo, int advice) { - return sys_fadvise64_64(fd, - (offhi << 32) | offlo, - (lenhi << 32) | lenlo, - advice); + return ksys_fadvise64_64(fd, + (offhi << 32) | offlo, + (lenhi << 32) | lenlo, + advice); } long sys32_sync_file_range(unsigned int fd, unsigned long off_high, unsigned long off_low, unsigned long nb_high, unsigned long nb_low, unsigned int flags) diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index df2acb13623f..401bd8ec9cf0 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -194,10 +194,10 @@ COMPAT_SYSCALL_DEFINE6(x86_fadvise64_64, int, fd, __u32, offset_low, __u32, offset_high, __u32, len_low, __u32, len_high, int, advice) { - return sys_fadvise64_64(fd, - (((u64)offset_high)<<32) | offset_low, - (((u64)len_high)<<32) | len_low, - advice); + return ksys_fadvise64_64(fd, + (((u64)offset_high)<<32) | offset_low, + (((u64)len_high)<<32) | len_low, + advice); } COMPAT_SYSCALL_DEFINE4(x86_readahead, int, fd, unsigned int, off_lo, @@ -218,8 +218,8 @@ COMPAT_SYSCALL_DEFINE6(x86_sync_file_range, int, fd, unsigned int, off_low, COMPAT_SYSCALL_DEFINE5(x86_fadvise64, int, fd, unsigned int, offset_lo, unsigned int, offset_hi, size_t, len, int, advice) { - return sys_fadvise64_64(fd, ((u64)offset_hi << 32) | offset_lo, - len, advice); + return ksys_fadvise64_64(fd, ((u64)offset_hi << 32) | offset_lo, + len, advice); } COMPAT_SYSCALL_DEFINE6(x86_fallocate, int, fd, int, mode, diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index 74afbf02d07e..8201748da05b 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c @@ -55,7 +55,7 @@ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) asmlinkage long xtensa_fadvise64_64(int fd, int advice, unsigned long long offset, unsigned long long len) { - return sys_fadvise64_64(fd, offset, len, advice); + return ksys_fadvise64_64(fd, offset, len, advice); } #ifdef CONFIG_MMU diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 613b8127834d..466d408deefd 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -970,6 +970,15 @@ ssize_t ksys_pread64(unsigned int fd, char __user *buf, size_t count, ssize_t ksys_pwrite64(unsigned int fd, const char __user *buf, size_t count, loff_t pos); int ksys_fallocate(int fd, int mode, loff_t offset, loff_t len); +#ifdef CONFIG_ADVISE_SYSCALLS +int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice); +#else +static inline int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, + int advice) +{ + return -EINVAL; +} +#endif /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/mm/fadvise.c b/mm/fadvise.c index 767887f5f3bf..afa41491d324 100644 --- a/mm/fadvise.c +++ b/mm/fadvise.c @@ -26,7 +26,8 @@ * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could * deactivate the pages and clear PG_Referenced. */ -SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice) + +int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) { struct fd f = fdget(fd); struct inode *inode; @@ -185,11 +186,16 @@ out: return ret; } +SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice) +{ + return ksys_fadvise64_64(fd, offset, len, advice); +} + #ifdef __ARCH_WANT_SYS_FADVISE64 SYSCALL_DEFINE4(fadvise64, int, fd, loff_t, offset, size_t, len, int, advice) { - return sys_fadvise64_64(fd, offset, len, advice); + return ksys_fadvise64_64(fd, offset, len, advice); } #endif -- cgit v1.2.3-71-gd317 From a90f590a1bee36fc2129cfb38ceec24a555bb12d Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:46 +0100 Subject: mm: add ksys_mmap_pgoff() helper; remove in-kernel calls to sys_mmap_pgoff() Using this helper allows us to avoid the in-kernel calls to the sys_mmap_pgoff() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_mmap_pgoff(). 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: Andrew Morton Cc: linux-mm@kvack.org Signed-off-by: Dominik Brodowski --- arch/alpha/kernel/osf_sys.c | 2 +- arch/arm64/kernel/sys.c | 2 +- arch/ia64/kernel/sys_ia64.c | 4 ++-- arch/m68k/kernel/sys_m68k.c | 2 +- arch/microblaze/kernel/sys_microblaze.c | 6 +++--- arch/mips/kernel/linux32.c | 4 ++-- arch/mips/kernel/syscall.c | 6 ++++-- arch/parisc/kernel/sys_parisc.c | 6 +++--- arch/powerpc/kernel/syscalls.c | 2 +- arch/riscv/kernel/sys_riscv.c | 4 ++-- arch/s390/kernel/compat_linux.c | 6 +++--- arch/s390/kernel/sys_s390.c | 2 +- arch/sh/kernel/sys_sh.c | 4 ++-- arch/sparc/kernel/sys_sparc_32.c | 6 +++--- arch/sparc/kernel/sys_sparc_64.c | 2 +- arch/um/kernel/syscall.c | 2 +- arch/x86/ia32/sys_ia32.c | 2 +- arch/x86/kernel/sys_x86_64.c | 2 +- include/linux/syscalls.h | 3 +++ mm/mmap.c | 17 ++++++++++++----- mm/nommu.c | 17 ++++++++++++----- 21 files changed, 60 insertions(+), 41 deletions(-) (limited to 'include/linux') diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index fa1a392ca9a2..89faa6f4de47 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -189,7 +189,7 @@ SYSCALL_DEFINE6(osf_mmap, unsigned long, addr, unsigned long, len, goto out; if (off & ~PAGE_MASK) goto out; - ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); + ret = ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); out: return ret; } diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c index 26fe8ea93ea2..72981bae10eb 100644 --- a/arch/arm64/kernel/sys.c +++ b/arch/arm64/kernel/sys.c @@ -34,7 +34,7 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len, if (offset_in_page(off) != 0) return -EINVAL; - return sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); } SYSCALL_DEFINE1(arm64_personality, unsigned int, personality) diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index 085adfcc74a4..9ebe1d633abc 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c @@ -139,7 +139,7 @@ int ia64_mmap_check(unsigned long addr, unsigned long len, asmlinkage unsigned long sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff) { - addr = sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); + addr = ksys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); if (!IS_ERR((void *) addr)) force_successful_syscall_return(); return addr; @@ -151,7 +151,7 @@ sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, lo if (offset_in_page(off) != 0) return -EINVAL; - addr = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); + addr = ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); if (!IS_ERR((void *) addr)) force_successful_syscall_return(); return addr; diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 27e10af5153a..6363ec83a290 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -46,7 +46,7 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, * so we need to shift the argument down by 1; m68k mmap64(3) * (in libc) expects the last argument of mmap2 in 4Kb units. */ - return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); } /* Convert virtual (user) address VADDR to physical address PADDR */ diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index f1e1f666ddde..ed9f34da1a2a 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c @@ -40,7 +40,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, if (pgoff & ~PAGE_MASK) return -EINVAL; - return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); } SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, @@ -50,6 +50,6 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, if (pgoff & (~PAGE_MASK >> 12)) return -EINVAL; - return sys_mmap_pgoff(addr, len, prot, flags, fd, - pgoff >> (PAGE_SHIFT - 12)); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, + pgoff >> (PAGE_SHIFT - 12)); } diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 1c5785e72db4..0571ab7b68b0 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -67,8 +67,8 @@ SYSCALL_DEFINE6(32_mmap2, unsigned long, addr, unsigned long, len, { if (pgoff & (~PAGE_MASK >> 12)) return -EINVAL; - return sys_mmap_pgoff(addr, len, prot, flags, fd, - pgoff >> (PAGE_SHIFT-12)); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, + pgoff >> (PAGE_SHIFT-12)); } #define RLIM_INFINITY32 0x7fffffff diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 58c6f634b550..69c17b549fd3 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -63,7 +63,8 @@ SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, { if (offset & ~PAGE_MASK) return -EINVAL; - return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, + offset >> PAGE_SHIFT); } SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len, @@ -73,7 +74,8 @@ SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len, if (pgoff & (~PAGE_MASK >> 12)) return -EINVAL; - return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12)); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, + pgoff >> (PAGE_SHIFT - 12)); } save_static_function(sys_fork); diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index f36ab1f09595..080d566654ea 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -270,8 +270,8 @@ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, { /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE we have. */ - return sys_mmap_pgoff(addr, len, prot, flags, fd, - pgoff >> (PAGE_SHIFT - 12)); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, + pgoff >> (PAGE_SHIFT - 12)); } asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, @@ -279,7 +279,7 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, unsigned long offset) { if (!(offset & ~PAGE_MASK)) { - return sys_mmap_pgoff(addr, len, prot, flags, fd, + return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); } else { return -EINVAL; diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index ecb981eea74b..1ef3b80b62a6 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -57,7 +57,7 @@ static inline long do_mmap2(unsigned long addr, size_t len, off >>= shift; } - ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off); + ret = ksys_mmap_pgoff(addr, len, prot, flags, fd, off); out: return ret; } diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c index 79c78668258e..f7181ed8aafc 100644 --- a/arch/riscv/kernel/sys_riscv.c +++ b/arch/riscv/kernel/sys_riscv.c @@ -24,8 +24,8 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len, { if (unlikely(offset & (~PAGE_MASK >> page_shift_offset))) return -EINVAL; - return sys_mmap_pgoff(addr, len, prot, flags, fd, - offset >> (PAGE_SHIFT - page_shift_offset)); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, + offset >> (PAGE_SHIFT - page_shift_offset)); } #ifdef CONFIG_64BIT diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 9bb897e443a6..da5ef7718254 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -442,8 +442,8 @@ COMPAT_SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct_emu31 __user *, arg return -EFAULT; if (a.offset & ~PAGE_MASK) return -EINVAL; - return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, - a.offset >> PAGE_SHIFT); + return ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, + a.offset >> PAGE_SHIFT); } COMPAT_SYSCALL_DEFINE1(s390_mmap2, struct mmap_arg_struct_emu31 __user *, arg) @@ -452,7 +452,7 @@ COMPAT_SYSCALL_DEFINE1(s390_mmap2, struct mmap_arg_struct_emu31 __user *, arg) if (copy_from_user(&a, arg, sizeof(a))) return -EFAULT; - return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); + return ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); } COMPAT_SYSCALL_DEFINE3(s390_read, unsigned int, fd, char __user *, buf, compat_size_t, count) diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index 0090037ab148..31cefe0c28c0 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c @@ -53,7 +53,7 @@ SYSCALL_DEFINE1(mmap2, struct s390_mmap_arg_struct __user *, arg) if (copy_from_user(&a, arg, sizeof(a))) goto out; - error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); + error = ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); out: return error; } diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 724911c59e7d..f8afc014e084 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c @@ -35,7 +35,7 @@ asmlinkage int old_mmap(unsigned long addr, unsigned long len, { if (off & ~PAGE_MASK) return -EINVAL; - return sys_mmap_pgoff(addr, len, prot, flags, fd, off>>PAGE_SHIFT); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, off>>PAGE_SHIFT); } asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, @@ -51,7 +51,7 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, pgoff >>= PAGE_SHIFT - 12; - return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); } /* sys_cacheflush -- flush (part of) the processor cache. */ diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 990703b7cf4d..d980da4ffd7b 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c @@ -104,8 +104,8 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, { /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE we have. */ - return sys_mmap_pgoff(addr, len, prot, flags, fd, - pgoff >> (PAGE_SHIFT - 12)); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, + pgoff >> (PAGE_SHIFT - 12)); } asmlinkage long sys_mmap(unsigned long addr, unsigned long len, @@ -113,7 +113,7 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long off) { /* no alignment check? */ - return sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); } long sparc_remap_file_pages(unsigned long start, unsigned long size, diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 55416db482ad..ebb84dc8a5a7 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -458,7 +458,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, goto out; if (off & ~PAGE_MASK) goto out; - retval = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); + retval = ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); out: return retval; } diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 6258676bed85..35f7047bdebc 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c @@ -22,7 +22,7 @@ long old_mmap(unsigned long addr, unsigned long len, if (offset & ~PAGE_MASK) goto out; - err = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); + err = ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); out: return err; } diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index 401bd8ec9cf0..bff71b9ae3f5 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -166,7 +166,7 @@ COMPAT_SYSCALL_DEFINE1(x86_mmap, struct mmap_arg_struct32 __user *, arg) if (a.offset & ~PAGE_MASK) return -EINVAL; - return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, + return ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset>>PAGE_SHIFT); } diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c index 676774b9bb8d..a3f15ed545b5 100644 --- a/arch/x86/kernel/sys_x86_64.c +++ b/arch/x86/kernel/sys_x86_64.c @@ -97,7 +97,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, if (off & ~PAGE_MASK) goto out; - error = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); + error = ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); out: return error; } diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 466d408deefd..ec866c959e7d 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -979,6 +979,9 @@ static inline int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, return -EINVAL; } #endif +unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/mm/mmap.c b/mm/mmap.c index 9efdc021ad22..aa0dc8231c0d 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1488,9 +1488,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr, return addr; } -SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, - unsigned long, prot, unsigned long, flags, - unsigned long, fd, unsigned long, pgoff) +unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) { struct file *file = NULL; unsigned long retval; @@ -1537,6 +1537,13 @@ out_fput: return retval; } +SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, + unsigned long, fd, unsigned long, pgoff) +{ + return ksys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); +} + #ifdef __ARCH_WANT_SYS_OLD_MMAP struct mmap_arg_struct { unsigned long addr; @@ -1556,8 +1563,8 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg) if (offset_in_page(a.offset)) return -EINVAL; - return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, - a.offset >> PAGE_SHIFT); + return ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, + a.offset >> PAGE_SHIFT); } #endif /* __ARCH_WANT_SYS_OLD_MMAP */ diff --git a/mm/nommu.c b/mm/nommu.c index ebb6e618dade..cad329629530 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1423,9 +1423,9 @@ error_getting_region: return -ENOMEM; } -SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, - unsigned long, prot, unsigned long, flags, - unsigned long, fd, unsigned long, pgoff) +unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) { struct file *file = NULL; unsigned long retval = -EBADF; @@ -1447,6 +1447,13 @@ out: return retval; } +SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, + unsigned long, fd, unsigned long, pgoff) +{ + return ksys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); +} + #ifdef __ARCH_WANT_SYS_OLD_MMAP struct mmap_arg_struct { unsigned long addr; @@ -1466,8 +1473,8 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg) if (offset_in_page(a.offset)) return -EINVAL; - return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, - a.offset >> PAGE_SHIFT); + return ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, + a.offset >> PAGE_SHIFT); } #endif /* __ARCH_WANT_SYS_OLD_MMAP */ -- cgit v1.2.3-71-gd317 From c7b95d5156a9ee70f800bd2e47a9eba677be73e1 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 19 Mar 2018 17:51:36 +0100 Subject: mm: add ksys_readahead() helper; remove in-kernel calls to sys_readahead() Using this helper allows us to avoid the in-kernel calls to the sys_readahead() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_readahead(). 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: Andrew Morton Cc: linux-mm@kvack.org Signed-off-by: Dominik Brodowski --- arch/mips/kernel/linux32.c | 2 +- arch/parisc/kernel/sys_parisc.c | 2 +- arch/powerpc/kernel/sys_ppc32.c | 2 +- arch/s390/kernel/compat_linux.c | 2 +- arch/sparc/kernel/sys_sparc32.c | 2 +- arch/x86/ia32/sys_ia32.c | 2 +- include/linux/syscalls.h | 1 + mm/readahead.c | 7 ++++++- 8 files changed, 13 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 0571ab7b68b0..318f1c05c5b3 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -131,7 +131,7 @@ SYSCALL_DEFINE1(32_personality, unsigned long, personality) asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3, size_t count) { - return sys_readahead(fd, merge_64(a2, a3), count); + return ksys_readahead(fd, merge_64(a2, a3), count); } asmlinkage long sys32_sync_file_range(int fd, int __pad, diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 080d566654ea..8c99ebbe2bac 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -345,7 +345,7 @@ asmlinkage ssize_t parisc_pwrite64(unsigned int fd, const char __user *buf, asmlinkage ssize_t parisc_readahead(int fd, unsigned int high, unsigned int low, size_t count) { - return sys_readahead(fd, (loff_t)high << 32 | low, count); + return ksys_readahead(fd, (loff_t)high << 32 | low, count); } asmlinkage long parisc_fadvise64_64(int fd, diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 0b95fa13307f..c11c73373691 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -88,7 +88,7 @@ compat_ssize_t compat_sys_pwrite64(unsigned int fd, const char __user *ubuf, com compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count) { - return sys_readahead(fd, ((loff_t)offhi << 32) | offlo, count); + return ksys_readahead(fd, ((loff_t)offhi << 32) | offlo, count); } asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4, diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index da5ef7718254..8ac38d51ed7d 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -328,7 +328,7 @@ COMPAT_SYSCALL_DEFINE5(s390_pwrite64, unsigned int, fd, const char __user *, ubu COMPAT_SYSCALL_DEFINE4(s390_readahead, int, fd, u32, high, u32, low, s32, count) { - return sys_readahead(fd, (unsigned long)high << 32 | low, count); + return ksys_readahead(fd, (unsigned long)high << 32 | low, count); } struct stat64_emu31 { diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index 4da66aed50b4..f166e5bbf506 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -217,7 +217,7 @@ asmlinkage long compat_sys_readahead(int fd, unsigned long offlo, compat_size_t count) { - return sys_readahead(fd, (offhi << 32) | offlo, count); + return ksys_readahead(fd, (offhi << 32) | offlo, count); } long compat_sys_fadvise64(int fd, diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index bff71b9ae3f5..bd8a7020b9a7 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -203,7 +203,7 @@ COMPAT_SYSCALL_DEFINE6(x86_fadvise64_64, int, fd, __u32, offset_low, COMPAT_SYSCALL_DEFINE4(x86_readahead, int, fd, unsigned int, off_lo, unsigned int, off_hi, size_t, count) { - return sys_readahead(fd, ((u64)off_hi << 32) | off_lo, count); + return ksys_readahead(fd, ((u64)off_hi << 32) | off_lo, count); } COMPAT_SYSCALL_DEFINE6(x86_sync_file_range, int, fd, unsigned int, off_low, diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index ec866c959e7d..815fbdd9cca1 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -982,6 +982,7 @@ static inline int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff); +ssize_t ksys_readahead(int fd, loff_t offset, size_t count); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/mm/readahead.c b/mm/readahead.c index c4ca70239233..4d57b4644f98 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -573,7 +573,7 @@ do_readahead(struct address_space *mapping, struct file *filp, return force_page_cache_readahead(mapping, filp, index, nr); } -SYSCALL_DEFINE3(readahead, int, fd, loff_t, offset, size_t, count) +ssize_t ksys_readahead(int fd, loff_t offset, size_t count) { ssize_t ret; struct fd f; @@ -592,3 +592,8 @@ SYSCALL_DEFINE3(readahead, int, fd, loff_t, offset, size_t, count) } return ret; } + +SYSCALL_DEFINE3(readahead, int, fd, loff_t, offset, size_t, count) +{ + return ksys_readahead(fd, offset, count); +} -- cgit v1.2.3-71-gd317 From 1bec510a9ebf00baa1aa8751e4a5d88b54efb748 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 22 Mar 2018 17:46:57 +0100 Subject: kexec: move sys_kexec_load() prototype to syscalls.h As the syscall function should only be called from the system call table but not from elsewhere in the kernel, move the prototype for sys_kexec_load() to include/syscall.h. Cc: Eric Biederman Cc: kexec@lists.infradead.org Signed-off-by: Dominik Brodowski --- include/linux/kexec.h | 4 ---- include/linux/syscalls.h | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kexec.h b/include/linux/kexec.h index f16f6ceb3875..0ebcbeb21056 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -223,10 +223,6 @@ struct kimage { extern void machine_kexec(struct kimage *image); extern int machine_kexec_prepare(struct kimage *image); extern void machine_kexec_cleanup(struct kimage *image); -extern asmlinkage long sys_kexec_load(unsigned long entry, - unsigned long nr_segments, - struct kexec_segment __user *segments, - unsigned long flags); extern int kernel_kexec(void); extern struct page *kimage_alloc_control_pages(struct kimage *image, unsigned int order); diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 815fbdd9cca1..8330f046541e 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -936,6 +936,10 @@ asmlinkage long sys_pkey_mprotect(unsigned long start, size_t len, unsigned long prot, int pkey); asmlinkage long sys_pkey_alloc(unsigned long flags, unsigned long init_val); asmlinkage long sys_pkey_free(int pkey); +asmlinkage long sys_kexec_load(unsigned long entry, + unsigned long nr_segments, + struct kexec_segment __user *segments, + unsigned long flags); asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags, unsigned mask, struct statx __user *buffer); -- cgit v1.2.3-71-gd317 From 3c1c456f9b96c208c9dc9ad7aa3be36b8d488504 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 25 Mar 2018 21:50:11 +0200 Subject: syscalls: sort syscall prototypes in include/linux/syscalls.h Shuffle the syscall prototypes in include/linux/syscalls.h around so that they are kept in the same order as in include/uapi/asm-generic/unistd.h. The individual entries are kept the same, and neither modified to bring them in line with kernel coding style nor wrapped in proper ifdefs. Cc: Arnd Bergmann Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- include/linux/syscalls.h | 1226 +++++++++++++++++++++++++--------------------- 1 file changed, 678 insertions(+), 548 deletions(-) (limited to 'include/linux') diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 8330f046541e..1f223b7cf16d 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -241,223 +241,28 @@ static inline void addr_limit_user_check(void) #endif } -asmlinkage long sys_time(time_t __user *tloc); -asmlinkage long sys_stime(time_t __user *tptr); -asmlinkage long sys_gettimeofday(struct timeval __user *tv, - struct timezone __user *tz); -asmlinkage long sys_settimeofday(struct timeval __user *tv, - struct timezone __user *tz); -asmlinkage long sys_adjtimex(struct timex __user *txc_p); - -asmlinkage long sys_times(struct tms __user *tbuf); - -asmlinkage long sys_gettid(void); -asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp); -asmlinkage long sys_alarm(unsigned int seconds); -asmlinkage long sys_getpid(void); -asmlinkage long sys_getppid(void); -asmlinkage long sys_getuid(void); -asmlinkage long sys_geteuid(void); -asmlinkage long sys_getgid(void); -asmlinkage long sys_getegid(void); -asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid); -asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid); -asmlinkage long sys_getpgid(pid_t pid); -asmlinkage long sys_getpgrp(void); -asmlinkage long sys_getsid(pid_t pid); -asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist); - -asmlinkage long sys_setregid(gid_t rgid, gid_t egid); -asmlinkage long sys_setgid(gid_t gid); -asmlinkage long sys_setreuid(uid_t ruid, uid_t euid); -asmlinkage long sys_setuid(uid_t uid); -asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); -asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); -asmlinkage long sys_setfsuid(uid_t uid); -asmlinkage long sys_setfsgid(gid_t gid); -asmlinkage long sys_setpgid(pid_t pid, pid_t pgid); -asmlinkage long sys_setsid(void); -asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist); - -asmlinkage long sys_acct(const char __user *name); -asmlinkage long sys_capget(cap_user_header_t header, - cap_user_data_t dataptr); -asmlinkage long sys_capset(cap_user_header_t header, - const cap_user_data_t data); -asmlinkage long sys_personality(unsigned int personality); - -asmlinkage long sys_sigpending(old_sigset_t __user *uset); -asmlinkage long sys_sigprocmask(int how, old_sigset_t __user *set, - old_sigset_t __user *oset); -asmlinkage long sys_sigaltstack(const struct sigaltstack __user *uss, - struct sigaltstack __user *uoss); - -asmlinkage long sys_getitimer(int which, struct itimerval __user *value); -asmlinkage long sys_setitimer(int which, - struct itimerval __user *value, - struct itimerval __user *ovalue); -asmlinkage long sys_timer_create(clockid_t which_clock, - struct sigevent __user *timer_event_spec, - timer_t __user * created_timer_id); -asmlinkage long sys_timer_gettime(timer_t timer_id, - struct itimerspec __user *setting); -asmlinkage long sys_timer_getoverrun(timer_t timer_id); -asmlinkage long sys_timer_settime(timer_t timer_id, int flags, - const struct itimerspec __user *new_setting, - struct itimerspec __user *old_setting); -asmlinkage long sys_timer_delete(timer_t timer_id); -asmlinkage long sys_clock_settime(clockid_t which_clock, - const struct timespec __user *tp); -asmlinkage long sys_clock_gettime(clockid_t which_clock, - struct timespec __user *tp); -asmlinkage long sys_clock_adjtime(clockid_t which_clock, - struct timex __user *tx); -asmlinkage long sys_clock_getres(clockid_t which_clock, - struct timespec __user *tp); -asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags, - const struct timespec __user *rqtp, - struct timespec __user *rmtp); - -asmlinkage long sys_nice(int increment); -asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, - struct sched_param __user *param); -asmlinkage long sys_sched_setparam(pid_t pid, - struct sched_param __user *param); -asmlinkage long sys_sched_setattr(pid_t pid, - struct sched_attr __user *attr, - unsigned int flags); -asmlinkage long sys_sched_getscheduler(pid_t pid); -asmlinkage long sys_sched_getparam(pid_t pid, - struct sched_param __user *param); -asmlinkage long sys_sched_getattr(pid_t pid, - struct sched_attr __user *attr, - unsigned int size, - unsigned int flags); -asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, - unsigned long __user *user_mask_ptr); -asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, - unsigned long __user *user_mask_ptr); -asmlinkage long sys_sched_yield(void); -asmlinkage long sys_sched_get_priority_max(int policy); -asmlinkage long sys_sched_get_priority_min(int policy); -asmlinkage long sys_sched_rr_get_interval(pid_t pid, - struct timespec __user *interval); -asmlinkage long sys_setpriority(int which, int who, int niceval); -asmlinkage long sys_getpriority(int which, int who); - -asmlinkage long sys_shutdown(int, int); -asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, - void __user *arg); -asmlinkage long sys_restart_syscall(void); -asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, - struct kexec_segment __user *segments, - unsigned long flags); -asmlinkage long sys_kexec_file_load(int kernel_fd, int initrd_fd, - unsigned long cmdline_len, - const char __user *cmdline_ptr, - unsigned long flags); - -asmlinkage long sys_exit(int error_code); -asmlinkage long sys_exit_group(int error_code); -asmlinkage long sys_wait4(pid_t pid, int __user *stat_addr, - int options, struct rusage __user *ru); -asmlinkage long sys_waitid(int which, pid_t pid, - struct siginfo __user *infop, - int options, struct rusage __user *ru); -asmlinkage long sys_waitpid(pid_t pid, int __user *stat_addr, int options); -asmlinkage long sys_set_tid_address(int __user *tidptr); -asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, - struct timespec __user *utime, u32 __user *uaddr2, - u32 val3); - -asmlinkage long sys_init_module(void __user *umod, unsigned long len, - const char __user *uargs); -asmlinkage long sys_delete_module(const char __user *name_user, - unsigned int flags); - -#ifdef CONFIG_OLD_SIGSUSPEND -asmlinkage long sys_sigsuspend(old_sigset_t mask); -#endif - -#ifdef CONFIG_OLD_SIGSUSPEND3 -asmlinkage long sys_sigsuspend(int unused1, int unused2, old_sigset_t mask); -#endif - -asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize); - -#ifdef CONFIG_OLD_SIGACTION -asmlinkage long sys_sigaction(int, const struct old_sigaction __user *, - struct old_sigaction __user *); -#endif - -#ifndef CONFIG_ODD_RT_SIGACTION -asmlinkage long sys_rt_sigaction(int, - const struct sigaction __user *, - struct sigaction __user *, - size_t); -#endif -asmlinkage long sys_rt_sigprocmask(int how, sigset_t __user *set, - sigset_t __user *oset, size_t sigsetsize); -asmlinkage long sys_rt_sigpending(sigset_t __user *set, size_t sigsetsize); -asmlinkage long sys_rt_sigtimedwait(const sigset_t __user *uthese, - siginfo_t __user *uinfo, - const struct timespec __user *uts, - size_t sigsetsize); -asmlinkage long sys_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, - siginfo_t __user *uinfo); -asmlinkage long sys_kill(pid_t pid, int sig); -asmlinkage long sys_tgkill(pid_t tgid, pid_t pid, int sig); -asmlinkage long sys_tkill(pid_t pid, int sig); -asmlinkage long sys_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t __user *uinfo); -asmlinkage long sys_sgetmask(void); -asmlinkage long sys_ssetmask(int newmask); -asmlinkage long sys_signal(int sig, __sighandler_t handler); -asmlinkage long sys_pause(void); - -asmlinkage long sys_sync(void); -asmlinkage long sys_fsync(unsigned int fd); -asmlinkage long sys_fdatasync(unsigned int fd); -asmlinkage long sys_bdflush(int func, long data); -asmlinkage long sys_mount(char __user *dev_name, char __user *dir_name, - char __user *type, unsigned long flags, - void __user *data); -asmlinkage long sys_umount(char __user *name, int flags); -asmlinkage long sys_oldumount(char __user *name); -asmlinkage long sys_truncate(const char __user *path, long length); -asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length); -asmlinkage long sys_stat(const char __user *filename, - struct __old_kernel_stat __user *statbuf); -asmlinkage long sys_statfs(const char __user * path, - struct statfs __user *buf); -asmlinkage long sys_statfs64(const char __user *path, size_t sz, - struct statfs64 __user *buf); -asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user *buf); -asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, - struct statfs64 __user *buf); -asmlinkage long sys_lstat(const char __user *filename, - struct __old_kernel_stat __user *statbuf); -asmlinkage long sys_fstat(unsigned int fd, - struct __old_kernel_stat __user *statbuf); -asmlinkage long sys_newstat(const char __user *filename, - struct stat __user *statbuf); -asmlinkage long sys_newlstat(const char __user *filename, - struct stat __user *statbuf); -asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf); -asmlinkage long sys_ustat(unsigned dev, struct ustat __user *ubuf); -#if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64) -asmlinkage long sys_stat64(const char __user *filename, - struct stat64 __user *statbuf); -asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user *statbuf); -asmlinkage long sys_lstat64(const char __user *filename, - struct stat64 __user *statbuf); -asmlinkage long sys_fstatat64(int dfd, const char __user *filename, - struct stat64 __user *statbuf, int flag); -#endif -#if BITS_PER_LONG == 32 -asmlinkage long sys_truncate64(const char __user *path, loff_t length); -asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length); -#endif +/* + * These syscall function prototypes are kept in the same order as + * include/uapi/asm-generic/unistd.h. Architecture specific entries go below, + * followed by deprecated or obsolete system calls. + * + * Please note that these prototypes here are only provided for information + * purposes, for static analysis, and for linking from the syscall table. + * These functions should not be called elsewhere from kernel code. + */ +asmlinkage long sys_io_setup(unsigned nr_reqs, aio_context_t __user *ctx); +asmlinkage long sys_io_destroy(aio_context_t ctx); +asmlinkage long sys_io_submit(aio_context_t, long, + struct iocb __user * __user *); +asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb, + struct io_event __user *result); +asmlinkage long sys_io_getevents(aio_context_t ctx_id, + long min_nr, + long nr, + struct io_event __user *events, + struct timespec __user *timeout); +/* fs/xattr.c */ asmlinkage long sys_setxattr(const char __user *path, const char __user *name, const void __user *value, size_t size, int flags); asmlinkage long sys_lsetxattr(const char __user *path, const char __user *name, @@ -481,125 +286,126 @@ asmlinkage long sys_lremovexattr(const char __user *path, const char __user *name); asmlinkage long sys_fremovexattr(int fd, const char __user *name); -asmlinkage long sys_brk(unsigned long brk); -asmlinkage long sys_mprotect(unsigned long start, size_t len, - unsigned long prot); -asmlinkage long sys_mremap(unsigned long addr, - unsigned long old_len, unsigned long new_len, - unsigned long flags, unsigned long new_addr); -asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size, - unsigned long prot, unsigned long pgoff, - unsigned long flags); -asmlinkage long sys_msync(unsigned long start, size_t len, int flags); -asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice); -asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice); -asmlinkage long sys_munmap(unsigned long addr, size_t len); -asmlinkage long sys_mlock(unsigned long start, size_t len); -asmlinkage long sys_munlock(unsigned long start, size_t len); -asmlinkage long sys_mlockall(int flags); -asmlinkage long sys_munlockall(void); -asmlinkage long sys_madvise(unsigned long start, size_t len, int behavior); -asmlinkage long sys_mincore(unsigned long start, size_t len, - unsigned char __user * vec); +/* fs/dcache.c */ +asmlinkage long sys_getcwd(char __user *buf, unsigned long size); -asmlinkage long sys_pivot_root(const char __user *new_root, - const char __user *put_old); -asmlinkage long sys_chroot(const char __user *filename); -asmlinkage long sys_mknod(const char __user *filename, umode_t mode, - unsigned dev); -asmlinkage long sys_link(const char __user *oldname, - const char __user *newname); -asmlinkage long sys_symlink(const char __user *old, const char __user *new); -asmlinkage long sys_unlink(const char __user *pathname); -asmlinkage long sys_rename(const char __user *oldname, - const char __user *newname); -asmlinkage long sys_chmod(const char __user *filename, umode_t mode); -asmlinkage long sys_fchmod(unsigned int fd, umode_t mode); +/* fs/cookies.c */ +asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user *buf, size_t len); + +/* fs/eventfd.c */ +asmlinkage long sys_eventfd2(unsigned int count, int flags); +/* fs/eventpoll.c */ +asmlinkage long sys_epoll_create1(int flags); +asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, + struct epoll_event __user *event); +asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events, + int maxevents, int timeout, + const sigset_t __user *sigmask, + size_t sigsetsize); + +/* fs/fcntl.c */ +asmlinkage long sys_dup(unsigned int fildes); +asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags); asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); #if BITS_PER_LONG == 32 asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg); #endif -asmlinkage long sys_pipe(int __user *fildes); -asmlinkage long sys_pipe2(int __user *fildes, int flags); -asmlinkage long sys_dup(unsigned int fildes); -asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd); -asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags); -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on); + +/* fs/inotify_user.c */ +asmlinkage long sys_inotify_init1(int flags); +asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, + u32 mask); +asmlinkage long sys_inotify_rm_watch(int fd, __s32 wd); + +/* fs/ioctl.c */ asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); + +/* fs/ioprio.c */ +asmlinkage long sys_ioprio_set(int which, int who, int ioprio); +asmlinkage long sys_ioprio_get(int which, int who); + +/* fs/locks.c */ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd); -asmlinkage long sys_io_setup(unsigned nr_reqs, aio_context_t __user *ctx); -asmlinkage long sys_io_destroy(aio_context_t ctx); -asmlinkage long sys_io_getevents(aio_context_t ctx_id, - long min_nr, - long nr, - struct io_event __user *events, - struct timespec __user *timeout); -asmlinkage long sys_io_submit(aio_context_t, long, - struct iocb __user * __user *); -asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb, - struct io_event __user *result); -asmlinkage long sys_sendfile(int out_fd, int in_fd, - off_t __user *offset, size_t count); -asmlinkage long sys_sendfile64(int out_fd, int in_fd, - loff_t __user *offset, size_t count); -asmlinkage long sys_readlink(const char __user *path, - char __user *buf, int bufsiz); -asmlinkage long sys_creat(const char __user *pathname, umode_t mode); -asmlinkage long sys_open(const char __user *filename, - int flags, umode_t mode); + +/* fs/namei.c */ +asmlinkage long sys_mknodat(int dfd, const char __user * filename, umode_t mode, + unsigned dev); +asmlinkage long sys_mkdirat(int dfd, const char __user * pathname, umode_t mode); +asmlinkage long sys_unlinkat(int dfd, const char __user * pathname, int flag); +asmlinkage long sys_symlinkat(const char __user * oldname, + int newdfd, const char __user * newname); +asmlinkage long sys_linkat(int olddfd, const char __user *oldname, + int newdfd, const char __user *newname, int flags); +asmlinkage long sys_renameat(int olddfd, const char __user * oldname, + int newdfd, const char __user * newname); + +/* fs/namespace.c */ +asmlinkage long sys_umount(char __user *name, int flags); +asmlinkage long sys_mount(char __user *dev_name, char __user *dir_name, + char __user *type, unsigned long flags, + void __user *data); +asmlinkage long sys_pivot_root(const char __user *new_root, + const char __user *put_old); + +/* fs/nfsctl.c */ + +/* fs/open.c */ +asmlinkage long sys_statfs(const char __user * path, + struct statfs __user *buf); +asmlinkage long sys_statfs64(const char __user *path, size_t sz, + struct statfs64 __user *buf); +asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user *buf); +asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, + struct statfs64 __user *buf); +asmlinkage long sys_truncate(const char __user *path, long length); +asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length); +#if BITS_PER_LONG == 32 +asmlinkage long sys_truncate64(const char __user *path, loff_t length); +asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length); +#endif +asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len); +asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode); +asmlinkage long sys_chdir(const char __user *filename); +asmlinkage long sys_fchdir(unsigned int fd); +asmlinkage long sys_chroot(const char __user *filename); +asmlinkage long sys_fchmod(unsigned int fd, umode_t mode); +asmlinkage long sys_fchmodat(int dfd, const char __user * filename, + umode_t mode); +asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, + gid_t group, int flag); +asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group); +asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, + umode_t mode); asmlinkage long sys_close(unsigned int fd); -asmlinkage long sys_access(const char __user *filename, int mode); asmlinkage long sys_vhangup(void); -asmlinkage long sys_chown(const char __user *filename, - uid_t user, gid_t group); -asmlinkage long sys_lchown(const char __user *filename, - uid_t user, gid_t group); -asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group); -#ifdef CONFIG_HAVE_UID16 -asmlinkage long sys_chown16(const char __user *filename, - old_uid_t user, old_gid_t group); -asmlinkage long sys_lchown16(const char __user *filename, - old_uid_t user, old_gid_t group); -asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group); -asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid); -asmlinkage long sys_setgid16(old_gid_t gid); -asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid); -asmlinkage long sys_setuid16(old_uid_t uid); -asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid); -asmlinkage long sys_getresuid16(old_uid_t __user *ruid, - old_uid_t __user *euid, old_uid_t __user *suid); -asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid); -asmlinkage long sys_getresgid16(old_gid_t __user *rgid, - old_gid_t __user *egid, old_gid_t __user *sgid); -asmlinkage long sys_setfsuid16(old_uid_t uid); -asmlinkage long sys_setfsgid16(old_gid_t gid); -asmlinkage long sys_getgroups16(int gidsetsize, old_gid_t __user *grouplist); -asmlinkage long sys_setgroups16(int gidsetsize, old_gid_t __user *grouplist); -asmlinkage long sys_getuid16(void); -asmlinkage long sys_geteuid16(void); -asmlinkage long sys_getgid16(void); -asmlinkage long sys_getegid16(void); -#endif -asmlinkage long sys_utime(char __user *filename, - struct utimbuf __user *times); -asmlinkage long sys_utimes(char __user *filename, - struct timeval __user *utimes); -asmlinkage long sys_lseek(unsigned int fd, off_t offset, - unsigned int whence); +/* fs/pipe.c */ +asmlinkage long sys_pipe2(int __user *fildes, int flags); + +/* fs/quota.c */ +asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, + qid_t id, void __user *addr); + +/* fs/readdir.c */ +asmlinkage long sys_getdents64(unsigned int fd, + struct linux_dirent64 __user *dirent, + unsigned int count); + +/* fs/read_write.c */ asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t __user *result, unsigned int whence); +asmlinkage long sys_lseek(unsigned int fd, off_t offset, + unsigned int whence); asmlinkage long sys_read(unsigned int fd, char __user *buf, size_t count); -asmlinkage long sys_readahead(int fd, loff_t offset, size_t count); +asmlinkage long sys_write(unsigned int fd, const char __user *buf, + size_t count); asmlinkage long sys_readv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen); -asmlinkage long sys_write(unsigned int fd, const char __user *buf, - size_t count); asmlinkage long sys_writev(unsigned long fd, const struct iovec __user *vec, unsigned long vlen); @@ -609,264 +415,314 @@ asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf, size_t count, loff_t pos); asmlinkage long sys_preadv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h); -asmlinkage long sys_preadv2(unsigned long fd, const struct iovec __user *vec, - unsigned long vlen, unsigned long pos_l, unsigned long pos_h, - rwf_t flags); asmlinkage long sys_pwritev(unsigned long fd, const struct iovec __user *vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h); -asmlinkage long sys_pwritev2(unsigned long fd, const struct iovec __user *vec, - unsigned long vlen, unsigned long pos_l, unsigned long pos_h, - rwf_t flags); -asmlinkage long sys_getcwd(char __user *buf, unsigned long size); -asmlinkage long sys_mkdir(const char __user *pathname, umode_t mode); -asmlinkage long sys_chdir(const char __user *filename); -asmlinkage long sys_fchdir(unsigned int fd); -asmlinkage long sys_rmdir(const char __user *pathname); -asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user *buf, size_t len); -asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, - qid_t id, void __user *addr); -asmlinkage long sys_getdents(unsigned int fd, - struct linux_dirent __user *dirent, - unsigned int count); -asmlinkage long sys_getdents64(unsigned int fd, - struct linux_dirent64 __user *dirent, - unsigned int count); -asmlinkage long sys_setsockopt(int fd, int level, int optname, - char __user *optval, int optlen); -asmlinkage long sys_getsockopt(int fd, int level, int optname, - char __user *optval, int __user *optlen); -asmlinkage long sys_bind(int, struct sockaddr __user *, int); -asmlinkage long sys_connect(int, struct sockaddr __user *, int); -asmlinkage long sys_accept(int, struct sockaddr __user *, int __user *); -asmlinkage long sys_accept4(int, struct sockaddr __user *, int __user *, int); -asmlinkage long sys_getsockname(int, struct sockaddr __user *, int __user *); -asmlinkage long sys_getpeername(int, struct sockaddr __user *, int __user *); -asmlinkage long sys_send(int, void __user *, size_t, unsigned); -asmlinkage long sys_sendto(int, void __user *, size_t, unsigned, - struct sockaddr __user *, int); -asmlinkage long sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags); -asmlinkage long sys_sendmmsg(int fd, struct mmsghdr __user *msg, - unsigned int vlen, unsigned flags); -asmlinkage long sys_recv(int, void __user *, size_t, unsigned); -asmlinkage long sys_recvfrom(int, void __user *, size_t, unsigned, - struct sockaddr __user *, int __user *); -asmlinkage long sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags); -asmlinkage long sys_recvmmsg(int fd, struct mmsghdr __user *msg, - unsigned int vlen, unsigned flags, - struct timespec __user *timeout); -asmlinkage long sys_socket(int, int, int); -asmlinkage long sys_socketpair(int, int, int, int __user *); -asmlinkage long sys_socketcall(int call, unsigned long __user *args); -asmlinkage long sys_listen(int, int); -asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, - int timeout); -asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, struct timeval __user *tvp); -asmlinkage long sys_old_select(struct sel_arg_struct __user *arg); -asmlinkage long sys_epoll_create(int size); -asmlinkage long sys_epoll_create1(int flags); -asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, - struct epoll_event __user *event); -asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, - int maxevents, int timeout); -asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events, - int maxevents, int timeout, - const sigset_t __user *sigmask, +/* fs/sendfile.c */ +asmlinkage long sys_sendfile64(int out_fd, int in_fd, + loff_t __user *offset, size_t count); + +/* fs/select.c */ +asmlinkage long sys_pselect6(int, fd_set __user *, fd_set __user *, + fd_set __user *, struct timespec __user *, + void __user *); +asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int, + struct timespec __user *, const sigset_t __user *, + size_t); + +/* fs/signalfd.c */ +asmlinkage long sys_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask, int flags); + +/* fs/splice.c */ +asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, + unsigned long nr_segs, unsigned int flags); +asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, + int fd_out, loff_t __user *off_out, + size_t len, unsigned int flags); +asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags); + +/* fs/stat.c */ +asmlinkage long sys_readlinkat(int dfd, const char __user *path, char __user *buf, + int bufsiz); +asmlinkage long sys_newfstatat(int dfd, const char __user *filename, + struct stat __user *statbuf, int flag); +asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf); +#if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64) +asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user *statbuf); +asmlinkage long sys_fstatat64(int dfd, const char __user *filename, + struct stat64 __user *statbuf, int flag); +#endif + +/* fs/sync.c */ +asmlinkage long sys_sync(void); +asmlinkage long sys_fsync(unsigned int fd); +asmlinkage long sys_fdatasync(unsigned int fd); +asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, + loff_t offset, loff_t nbytes); +asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, + unsigned int flags); + +/* fs/timerfd.c */ +asmlinkage long sys_timerfd_create(int clockid, int flags); +asmlinkage long sys_timerfd_settime(int ufd, int flags, + const struct itimerspec __user *utmr, + struct itimerspec __user *otmr); +asmlinkage long sys_timerfd_gettime(int ufd, struct itimerspec __user *otmr); + +/* fs/utimes.c */ +asmlinkage long sys_utimensat(int dfd, const char __user *filename, + struct timespec __user *utimes, int flags); + +/* kernel/acct.c */ +asmlinkage long sys_acct(const char __user *name); + +/* kernel/capability.c */ +asmlinkage long sys_capget(cap_user_header_t header, + cap_user_data_t dataptr); +asmlinkage long sys_capset(cap_user_header_t header, + const cap_user_data_t data); + +/* kernel/exec_domain.c */ +asmlinkage long sys_personality(unsigned int personality); + +/* kernel/exit.c */ +asmlinkage long sys_exit(int error_code); +asmlinkage long sys_exit_group(int error_code); +asmlinkage long sys_waitid(int which, pid_t pid, + struct siginfo __user *infop, + int options, struct rusage __user *ru); + +/* kernel/fork.c */ +asmlinkage long sys_set_tid_address(int __user *tidptr); +asmlinkage long sys_unshare(unsigned long unshare_flags); + +/* kernel/futex.c */ +asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, + struct timespec __user *utime, u32 __user *uaddr2, + u32 val3); +asmlinkage long sys_get_robust_list(int pid, + struct robust_list_head __user * __user *head_ptr, + size_t __user *len_ptr); +asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, + size_t len); + +/* kernel/hrtimer.c */ +asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp); + +/* kernel/itimer.c */ +asmlinkage long sys_getitimer(int which, struct itimerval __user *value); +asmlinkage long sys_setitimer(int which, + struct itimerval __user *value, + struct itimerval __user *ovalue); + +/* kernel/kexec.c */ +asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, + struct kexec_segment __user *segments, + unsigned long flags); + +/* kernel/module.c */ +asmlinkage long sys_init_module(void __user *umod, unsigned long len, + const char __user *uargs); +asmlinkage long sys_delete_module(const char __user *name_user, + unsigned int flags); + +/* kernel/posix-timers.c */ +asmlinkage long sys_timer_create(clockid_t which_clock, + struct sigevent __user *timer_event_spec, + timer_t __user * created_timer_id); +asmlinkage long sys_timer_gettime(timer_t timer_id, + struct itimerspec __user *setting); +asmlinkage long sys_timer_getoverrun(timer_t timer_id); +asmlinkage long sys_timer_settime(timer_t timer_id, int flags, + const struct itimerspec __user *new_setting, + struct itimerspec __user *old_setting); +asmlinkage long sys_timer_delete(timer_t timer_id); +asmlinkage long sys_clock_settime(clockid_t which_clock, + const struct timespec __user *tp); +asmlinkage long sys_clock_gettime(clockid_t which_clock, + struct timespec __user *tp); +asmlinkage long sys_clock_getres(clockid_t which_clock, + struct timespec __user *tp); +asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags, + const struct timespec __user *rqtp, + struct timespec __user *rmtp); + +/* kernel/printk.c */ +asmlinkage long sys_syslog(int type, char __user *buf, int len); + +/* kernel/ptrace.c */ +asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, + unsigned long data); +/* kernel/sched/core.c */ + +asmlinkage long sys_sched_setparam(pid_t pid, + struct sched_param __user *param); +asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, + struct sched_param __user *param); +asmlinkage long sys_sched_getscheduler(pid_t pid); +asmlinkage long sys_sched_getparam(pid_t pid, + struct sched_param __user *param); +asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, + unsigned long __user *user_mask_ptr); +asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, + unsigned long __user *user_mask_ptr); +asmlinkage long sys_sched_yield(void); +asmlinkage long sys_sched_get_priority_max(int policy); +asmlinkage long sys_sched_get_priority_min(int policy); +asmlinkage long sys_sched_rr_get_interval(pid_t pid, + struct timespec __user *interval); + +/* kernel/signal.c */ +asmlinkage long sys_restart_syscall(void); +asmlinkage long sys_kill(pid_t pid, int sig); +asmlinkage long sys_tkill(pid_t pid, int sig); +asmlinkage long sys_tgkill(pid_t tgid, pid_t pid, int sig); +asmlinkage long sys_sigaltstack(const struct sigaltstack __user *uss, + struct sigaltstack __user *uoss); +asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize); +#ifndef CONFIG_ODD_RT_SIGACTION +asmlinkage long sys_rt_sigaction(int, + const struct sigaction __user *, + struct sigaction __user *, + size_t); +#endif +asmlinkage long sys_rt_sigprocmask(int how, sigset_t __user *set, + sigset_t __user *oset, size_t sigsetsize); +asmlinkage long sys_rt_sigpending(sigset_t __user *set, size_t sigsetsize); +asmlinkage long sys_rt_sigtimedwait(const sigset_t __user *uthese, + siginfo_t __user *uinfo, + const struct timespec __user *uts, size_t sigsetsize); -asmlinkage long sys_gethostname(char __user *name, int len); +asmlinkage long sys_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t __user *uinfo); + +/* kernel/sys.c */ +asmlinkage long sys_setpriority(int which, int who, int niceval); +asmlinkage long sys_getpriority(int which, int who); +asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, + void __user *arg); +asmlinkage long sys_setregid(gid_t rgid, gid_t egid); +asmlinkage long sys_setgid(gid_t gid); +asmlinkage long sys_setreuid(uid_t ruid, uid_t euid); +asmlinkage long sys_setuid(uid_t uid); +asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); +asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid); +asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); +asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid); +asmlinkage long sys_setfsuid(uid_t uid); +asmlinkage long sys_setfsgid(gid_t gid); +asmlinkage long sys_times(struct tms __user *tbuf); +asmlinkage long sys_setpgid(pid_t pid, pid_t pgid); +asmlinkage long sys_getpgid(pid_t pid); +asmlinkage long sys_getsid(pid_t pid); +asmlinkage long sys_setsid(void); +asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist); +asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist); +asmlinkage long sys_newuname(struct new_utsname __user *name); asmlinkage long sys_sethostname(char __user *name, int len); asmlinkage long sys_setdomainname(char __user *name, int len); -asmlinkage long sys_newuname(struct new_utsname __user *name); -asmlinkage long sys_uname(struct old_utsname __user *); -asmlinkage long sys_olduname(struct oldold_utsname __user *); - asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim); -#ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT -asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim); -#endif asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim); -asmlinkage long sys_prlimit64(pid_t pid, unsigned int resource, - const struct rlimit64 __user *new_rlim, - struct rlimit64 __user *old_rlim); asmlinkage long sys_getrusage(int who, struct rusage __user *ru); asmlinkage long sys_umask(int mask); +asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5); +asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache); + +/* kernel/time.c */ +asmlinkage long sys_gettimeofday(struct timeval __user *tv, + struct timezone __user *tz); +asmlinkage long sys_settimeofday(struct timeval __user *tv, + struct timezone __user *tz); +asmlinkage long sys_adjtimex(struct timex __user *txc_p); + +/* kernel/timer.c */ +asmlinkage long sys_getpid(void); +asmlinkage long sys_getppid(void); +asmlinkage long sys_getuid(void); +asmlinkage long sys_geteuid(void); +asmlinkage long sys_getgid(void); +asmlinkage long sys_getegid(void); +asmlinkage long sys_gettid(void); +asmlinkage long sys_sysinfo(struct sysinfo __user *info); + +/* ipc/mqueue.c */ +asmlinkage long sys_mq_open(const char __user *name, int oflag, umode_t mode, struct mq_attr __user *attr); +asmlinkage long sys_mq_unlink(const char __user *name); +asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec __user *abs_timeout); +asmlinkage long sys_mq_timedreceive(mqd_t mqdes, char __user *msg_ptr, size_t msg_len, unsigned int __user *msg_prio, const struct timespec __user *abs_timeout); +asmlinkage long sys_mq_notify(mqd_t mqdes, const struct sigevent __user *notification); +asmlinkage long sys_mq_getsetattr(mqd_t mqdes, const struct mq_attr __user *mqstat, struct mq_attr __user *omqstat); +/* ipc/msg.c */ asmlinkage long sys_msgget(key_t key, int msgflg); -asmlinkage long sys_msgsnd(int msqid, struct msgbuf __user *msgp, - size_t msgsz, int msgflg); +asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf); asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, long msgtyp, int msgflg); -asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf); +asmlinkage long sys_msgsnd(int msqid, struct msgbuf __user *msgp, + size_t msgsz, int msgflg); +/* ipc/sem.c */ asmlinkage long sys_semget(key_t key, int nsems, int semflg); -asmlinkage long sys_semop(int semid, struct sembuf __user *sops, - unsigned nsops); asmlinkage long sys_semctl(int semid, int semnum, int cmd, unsigned long arg); asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops, unsigned nsops, const struct timespec __user *timeout); -asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg); +asmlinkage long sys_semop(int semid, struct sembuf __user *sops, + unsigned nsops); + +/* ipc/shm.c */ asmlinkage long sys_shmget(key_t key, size_t size, int flag); -asmlinkage long sys_shmdt(char __user *shmaddr); asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); -asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, - unsigned long third, void __user *ptr, long fifth); +asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg); +asmlinkage long sys_shmdt(char __user *shmaddr); -asmlinkage long sys_mq_open(const char __user *name, int oflag, umode_t mode, struct mq_attr __user *attr); -asmlinkage long sys_mq_unlink(const char __user *name); -asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec __user *abs_timeout); -asmlinkage long sys_mq_timedreceive(mqd_t mqdes, char __user *msg_ptr, size_t msg_len, unsigned int __user *msg_prio, const struct timespec __user *abs_timeout); -asmlinkage long sys_mq_notify(mqd_t mqdes, const struct sigevent __user *notification); -asmlinkage long sys_mq_getsetattr(mqd_t mqdes, const struct mq_attr __user *mqstat, struct mq_attr __user *omqstat); +/* net/socket.c */ +asmlinkage long sys_socket(int, int, int); +asmlinkage long sys_socketpair(int, int, int, int __user *); +asmlinkage long sys_bind(int, struct sockaddr __user *, int); +asmlinkage long sys_listen(int, int); +asmlinkage long sys_accept(int, struct sockaddr __user *, int __user *); +asmlinkage long sys_connect(int, struct sockaddr __user *, int); +asmlinkage long sys_getsockname(int, struct sockaddr __user *, int __user *); +asmlinkage long sys_getpeername(int, struct sockaddr __user *, int __user *); +asmlinkage long sys_sendto(int, void __user *, size_t, unsigned, + struct sockaddr __user *, int); +asmlinkage long sys_recvfrom(int, void __user *, size_t, unsigned, + struct sockaddr __user *, int __user *); +asmlinkage long sys_setsockopt(int fd, int level, int optname, + char __user *optval, int optlen); +asmlinkage long sys_getsockopt(int fd, int level, int optname, + char __user *optval, int __user *optlen); +asmlinkage long sys_shutdown(int, int); +asmlinkage long sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags); +asmlinkage long sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags); -asmlinkage long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn); -asmlinkage long sys_pciconfig_read(unsigned long bus, unsigned long dfn, - unsigned long off, unsigned long len, - void __user *buf); -asmlinkage long sys_pciconfig_write(unsigned long bus, unsigned long dfn, - unsigned long off, unsigned long len, - void __user *buf); +/* mm/filemap.c */ +asmlinkage long sys_readahead(int fd, loff_t offset, size_t count); -asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, - unsigned long arg4, unsigned long arg5); -asmlinkage long sys_swapon(const char __user *specialfile, int swap_flags); -asmlinkage long sys_swapoff(const char __user *specialfile); -asmlinkage long sys_sysctl(struct __sysctl_args __user *args); -asmlinkage long sys_sysinfo(struct sysinfo __user *info); -asmlinkage long sys_sysfs(int option, - unsigned long arg1, unsigned long arg2); -asmlinkage long sys_syslog(int type, char __user *buf, int len); -asmlinkage long sys_uselib(const char __user *library); -asmlinkage long sys_ni_syscall(void); -asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, - unsigned long data); +/* mm/nommu.c, also with MMU */ +asmlinkage long sys_brk(unsigned long brk); +asmlinkage long sys_munmap(unsigned long addr, size_t len); +asmlinkage long sys_mremap(unsigned long addr, + unsigned long old_len, unsigned long new_len, + unsigned long flags, unsigned long new_addr); +/* security/keys/keyctl.c */ asmlinkage long sys_add_key(const char __user *_type, const char __user *_description, const void __user *_payload, size_t plen, key_serial_t destringid); - asmlinkage long sys_request_key(const char __user *_type, const char __user *_description, const char __user *_callout_info, key_serial_t destringid); - asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); -asmlinkage long sys_ioprio_set(int which, int who, int ioprio); -asmlinkage long sys_ioprio_get(int which, int who); -asmlinkage long sys_set_mempolicy(int mode, const unsigned long __user *nmask, - unsigned long maxnode); -asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode, - const unsigned long __user *from, - const unsigned long __user *to); -asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, - const void __user * __user *pages, - const int __user *nodes, - int __user *status, - int flags); -asmlinkage long sys_mbind(unsigned long start, unsigned long len, - unsigned long mode, - const unsigned long __user *nmask, - unsigned long maxnode, - unsigned flags); -asmlinkage long sys_get_mempolicy(int __user *policy, - unsigned long __user *nmask, - unsigned long maxnode, - unsigned long addr, unsigned long flags); - -asmlinkage long sys_inotify_init(void); -asmlinkage long sys_inotify_init1(int flags); -asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, - u32 mask); -asmlinkage long sys_inotify_rm_watch(int fd, __s32 wd); - -asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, - __u32 __user *ustatus); -asmlinkage long sys_spu_create(const char __user *name, - unsigned int flags, umode_t mode, int fd); - -asmlinkage long sys_mknodat(int dfd, const char __user * filename, umode_t mode, - unsigned dev); -asmlinkage long sys_mkdirat(int dfd, const char __user * pathname, umode_t mode); -asmlinkage long sys_unlinkat(int dfd, const char __user * pathname, int flag); -asmlinkage long sys_symlinkat(const char __user * oldname, - int newdfd, const char __user * newname); -asmlinkage long sys_linkat(int olddfd, const char __user *oldname, - int newdfd, const char __user *newname, int flags); -asmlinkage long sys_renameat(int olddfd, const char __user * oldname, - int newdfd, const char __user * newname); -asmlinkage long sys_renameat2(int olddfd, const char __user *oldname, - int newdfd, const char __user *newname, - unsigned int flags); -asmlinkage long sys_futimesat(int dfd, const char __user *filename, - struct timeval __user *utimes); -asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode); -asmlinkage long sys_fchmodat(int dfd, const char __user * filename, - umode_t mode); -asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, - gid_t group, int flag); -asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, - umode_t mode); -asmlinkage long sys_newfstatat(int dfd, const char __user *filename, - struct stat __user *statbuf, int flag); -asmlinkage long sys_readlinkat(int dfd, const char __user *path, char __user *buf, - int bufsiz); -asmlinkage long sys_utimensat(int dfd, const char __user *filename, - struct timespec __user *utimes, int flags); -asmlinkage long sys_unshare(unsigned long unshare_flags); - -asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, - int fd_out, loff_t __user *off_out, - size_t len, unsigned int flags); - -asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, - unsigned long nr_segs, unsigned int flags); - -asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags); - -asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, - unsigned int flags); -asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, - loff_t offset, loff_t nbytes); -asmlinkage long sys_get_robust_list(int pid, - struct robust_list_head __user * __user *head_ptr, - size_t __user *len_ptr); -asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, - size_t len); -asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache); -asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask); -asmlinkage long sys_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask, int flags); -asmlinkage long sys_timerfd_create(int clockid, int flags); -asmlinkage long sys_timerfd_settime(int ufd, int flags, - const struct itimerspec __user *utmr, - struct itimerspec __user *otmr); -asmlinkage long sys_timerfd_gettime(int ufd, struct itimerspec __user *otmr); -asmlinkage long sys_eventfd(unsigned int count); -asmlinkage long sys_eventfd2(unsigned int count, int flags); -asmlinkage long sys_memfd_create(const char __user *uname_ptr, unsigned int flags); -asmlinkage long sys_userfaultfd(int flags); -asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len); -asmlinkage long sys_old_readdir(unsigned int, struct old_linux_dirent __user *, unsigned int); -asmlinkage long sys_pselect6(int, fd_set __user *, fd_set __user *, - fd_set __user *, struct timespec __user *, - void __user *); -asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int, - struct timespec __user *, const sigset_t __user *, - size_t); -asmlinkage long sys_fanotify_init(unsigned int flags, unsigned int event_f_flags); -asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags, - u64 mask, int fd, - const char __user *pathname); -asmlinkage long sys_syncfs(int fd); - -asmlinkage long sys_fork(void); -asmlinkage long sys_vfork(void); +/* arch/example/kernel/sys_example.c */ #ifdef CONFIG_CLONE_BACKWARDS asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, unsigned long, int __user *); @@ -879,26 +735,80 @@ asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, int __user *, unsigned long); #endif #endif - asmlinkage long sys_execve(const char __user *filename, const char __user *const __user *argv, const char __user *const __user *envp); +/* mm/fadvise.c */ +asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice); + +/* mm/, CONFIG_MMU only */ +asmlinkage long sys_swapon(const char __user *specialfile, int swap_flags); +asmlinkage long sys_swapoff(const char __user *specialfile); +asmlinkage long sys_mprotect(unsigned long start, size_t len, + unsigned long prot); +asmlinkage long sys_msync(unsigned long start, size_t len, int flags); +asmlinkage long sys_mlock(unsigned long start, size_t len); +asmlinkage long sys_munlock(unsigned long start, size_t len); +asmlinkage long sys_mlockall(int flags); +asmlinkage long sys_munlockall(void); +asmlinkage long sys_mincore(unsigned long start, size_t len, + unsigned char __user * vec); +asmlinkage long sys_madvise(unsigned long start, size_t len, int behavior); +asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size, + unsigned long prot, unsigned long pgoff, + unsigned long flags); +asmlinkage long sys_mbind(unsigned long start, unsigned long len, + unsigned long mode, + const unsigned long __user *nmask, + unsigned long maxnode, + unsigned flags); +asmlinkage long sys_get_mempolicy(int __user *policy, + unsigned long __user *nmask, + unsigned long maxnode, + unsigned long addr, unsigned long flags); +asmlinkage long sys_set_mempolicy(int mode, const unsigned long __user *nmask, + unsigned long maxnode); +asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode, + const unsigned long __user *from, + const unsigned long __user *to); +asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, + const void __user * __user *pages, + const int __user *nodes, + int __user *status, + int flags); + +asmlinkage long sys_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, + siginfo_t __user *uinfo); asmlinkage long sys_perf_event_open( struct perf_event_attr __user *attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags); +asmlinkage long sys_accept4(int, struct sockaddr __user *, int __user *, int); +asmlinkage long sys_recvmmsg(int fd, struct mmsghdr __user *msg, + unsigned int vlen, unsigned flags, + struct timespec __user *timeout); -asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff); -asmlinkage long sys_old_mmap(struct mmap_arg_struct __user *arg); +asmlinkage long sys_wait4(pid_t pid, int __user *stat_addr, + int options, struct rusage __user *ru); +asmlinkage long sys_prlimit64(pid_t pid, unsigned int resource, + const struct rlimit64 __user *new_rlim, + struct rlimit64 __user *old_rlim); +asmlinkage long sys_fanotify_init(unsigned int flags, unsigned int event_f_flags); +asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags, + u64 mask, int fd, + const char __user *pathname); asmlinkage long sys_name_to_handle_at(int dfd, const char __user *name, struct file_handle __user *handle, int __user *mnt_id, int flag); asmlinkage long sys_open_by_handle_at(int mountdirfd, struct file_handle __user *handle, int flags); +asmlinkage long sys_clock_adjtime(clockid_t which_clock, + struct timex __user *tx); +asmlinkage long sys_syncfs(int fd); asmlinkage long sys_setns(int fd, int nstype); +asmlinkage long sys_sendmmsg(int fd, struct mmsghdr __user *msg, + unsigned int vlen, unsigned flags); asmlinkage long sys_process_vm_readv(pid_t pid, const struct iovec __user *lvec, unsigned long liovcnt, @@ -911,39 +821,259 @@ asmlinkage long sys_process_vm_writev(pid_t pid, const struct iovec __user *rvec, unsigned long riovcnt, unsigned long flags); - asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2); asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags); +asmlinkage long sys_sched_setattr(pid_t pid, + struct sched_attr __user *attr, + unsigned int flags); +asmlinkage long sys_sched_getattr(pid_t pid, + struct sched_attr __user *attr, + unsigned int size, + unsigned int flags); +asmlinkage long sys_renameat2(int olddfd, const char __user *oldname, + int newdfd, const char __user *newname, + unsigned int flags); asmlinkage long sys_seccomp(unsigned int op, unsigned int flags, const char __user *uargs); asmlinkage long sys_getrandom(char __user *buf, size_t count, unsigned int flags); +asmlinkage long sys_memfd_create(const char __user *uname_ptr, unsigned int flags); asmlinkage long sys_bpf(int cmd, union bpf_attr *attr, unsigned int size); - asmlinkage long sys_execveat(int dfd, const char __user *filename, const char __user *const __user *argv, const char __user *const __user *envp, int flags); - +asmlinkage long sys_userfaultfd(int flags); asmlinkage long sys_membarrier(int cmd, int flags); +asmlinkage long sys_mlock2(unsigned long start, size_t len, int flags); asmlinkage long sys_copy_file_range(int fd_in, loff_t __user *off_in, int fd_out, loff_t __user *off_out, size_t len, unsigned int flags); - -asmlinkage long sys_mlock2(unsigned long start, size_t len, int flags); - +asmlinkage long sys_preadv2(unsigned long fd, const struct iovec __user *vec, + unsigned long vlen, unsigned long pos_l, unsigned long pos_h, + rwf_t flags); +asmlinkage long sys_pwritev2(unsigned long fd, const struct iovec __user *vec, + unsigned long vlen, unsigned long pos_l, unsigned long pos_h, + rwf_t flags); asmlinkage long sys_pkey_mprotect(unsigned long start, size_t len, unsigned long prot, int pkey); asmlinkage long sys_pkey_alloc(unsigned long flags, unsigned long init_val); asmlinkage long sys_pkey_free(int pkey); -asmlinkage long sys_kexec_load(unsigned long entry, - unsigned long nr_segments, - struct kexec_segment __user *segments, - unsigned long flags); asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags, unsigned mask, struct statx __user *buffer); +/* + * Architecture-specific system calls + */ + +/* arch/x86/kernel/ioport.c */ +asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on); + +/* pciconfig: alpha, arm, arm64, ia64, sparc */ +asmlinkage long sys_pciconfig_read(unsigned long bus, unsigned long dfn, + unsigned long off, unsigned long len, + void __user *buf); +asmlinkage long sys_pciconfig_write(unsigned long bus, unsigned long dfn, + unsigned long off, unsigned long len, + void __user *buf); +asmlinkage long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn); + +/* powerpc */ +asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, + __u32 __user *ustatus); +asmlinkage long sys_spu_create(const char __user *name, + unsigned int flags, umode_t mode, int fd); + + +/* + * Deprecated system calls which are still defined in + * include/uapi/asm-generic/unistd.h and wanted by >= 1 arch + */ + +/* __ARCH_WANT_SYSCALL_NO_AT */ +asmlinkage long sys_open(const char __user *filename, + int flags, umode_t mode); +asmlinkage long sys_link(const char __user *oldname, + const char __user *newname); +asmlinkage long sys_unlink(const char __user *pathname); +asmlinkage long sys_mknod(const char __user *filename, umode_t mode, + unsigned dev); +asmlinkage long sys_chmod(const char __user *filename, umode_t mode); +asmlinkage long sys_chown(const char __user *filename, + uid_t user, gid_t group); +asmlinkage long sys_mkdir(const char __user *pathname, umode_t mode); +asmlinkage long sys_rmdir(const char __user *pathname); +asmlinkage long sys_lchown(const char __user *filename, + uid_t user, gid_t group); +asmlinkage long sys_access(const char __user *filename, int mode); +asmlinkage long sys_rename(const char __user *oldname, + const char __user *newname); +asmlinkage long sys_symlink(const char __user *old, const char __user *new); +asmlinkage long sys_utimes(char __user *filename, + struct timeval __user *utimes); +#if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64) +asmlinkage long sys_stat64(const char __user *filename, + struct stat64 __user *statbuf); +asmlinkage long sys_lstat64(const char __user *filename, + struct stat64 __user *statbuf); +#endif + +/* __ARCH_WANT_SYSCALL_NO_FLAGS */ +asmlinkage long sys_pipe(int __user *fildes); +asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd); +asmlinkage long sys_epoll_create(int size); +asmlinkage long sys_inotify_init(void); +asmlinkage long sys_eventfd(unsigned int count); +asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask); + +/* __ARCH_WANT_SYSCALL_OFF_T */ +asmlinkage long sys_sendfile(int out_fd, int in_fd, + off_t __user *offset, size_t count); +asmlinkage long sys_newstat(const char __user *filename, + struct stat __user *statbuf); +asmlinkage long sys_newlstat(const char __user *filename, + struct stat __user *statbuf); +asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice); + +/* __ARCH_WANT_SYSCALL_DEPRECATED */ +asmlinkage long sys_alarm(unsigned int seconds); +asmlinkage long sys_getpgrp(void); +asmlinkage long sys_pause(void); +asmlinkage long sys_time(time_t __user *tloc); +asmlinkage long sys_utime(char __user *filename, + struct utimbuf __user *times); +asmlinkage long sys_creat(const char __user *pathname, umode_t mode); +asmlinkage long sys_getdents(unsigned int fd, + struct linux_dirent __user *dirent, + unsigned int count); +asmlinkage long sys_futimesat(int dfd, const char __user *filename, + struct timeval __user *utimes); +asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, + fd_set __user *exp, struct timeval __user *tvp); +asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, + int timeout); +asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, + int maxevents, int timeout); +asmlinkage long sys_ustat(unsigned dev, struct ustat __user *ubuf); +asmlinkage long sys_vfork(void); +asmlinkage long sys_recv(int, void __user *, size_t, unsigned); +asmlinkage long sys_send(int, void __user *, size_t, unsigned); +asmlinkage long sys_bdflush(int func, long data); +asmlinkage long sys_oldumount(char __user *name); +asmlinkage long sys_uselib(const char __user *library); +asmlinkage long sys_sysctl(struct __sysctl_args __user *args); +asmlinkage long sys_sysfs(int option, + unsigned long arg1, unsigned long arg2); +asmlinkage long sys_fork(void); + +/* obsolete: kernel/time/time.c */ +asmlinkage long sys_stime(time_t __user *tptr); + +/* obsolete: kernel/signal.c */ +asmlinkage long sys_sigpending(old_sigset_t __user *uset); +asmlinkage long sys_sigprocmask(int how, old_sigset_t __user *set, + old_sigset_t __user *oset); +#ifdef CONFIG_OLD_SIGSUSPEND +asmlinkage long sys_sigsuspend(old_sigset_t mask); +#endif + +#ifdef CONFIG_OLD_SIGSUSPEND3 +asmlinkage long sys_sigsuspend(int unused1, int unused2, old_sigset_t mask); +#endif + +#ifdef CONFIG_OLD_SIGACTION +asmlinkage long sys_sigaction(int, const struct old_sigaction __user *, + struct old_sigaction __user *); +#endif +asmlinkage long sys_sgetmask(void); +asmlinkage long sys_ssetmask(int newmask); +asmlinkage long sys_signal(int sig, __sighandler_t handler); + +/* obsolete: kernel/sched/core.c */ +asmlinkage long sys_nice(int increment); + +/* obsolete: kernel/kexec_file.c */ +asmlinkage long sys_kexec_file_load(int kernel_fd, int initrd_fd, + unsigned long cmdline_len, + const char __user *cmdline_ptr, + unsigned long flags); + +/* obsolete: kernel/exit.c */ +asmlinkage long sys_waitpid(pid_t pid, int __user *stat_addr, int options); + +/* obsolete: kernel/uid16.c */ +#ifdef CONFIG_HAVE_UID16 +asmlinkage long sys_chown16(const char __user *filename, + old_uid_t user, old_gid_t group); +asmlinkage long sys_lchown16(const char __user *filename, + old_uid_t user, old_gid_t group); +asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group); +asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid); +asmlinkage long sys_setgid16(old_gid_t gid); +asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid); +asmlinkage long sys_setuid16(old_uid_t uid); +asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid); +asmlinkage long sys_getresuid16(old_uid_t __user *ruid, + old_uid_t __user *euid, old_uid_t __user *suid); +asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid); +asmlinkage long sys_getresgid16(old_gid_t __user *rgid, + old_gid_t __user *egid, old_gid_t __user *sgid); +asmlinkage long sys_setfsuid16(old_uid_t uid); +asmlinkage long sys_setfsgid16(old_gid_t gid); +asmlinkage long sys_getgroups16(int gidsetsize, old_gid_t __user *grouplist); +asmlinkage long sys_setgroups16(int gidsetsize, old_gid_t __user *grouplist); +asmlinkage long sys_getuid16(void); +asmlinkage long sys_geteuid16(void); +asmlinkage long sys_getgid16(void); +asmlinkage long sys_getegid16(void); +#endif + +/* obsolete: net/socket.c */ +asmlinkage long sys_socketcall(int call, unsigned long __user *args); + +/* obsolete: fs/stat.c */ +asmlinkage long sys_stat(const char __user *filename, + struct __old_kernel_stat __user *statbuf); +asmlinkage long sys_lstat(const char __user *filename, + struct __old_kernel_stat __user *statbuf); +asmlinkage long sys_fstat(unsigned int fd, + struct __old_kernel_stat __user *statbuf); +asmlinkage long sys_readlink(const char __user *path, + char __user *buf, int bufsiz); + +/* obsolete: fs/select.c */ +asmlinkage long sys_old_select(struct sel_arg_struct __user *arg); + +/* obsolete: fs/readdir.c */ +asmlinkage long sys_old_readdir(unsigned int, struct old_linux_dirent __user *, unsigned int); + +/* obsolete: kernel/sys.c */ +asmlinkage long sys_gethostname(char __user *name, int len); +asmlinkage long sys_uname(struct old_utsname __user *); +asmlinkage long sys_olduname(struct oldold_utsname __user *); +#ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT +asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim); +#endif + +/* obsolete: ipc */ +asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, + unsigned long third, void __user *ptr, long fifth); + +/* obsolete: mm/ */ +asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff); +asmlinkage long sys_old_mmap(struct mmap_arg_struct __user *arg); + + +/* + * Not a real system call, but a placeholder for syscalls which are + * not implemented -- see kernel/sys_ni.c + */ +asmlinkage long sys_ni_syscall(void); + + /* * Kernel code should not call syscalls (i.e., sys_xyzyyz()) directly. * Instead, use one of the functions which work equivalently, such as -- cgit v1.2.3-71-gd317 From c679a08983db7c1eb09930570b92ff7c9fd59c1c Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 25 Mar 2018 23:04:48 +0200 Subject: syscalls: sort syscall prototypes in include/linux/compat.h Shuffle the syscall prototypes in include/linux/compat.h around so that they are kept in the same order as in include/uapi/asm-generic/unistd.h. The individual entries are kept the same, and neither modified to bring them in line with kernel coding style nor wrapped in proper ifdefs -- as an exception to this, add the prefix "asmlinkage" where it was missing. Cc: Arnd Bergmann Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- include/linux/compat.h | 655 ++++++++++++++++++++++++++++--------------------- 1 file changed, 378 insertions(+), 277 deletions(-) (limited to 'include/linux') diff --git a/include/linux/compat.h b/include/linux/compat.h index f1649a5e6716..f881cce627f6 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -305,10 +305,6 @@ extern int put_compat_rusage(const struct rusage *, struct compat_siginfo; -extern asmlinkage long compat_sys_waitid(int, compat_pid_t, - struct compat_siginfo __user *, int, - struct compat_rusage __user *); - struct compat_dirent { u32 d_ino; compat_off_t d_off; @@ -422,90 +418,6 @@ struct compat_msgbuf; extern void compat_exit_robust_list(struct task_struct *curr); -asmlinkage long -compat_sys_set_robust_list(struct compat_robust_list_head __user *head, - compat_size_t len); -asmlinkage long -compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, - compat_size_t __user *len_ptr); - -asmlinkage long compat_sys_ipc(u32, int, int, u32, compat_uptr_t, u32); -asmlinkage long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg); -asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg); -asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp, - compat_ssize_t msgsz, int msgflg); -asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp, - compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg); -long compat_sys_msgctl(int first, int second, void __user *uptr); -long compat_sys_shmctl(int first, int second, void __user *uptr); -long compat_sys_semtimedop(int semid, struct sembuf __user *tsems, - unsigned nsems, const struct compat_timespec __user *timeout); -asmlinkage long compat_sys_keyctl(u32 option, - u32 arg2, u32 arg3, u32 arg4, u32 arg5); -asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32); - -asmlinkage ssize_t compat_sys_readv(compat_ulong_t fd, - const struct compat_iovec __user *vec, compat_ulong_t vlen); -asmlinkage ssize_t compat_sys_writev(compat_ulong_t fd, - const struct compat_iovec __user *vec, compat_ulong_t vlen); -asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd, - const struct compat_iovec __user *vec, - compat_ulong_t vlen, u32 pos_low, u32 pos_high); -asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd, - const struct compat_iovec __user *vec, - compat_ulong_t vlen, u32 pos_low, u32 pos_high); -asmlinkage ssize_t compat_sys_preadv2(compat_ulong_t fd, - const struct compat_iovec __user *vec, - compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags); -asmlinkage ssize_t compat_sys_pwritev2(compat_ulong_t fd, - const struct compat_iovec __user *vec, - compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags); - -asmlinkage long compat_sys_quotactl32(unsigned int cmd, - const char __user *special, qid_t id, void __user *addr); - -#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64 -asmlinkage long compat_sys_preadv64(unsigned long fd, - const struct compat_iovec __user *vec, - unsigned long vlen, loff_t pos); -#endif - -#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64 -asmlinkage long compat_sys_pwritev64(unsigned long fd, - const struct compat_iovec __user *vec, - unsigned long vlen, loff_t pos); -#endif - -#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64V2 -asmlinkage long compat_sys_readv64v2(unsigned long fd, - const struct compat_iovec __user *vec, - unsigned long vlen, loff_t pos, rwf_t flags); -#endif - -#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64V2 -asmlinkage long compat_sys_pwritev64v2(unsigned long fd, - const struct compat_iovec __user *vec, - unsigned long vlen, loff_t pos, rwf_t flags); -#endif - -asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int); - -asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv, - const compat_uptr_t __user *envp); -asmlinkage long compat_sys_execveat(int dfd, const char __user *filename, - const compat_uptr_t __user *argv, - const compat_uptr_t __user *envp, int flags); - -asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, - compat_ulong_t __user *outp, compat_ulong_t __user *exp, - struct compat_timeval __user *tvp); - -asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg); - -asmlinkage long compat_sys_wait4(compat_pid_t pid, - compat_uint_t __user *stat_addr, int options, - struct compat_rusage __user *ru); - #define BITS_PER_COMPAT_LONG (8*sizeof(compat_long_t)) #define BITS_TO_COMPAT_LONGS(bits) DIV_ROUND_UP(bits, BITS_PER_COMPAT_LONG) @@ -518,13 +430,6 @@ int copy_siginfo_from_user32(siginfo_t *to, const struct compat_siginfo __user * int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *from); int get_compat_sigevent(struct sigevent *event, const struct compat_sigevent __user *u_event); -long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, compat_pid_t pid, int sig, - struct compat_siginfo __user *uinfo); -#ifdef CONFIG_COMPAT_OLD_SIGACTION -asmlinkage long compat_sys_sigaction(int sig, - const struct compat_old_sigaction __user *act, - struct compat_old_sigaction __user *oact); -#endif static inline int compat_timeval_compare(struct compat_timeval *lhs, struct compat_timeval *rhs) @@ -546,13 +451,6 @@ static inline int compat_timespec_compare(struct compat_timespec *lhs, return lhs->tv_nsec - rhs->tv_nsec; } -asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, - struct timezone __user *tz); -asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, - struct timezone __user *tz); - -asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); - extern int get_compat_sigset(sigset_t *set, const compat_sigset_t __user *compat); /* @@ -578,110 +476,132 @@ put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set, #endif } -asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, - compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes, - const compat_ulong_t __user *new_nodes); - extern int compat_ptrace_request(struct task_struct *child, compat_long_t request, compat_ulong_t addr, compat_ulong_t data); extern long compat_arch_ptrace(struct task_struct *child, compat_long_t request, compat_ulong_t addr, compat_ulong_t data); -asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, - compat_long_t addr, compat_long_t data); -asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, compat_size_t); +struct epoll_event; /* fortunately, this one is fixed-layout */ + +extern ssize_t compat_rw_copy_check_uvector(int type, + const struct compat_iovec __user *uvector, + unsigned long nr_segs, + unsigned long fast_segs, struct iovec *fast_pointer, + struct iovec **ret_pointer); + +extern void __user *compat_alloc_user_space(unsigned long len); + +int compat_restore_altstack(const compat_stack_t __user *uss); +int __compat_save_altstack(compat_stack_t __user *, unsigned long); +#define compat_save_altstack_ex(uss, sp) do { \ + compat_stack_t __user *__uss = uss; \ + struct task_struct *t = current; \ + put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &__uss->ss_sp); \ + put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \ + put_user_ex(t->sas_ss_size, &__uss->ss_size); \ + if (t->sas_ss_flags & SS_AUTODISARM) \ + sas_ss_reset(t); \ +} while (0); + /* - * epoll (fs/eventpoll.c) compat bits follow ... + * These syscall function prototypes are kept in the same order as + * include/uapi/asm-generic/unistd.h. Architecture specific entries go below, + * followed by deprecated or obsolete system calls. + * + * Please note that these prototypes here are only provided for information + * purposes, for static analysis, and for linking from the syscall table. + * These functions should not be called elsewhere from kernel code. */ -struct epoll_event; /* fortunately, this one is fixed-layout */ +asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p); +asmlinkage long compat_sys_io_submit(compat_aio_context_t ctx_id, int nr, + u32 __user *iocb); +asmlinkage long compat_sys_io_getevents(compat_aio_context_t ctx_id, + compat_long_t min_nr, + compat_long_t nr, + struct io_event __user *events, + struct compat_timespec __user *timeout); + +/* fs/cookies.c */ +asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, compat_size_t); + +/* fs/eventpoll.c */ asmlinkage long compat_sys_epoll_pwait(int epfd, struct epoll_event __user *events, int maxevents, int timeout, const compat_sigset_t __user *sigmask, compat_size_t sigsetsize); -asmlinkage long compat_sys_utime(const char __user *filename, - struct compat_utimbuf __user *t); -asmlinkage long compat_sys_utimensat(unsigned int dfd, - const char __user *filename, - struct compat_timespec __user *t, - int flags); +/* fs/fcntl.c */ +asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, + compat_ulong_t arg); +asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, + compat_ulong_t arg); -asmlinkage long compat_sys_time(compat_time_t __user *tloc); -asmlinkage long compat_sys_stime(compat_time_t __user *tptr); -asmlinkage long compat_sys_signalfd(int ufd, - const compat_sigset_t __user *sigmask, - compat_size_t sigsetsize); -asmlinkage long compat_sys_timerfd_settime(int ufd, int flags, - const struct compat_itimerspec __user *utmr, - struct compat_itimerspec __user *otmr); -asmlinkage long compat_sys_timerfd_gettime(int ufd, - struct compat_itimerspec __user *otmr); +/* fs/ioctl.c */ +asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, + compat_ulong_t arg); -asmlinkage long compat_sys_move_pages(pid_t pid, compat_ulong_t nr_pages, - __u32 __user *pages, - const int __user *nodes, - int __user *status, - int flags); -asmlinkage long compat_sys_futimesat(unsigned int dfd, - const char __user *filename, - struct compat_timeval __user *t); -asmlinkage long compat_sys_utimes(const char __user *filename, - struct compat_timeval __user *t); -asmlinkage long compat_sys_newstat(const char __user *filename, - struct compat_stat __user *statbuf); -asmlinkage long compat_sys_newlstat(const char __user *filename, - struct compat_stat __user *statbuf); -asmlinkage long compat_sys_newfstatat(unsigned int dfd, - const char __user *filename, - struct compat_stat __user *statbuf, - int flag); -asmlinkage long compat_sys_newfstat(unsigned int fd, - struct compat_stat __user *statbuf); +/* fs/namespace.c */ +asmlinkage long compat_sys_mount(const char __user *dev_name, + const char __user *dir_name, + const char __user *type, compat_ulong_t flags, + const void __user *data); + +/* fs/open.c */ asmlinkage long compat_sys_statfs(const char __user *pathname, struct compat_statfs __user *buf); -asmlinkage long compat_sys_fstatfs(unsigned int fd, - struct compat_statfs __user *buf); asmlinkage long compat_sys_statfs64(const char __user *pathname, compat_size_t sz, struct compat_statfs64 __user *buf); +asmlinkage long compat_sys_fstatfs(unsigned int fd, + struct compat_statfs __user *buf); asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct compat_statfs64 __user *buf); -asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, - compat_ulong_t arg); -asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, - compat_ulong_t arg); -asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p); -asmlinkage long compat_sys_io_getevents(compat_aio_context_t ctx_id, - compat_long_t min_nr, - compat_long_t nr, - struct io_event __user *events, - struct compat_timespec __user *timeout); -asmlinkage long compat_sys_io_submit(compat_aio_context_t ctx_id, int nr, - u32 __user *iocb); -asmlinkage long compat_sys_mount(const char __user *dev_name, - const char __user *dir_name, - const char __user *type, compat_ulong_t flags, - const void __user *data); -asmlinkage long compat_sys_old_readdir(unsigned int fd, - struct compat_old_linux_dirent __user *, - unsigned int count); +asmlinkage long compat_sys_truncate(const char __user *, compat_off_t); +asmlinkage long compat_sys_ftruncate(unsigned int, compat_ulong_t); +/* No generic prototype for truncate64, ftruncate64, fallocate */ +asmlinkage long compat_sys_openat(int dfd, const char __user *filename, + int flags, umode_t mode); + +/* fs/readdir.c */ asmlinkage long compat_sys_getdents(unsigned int fd, struct compat_linux_dirent __user *dirent, unsigned int count); -asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *, - unsigned int nr_segs, unsigned int flags); -asmlinkage long compat_sys_open(const char __user *filename, int flags, - umode_t mode); -asmlinkage long compat_sys_openat(int dfd, const char __user *filename, - int flags, umode_t mode); -asmlinkage long compat_sys_open_by_handle_at(int mountdirfd, - struct file_handle __user *handle, - int flags); -asmlinkage long compat_sys_truncate(const char __user *, compat_off_t); -asmlinkage long compat_sys_ftruncate(unsigned int, compat_ulong_t); + +/* fs/read_write.c */ +asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int); +asmlinkage ssize_t compat_sys_readv(compat_ulong_t fd, + const struct compat_iovec __user *vec, compat_ulong_t vlen); +asmlinkage ssize_t compat_sys_writev(compat_ulong_t fd, + const struct compat_iovec __user *vec, compat_ulong_t vlen); +/* No generic prototype for pread64 and pwrite64 */ +asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd, + const struct compat_iovec __user *vec, + compat_ulong_t vlen, u32 pos_low, u32 pos_high); +asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd, + const struct compat_iovec __user *vec, + compat_ulong_t vlen, u32 pos_low, u32 pos_high); +#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64 +asmlinkage long compat_sys_preadv64(unsigned long fd, + const struct compat_iovec __user *vec, + unsigned long vlen, loff_t pos); +#endif + +#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64 +asmlinkage long compat_sys_pwritev64(unsigned long fd, + const struct compat_iovec __user *vec, + unsigned long vlen, loff_t pos); +#endif + +/* fs/sendfile.c */ +asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, + compat_off_t __user *offset, compat_size_t count); +asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd, + compat_loff_t __user *offset, compat_size_t count); + +/* fs/select.c */ asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp, compat_ulong_t __user *exp, @@ -692,110 +612,149 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, struct compat_timespec __user *tsp, const compat_sigset_t __user *sigmask, compat_size_t sigsetsize); + +/* fs/signalfd.c */ asmlinkage long compat_sys_signalfd4(int ufd, const compat_sigset_t __user *sigmask, compat_size_t sigsetsize, int flags); -asmlinkage long compat_sys_get_mempolicy(int __user *policy, - compat_ulong_t __user *nmask, - compat_ulong_t maxnode, - compat_ulong_t addr, - compat_ulong_t flags); -asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask, - compat_ulong_t maxnode); -asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len, - compat_ulong_t mode, - compat_ulong_t __user *nmask, - compat_ulong_t maxnode, compat_ulong_t flags); -asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, - char __user *optval, unsigned int optlen); -asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, - unsigned flags); -asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, - unsigned vlen, unsigned int flags); -asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, - unsigned int flags); -asmlinkage long compat_sys_recv(int fd, void __user *buf, compat_size_t len, - unsigned flags); -asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, compat_size_t len, - unsigned flags, struct sockaddr __user *addr, - int __user *addrlen); -asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, - unsigned vlen, unsigned int flags, - struct compat_timespec __user *timeout); +/* fs/splice.c */ +asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *, + unsigned int nr_segs, unsigned int flags); + +/* fs/stat.c */ +asmlinkage long compat_sys_newfstatat(unsigned int dfd, + const char __user *filename, + struct compat_stat __user *statbuf, + int flag); +asmlinkage long compat_sys_newfstat(unsigned int fd, + struct compat_stat __user *statbuf); + +/* fs/sync.c: No generic prototype for sync_file_range and sync_file_range2 */ + +/* fs/timerfd.c */ +asmlinkage long compat_sys_timerfd_gettime(int ufd, + struct compat_itimerspec __user *otmr); +asmlinkage long compat_sys_timerfd_settime(int ufd, int flags, + const struct compat_itimerspec __user *utmr, + struct compat_itimerspec __user *otmr); + +/* fs/utimes.c */ +asmlinkage long compat_sys_utimensat(unsigned int dfd, + const char __user *filename, + struct compat_timespec __user *t, + int flags); + +/* kernel/exit.c */ +asmlinkage long compat_sys_waitid(int, compat_pid_t, + struct compat_siginfo __user *, int, + struct compat_rusage __user *); + + + +/* kernel/futex.c */ +asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, + struct compat_timespec __user *utime, u32 __user *uaddr2, + u32 val3); +asmlinkage long +compat_sys_set_robust_list(struct compat_robust_list_head __user *head, + compat_size_t len); +asmlinkage long +compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, + compat_size_t __user *len_ptr); + +/* kernel/hrtimer.c */ asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, struct compat_timespec __user *rmtp); + +/* kernel/itimer.c */ asmlinkage long compat_sys_getitimer(int which, struct compat_itimerval __user *it); asmlinkage long compat_sys_setitimer(int which, struct compat_itimerval __user *in, struct compat_itimerval __user *out); -asmlinkage long compat_sys_times(struct compat_tms __user *tbuf); -asmlinkage long compat_sys_setrlimit(unsigned int resource, - struct compat_rlimit __user *rlim); -asmlinkage long compat_sys_getrlimit(unsigned int resource, - struct compat_rlimit __user *rlim); -asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru); -asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, - unsigned int len, - compat_ulong_t __user *user_mask_ptr); -asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, - unsigned int len, - compat_ulong_t __user *user_mask_ptr); + +/* kernel/kexec.c */ +asmlinkage long compat_sys_kexec_load(compat_ulong_t entry, + compat_ulong_t nr_segments, + struct compat_kexec_segment __user *, + compat_ulong_t flags); + +/* kernel/posix-timers.c */ asmlinkage long compat_sys_timer_create(clockid_t which_clock, struct compat_sigevent __user *timer_event_spec, timer_t __user *created_timer_id); +asmlinkage long compat_sys_timer_gettime(timer_t timer_id, + struct compat_itimerspec __user *setting); asmlinkage long compat_sys_timer_settime(timer_t timer_id, int flags, struct compat_itimerspec __user *new, struct compat_itimerspec __user *old); -asmlinkage long compat_sys_timer_gettime(timer_t timer_id, - struct compat_itimerspec __user *setting); asmlinkage long compat_sys_clock_settime(clockid_t which_clock, struct compat_timespec __user *tp); asmlinkage long compat_sys_clock_gettime(clockid_t which_clock, struct compat_timespec __user *tp); -asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock, - struct compat_timex __user *tp); asmlinkage long compat_sys_clock_getres(clockid_t which_clock, struct compat_timespec __user *tp); asmlinkage long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, struct compat_timespec __user *rqtp, struct compat_timespec __user *rmtp); -asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese, - struct compat_siginfo __user *uinfo, - struct compat_timespec __user *uts, compat_size_t sigsetsize); + +/* kernel/ptrace.c */ +asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, + compat_long_t addr, compat_long_t data); + +/* kernel/sched/core.c */ +asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, + unsigned int len, + compat_ulong_t __user *user_mask_ptr); +asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, + unsigned int len, + compat_ulong_t __user *user_mask_ptr); +asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, + struct compat_timespec __user *interval); + +/* kernel/signal.c */ +asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr, + compat_stack_t __user *uoss_ptr); asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat_size_t sigsetsize); -asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set, - compat_sigset_t __user *oset, - compat_size_t sigsetsize); -asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset, - compat_size_t sigsetsize); #ifndef CONFIG_ODD_RT_SIGACTION asmlinkage long compat_sys_rt_sigaction(int, const struct compat_sigaction __user *, struct compat_sigaction __user *, compat_size_t); #endif +asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set, + compat_sigset_t __user *oset, + compat_size_t sigsetsize); +asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset, + compat_size_t sigsetsize); +asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese, + struct compat_siginfo __user *uinfo, + struct compat_timespec __user *uts, compat_size_t sigsetsize); asmlinkage long compat_sys_rt_sigqueueinfo(compat_pid_t pid, int sig, struct compat_siginfo __user *uinfo); +/* No generic prototype for rt_sigreturn */ + +/* kernel/sys.c */ +asmlinkage long compat_sys_times(struct compat_tms __user *tbuf); +asmlinkage long compat_sys_getrlimit(unsigned int resource, + struct compat_rlimit __user *rlim); +asmlinkage long compat_sys_setrlimit(unsigned int resource, + struct compat_rlimit __user *rlim); +asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru); + +/* kernel/time.c */ +asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, + struct timezone __user *tz); +asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, + struct timezone __user *tz); +asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); + +/* kernel/timer.c */ asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); -asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, - compat_ulong_t arg); -asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, - struct compat_timespec __user *utime, u32 __user *uaddr2, - u32 val3); -asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, - char __user *optval, int __user *optlen); -asmlinkage long compat_sys_kexec_load(compat_ulong_t entry, - compat_ulong_t nr_segments, - struct compat_kexec_segment __user *, - compat_ulong_t flags); -asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes, - const struct compat_mq_attr __user *u_mqstat, - struct compat_mq_attr __user *u_omqstat); -asmlinkage long compat_sys_mq_notify(mqd_t mqdes, - const struct compat_sigevent __user *u_notification); + +/* ipc/mqueue.c */ asmlinkage long compat_sys_mq_open(const char __user *u_name, int oflag, compat_mode_t mode, struct compat_mq_attr __user *u_attr); @@ -807,17 +766,92 @@ asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr, compat_size_t msg_len, unsigned int __user *u_msg_prio, const struct compat_timespec __user *u_abs_timeout); -asmlinkage long compat_sys_socketcall(int call, u32 __user *args); -asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args); +asmlinkage long compat_sys_mq_notify(mqd_t mqdes, + const struct compat_sigevent __user *u_notification); +asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes, + const struct compat_mq_attr __user *u_mqstat, + struct compat_mq_attr __user *u_omqstat); -extern ssize_t compat_rw_copy_check_uvector(int type, - const struct compat_iovec __user *uvector, - unsigned long nr_segs, - unsigned long fast_segs, struct iovec *fast_pointer, - struct iovec **ret_pointer); +/* ipc/msg.c */ +asmlinkage long compat_sys_msgctl(int first, int second, void __user *uptr); +asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp, + compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg); +asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp, + compat_ssize_t msgsz, int msgflg); -extern void __user *compat_alloc_user_space(unsigned long len); +/* ipc/sem.c */ +asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg); +asmlinkage long compat_sys_semtimedop(int semid, struct sembuf __user *tsems, + unsigned nsems, const struct compat_timespec __user *timeout); + +/* ipc/shm.c */ +asmlinkage long compat_sys_shmctl(int first, int second, void __user *uptr); +asmlinkage long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg); + +/* net/socket.c */ +asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, compat_size_t len, + unsigned flags, struct sockaddr __user *addr, + int __user *addrlen); +asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, + char __user *optval, unsigned int optlen); +asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, + char __user *optval, int __user *optlen); +asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, + unsigned flags); +asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, + unsigned int flags); + +/* mm/filemap.c: No generic prototype for readahead */ +/* security/keys/keyctl.c */ +asmlinkage long compat_sys_keyctl(u32 option, + u32 arg2, u32 arg3, u32 arg4, u32 arg5); + +/* arch/example/kernel/sys_example.c */ +asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv, + const compat_uptr_t __user *envp); + +/* mm/fadvise.c: No generic prototype for fadvise64_64 */ + +/* mm/, CONFIG_MMU only */ +asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len, + compat_ulong_t mode, + compat_ulong_t __user *nmask, + compat_ulong_t maxnode, compat_ulong_t flags); +asmlinkage long compat_sys_get_mempolicy(int __user *policy, + compat_ulong_t __user *nmask, + compat_ulong_t maxnode, + compat_ulong_t addr, + compat_ulong_t flags); +asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask, + compat_ulong_t maxnode); +asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, + compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes, + const compat_ulong_t __user *new_nodes); +asmlinkage long compat_sys_move_pages(pid_t pid, compat_ulong_t nr_pages, + __u32 __user *pages, + const int __user *nodes, + int __user *status, + int flags); + +asmlinkage long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, + compat_pid_t pid, int sig, + struct compat_siginfo __user *uinfo); +asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, + unsigned vlen, unsigned int flags, + struct compat_timespec __user *timeout); +asmlinkage long compat_sys_wait4(compat_pid_t pid, + compat_uint_t __user *stat_addr, int options, + struct compat_rusage __user *ru); +asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32, + int, const char __user *); +asmlinkage long compat_sys_open_by_handle_at(int mountdirfd, + struct file_handle __user *handle, + int flags); +asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock, + struct compat_timex __user *tp); +asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, + unsigned vlen, unsigned int flags); asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid, const struct compat_iovec __user *lvec, compat_ulong_t liovcnt, const struct compat_iovec __user *rvec, @@ -826,14 +860,89 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid, const struct compat_iovec __user *lvec, compat_ulong_t liovcnt, const struct compat_iovec __user *rvec, compat_ulong_t riovcnt, compat_ulong_t flags); +asmlinkage long compat_sys_execveat(int dfd, const char __user *filename, + const compat_uptr_t __user *argv, + const compat_uptr_t __user *envp, int flags); +asmlinkage ssize_t compat_sys_preadv2(compat_ulong_t fd, + const struct compat_iovec __user *vec, + compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags); +asmlinkage ssize_t compat_sys_pwritev2(compat_ulong_t fd, + const struct compat_iovec __user *vec, + compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags); +#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64V2 +asmlinkage long compat_sys_readv64v2(unsigned long fd, + const struct compat_iovec __user *vec, + unsigned long vlen, loff_t pos, rwf_t flags); +#endif -asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, - compat_off_t __user *offset, compat_size_t count); -asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd, - compat_loff_t __user *offset, compat_size_t count); -asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr, - compat_stack_t __user *uoss_ptr); +#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64V2 +asmlinkage long compat_sys_pwritev64v2(unsigned long fd, + const struct compat_iovec __user *vec, + unsigned long vlen, loff_t pos, rwf_t flags); +#endif + + +/* + * Architecture-specific system calls + */ + +/* fs/quota/compat.c -- x86 only */ +asmlinkage long compat_sys_quotactl32(unsigned int cmd, + const char __user *special, qid_t id, void __user *addr); + +/* arch_prctl -- x86 */ +asmlinkage long compat_sys_arch_prctl(int option, unsigned long arg2); + + +/* + * Deprecated system calls which are still defined in + * include/uapi/asm-generic/unistd.h and wanted by >= 1 arch + */ + +/* __ARCH_WANT_SYSCALL_NO_AT */ +asmlinkage long compat_sys_open(const char __user *filename, int flags, + umode_t mode); +asmlinkage long compat_sys_utimes(const char __user *filename, + struct compat_timeval __user *t); + +/* __ARCH_WANT_SYSCALL_NO_FLAGS */ +asmlinkage long compat_sys_signalfd(int ufd, + const compat_sigset_t __user *sigmask, + compat_size_t sigsetsize); + +/* __ARCH_WANT_SYSCALL_OFF_T */ +asmlinkage long compat_sys_newstat(const char __user *filename, + struct compat_stat __user *statbuf); +asmlinkage long compat_sys_newlstat(const char __user *filename, + struct compat_stat __user *statbuf); + +/* __ARCH_WANT_SYSCALL_DEPRECATED */ +asmlinkage long compat_sys_time(compat_time_t __user *tloc); +asmlinkage long compat_sys_utime(const char __user *filename, + struct compat_utimbuf __user *t); +asmlinkage long compat_sys_futimesat(unsigned int dfd, + const char __user *filename, + struct compat_timeval __user *t); +asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, + compat_ulong_t __user *outp, compat_ulong_t __user *exp, + struct compat_timeval __user *tvp); +asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32); +asmlinkage long compat_sys_recv(int fd, void __user *buf, compat_size_t len, + unsigned flags); +asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args); + +/* obsolete: fs/readdir.c */ +asmlinkage long compat_sys_old_readdir(unsigned int fd, + struct compat_old_linux_dirent __user *, + unsigned int count); + +/* obsolete: fs/select.c */ +asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg); + +/* obsolete: ipc */ +asmlinkage long compat_sys_ipc(u32, int, int, u32, compat_uptr_t, u32); +/* obsolete: kernel/signal.c */ #ifdef __ARCH_WANT_SYS_SIGPENDING asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set); #endif @@ -842,26 +951,18 @@ asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set); asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *nset, compat_old_sigset_t __user *oset); #endif +#ifdef CONFIG_COMPAT_OLD_SIGACTION +asmlinkage long compat_sys_sigaction(int sig, + const struct compat_old_sigaction __user *act, + struct compat_old_sigaction __user *oact); +#endif -int compat_restore_altstack(const compat_stack_t __user *uss); -int __compat_save_altstack(compat_stack_t __user *, unsigned long); -#define compat_save_altstack_ex(uss, sp) do { \ - compat_stack_t __user *__uss = uss; \ - struct task_struct *t = current; \ - put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &__uss->ss_sp); \ - put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \ - put_user_ex(t->sas_ss_size, &__uss->ss_size); \ - if (t->sas_ss_flags & SS_AUTODISARM) \ - sas_ss_reset(t); \ -} while (0); - -asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, - struct compat_timespec __user *interval); +/* obsolete: kernel/time/time.c */ +asmlinkage long compat_sys_stime(compat_time_t __user *tptr); -asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32, - int, const char __user *); +/* obsolete: net/socket.c */ +asmlinkage long compat_sys_socketcall(int call, u32 __user *args); -asmlinkage long compat_sys_arch_prctl(int option, unsigned long arg2); /* * For most but not all architectures, "am I in a compat syscall?" and -- cgit v1.2.3-71-gd317 From 3e2052e5dd4062ccc7a10e8860aa7d2e58627001 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 22 Mar 2018 14:09:17 +0100 Subject: syscalls/x86: auto-create compat_sys_*() prototypes compat_sys_*() functions are no longer called from within the kernel on x86 except from the system call table. Linking the system call does not require compat_sys_*() function prototypes at least on x86. Therefore, generate compat_sys_*() prototypes on-the-fly within the COMPAT_SYSCALL_DEFINEx() macro, and remove x86-specific prototypes from various header files. Suggested-by: Andy Lutomirski Cc: Arnd Bergmann Cc: David S. Miller Cc: netdev@vger.kernel.org Cc: Thomas Gleixner Cc: Andi Kleen Cc: Ingo Molnar Cc: Andrew Morton Cc: Al Viro Cc: x86@kernel.org Signed-off-by: Dominik Brodowski --- arch/x86/ia32/ia32_signal.c | 1 - arch/x86/ia32/sys_ia32.c | 2 +- arch/x86/include/asm/sys_ia32.h | 64 ----------------------------------------- include/linux/compat.h | 17 ++--------- 4 files changed, 4 insertions(+), 80 deletions(-) delete mode 100644 arch/x86/include/asm/sys_ia32.h (limited to 'include/linux') diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index 41c671854642..86b1341cba9a 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -33,7 +33,6 @@ #include #include #include -#include #include /* diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index bd8a7020b9a7..11ef7b7c9cc8 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -47,7 +47,7 @@ #include #include #include -#include +#include #define AA(__x) ((unsigned long)(__x)) diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h deleted file mode 100644 index 2ee6e3b96656..000000000000 --- a/arch/x86/include/asm/sys_ia32.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * sys_ia32.h - Linux ia32 syscall interfaces - * - * Copyright (c) 2008 Jaswinder Singh Rajput - * - * This file is released under the GPLv2. - * See the file COPYING for more details. - */ - -#ifndef _ASM_X86_SYS_IA32_H -#define _ASM_X86_SYS_IA32_H - -#ifdef CONFIG_COMPAT - -#include -#include -#include -#include -#include -#include - -/* ia32/sys_ia32.c */ -asmlinkage long compat_sys_x86_truncate64(const char __user *, unsigned long, - unsigned long); -asmlinkage long compat_sys_x86_ftruncate64(unsigned int, unsigned long, - unsigned long); - -asmlinkage long compat_sys_x86_stat64(const char __user *, - struct stat64 __user *); -asmlinkage long compat_sys_x86_lstat64(const char __user *, - struct stat64 __user *); -asmlinkage long compat_sys_x86_fstat64(unsigned int, struct stat64 __user *); -asmlinkage long compat_sys_x86_fstatat(unsigned int, const char __user *, - struct stat64 __user *, int); -struct mmap_arg_struct32; -asmlinkage long compat_sys_x86_mmap(struct mmap_arg_struct32 __user *); - -asmlinkage long compat_sys_x86_pread(unsigned int, char __user *, u32, u32, - u32); -asmlinkage long compat_sys_x86_pwrite(unsigned int, const char __user *, u32, - u32, u32); - -asmlinkage long compat_sys_x86_fadvise64_64(int, __u32, __u32, __u32, __u32, - int); - -asmlinkage ssize_t compat_sys_x86_readahead(int, unsigned int, unsigned int, - size_t); -asmlinkage long compat_sys_x86_sync_file_range(int, unsigned int, unsigned int, - unsigned int, unsigned int, - int); -asmlinkage long compat_sys_x86_fadvise64(int, unsigned int, unsigned int, - size_t, int); -asmlinkage long compat_sys_x86_fallocate(int, int, unsigned int, unsigned int, - unsigned int, unsigned int); -asmlinkage long compat_sys_x86_clone(unsigned long, unsigned long, int __user *, - unsigned long, int __user *); - -/* ia32/ia32_signal.c */ -asmlinkage long sys32_sigreturn(void); -asmlinkage long sys32_rt_sigreturn(void); - -#endif /* CONFIG_COMPAT */ - -#endif /* _ASM_X86_SYS_IA32_H */ diff --git a/include/linux/compat.h b/include/linux/compat.h index f881cce627f6..8cb8710db0ab 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -49,6 +49,7 @@ COMPAT_SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \ + asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\ __attribute__((alias(__stringify(compat_SyS##name)))); \ static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ @@ -507,8 +508,8 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long); /* * These syscall function prototypes are kept in the same order as - * include/uapi/asm-generic/unistd.h. Architecture specific entries go below, - * followed by deprecated or obsolete system calls. + * include/uapi/asm-generic/unistd.h. Deprecated or obsolete system calls + * go below. * * Please note that these prototypes here are only provided for information * purposes, for static analysis, and for linking from the syscall table. @@ -882,18 +883,6 @@ asmlinkage long compat_sys_pwritev64v2(unsigned long fd, #endif -/* - * Architecture-specific system calls - */ - -/* fs/quota/compat.c -- x86 only */ -asmlinkage long compat_sys_quotactl32(unsigned int cmd, - const char __user *special, qid_t id, void __user *addr); - -/* arch_prctl -- x86 */ -asmlinkage long compat_sys_arch_prctl(int option, unsigned long arg2); - - /* * Deprecated system calls which are still defined in * include/uapi/asm-generic/unistd.h and wanted by >= 1 arch -- cgit v1.2.3-71-gd317 From c9a211951c7c79cfb5de888d7d9550872868b086 Mon Sep 17 00:00:00 2001 From: Howard McLauchlan Date: Wed, 21 Mar 2018 18:59:08 -0700 Subject: bpf: whitelist all syscalls for error injection Error injection is a useful mechanism to fail arbitrary kernel functions. However, it is often hard to guarantee an error propagates appropriately to user space programs. By injecting into syscalls, we can return arbitrary values to user space directly; this increases flexibility and robustness in testing, allowing us to test user space error paths effectively. The following script, for example, fails calls to sys_open() from a given pid: from bcc import BPF from sys import argv pid = argv[1] prog = r""" int kprobe__SyS_open(struct pt_regs *ctx, const char *pathname, int flags) { u32 pid = bpf_get_current_pid_tgid(); if (pid == %s) bpf_override_return(ctx, -ENOMEM); return 0; } """ % pid b = BPF(text=prog) while 1: b.perf_buffer_poll() This patch whitelists all syscalls defined with SYSCALL_DEFINE and COMPAT_SYSCALL_DEFINE for error injection. These changes are not intended to be considered stable, and would normally be configured off. Signed-off-by: Howard McLauchlan Signed-off-by: Dominik Brodowski --- include/linux/compat.h | 3 +++ include/linux/syscalls.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/compat.h b/include/linux/compat.h index 8cb8710db0ab..9847c5a013c3 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -33,6 +33,8 @@ #endif #define COMPAT_SYSCALL_DEFINE0(name) \ + asmlinkage long compat_sys_##name(void); \ + ALLOW_ERROR_INJECTION(compat_sys_##name, ERRNO); \ asmlinkage long compat_sys_##name(void) #define COMPAT_SYSCALL_DEFINE1(name, ...) \ @@ -52,6 +54,7 @@ asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\ __attribute__((alias(__stringify(compat_SyS##name)))); \ + ALLOW_ERROR_INJECTION(compat_sys##name, ERRNO); \ static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__));\ asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__))\ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 1f223b7cf16d..b961184f597a 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -191,6 +191,8 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event) #define SYSCALL_DEFINE0(sname) \ SYSCALL_METADATA(_##sname, 0); \ + asmlinkage long sys_##sname(void); \ + ALLOW_ERROR_INJECTION(sys_##sname, ERRNO); \ asmlinkage long sys_##sname(void) #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) @@ -210,6 +212,7 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event) #define __SYSCALL_DEFINEx(x, name, ...) \ asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ __attribute__((alias(__stringify(SyS##name)))); \ + ALLOW_ERROR_INJECTION(sys##name, ERRNO); \ static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ -- cgit v1.2.3-71-gd317