From 41f4f0e2f5f4cd060885405c04214851ffe7b299 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 20 Mar 2018 19:48:14 +0100 Subject: ipc: add semtimedop syscall/compat_syscall wrappers Provide ksys_semtimedop() and compat_ksys_semtimedop() wrappers to avoid in-kernel calls to these 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_semtimedop() and compat_sys_semtimedop(). 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 --- ipc/sem.c | 23 ++++++++++++++++++----- ipc/syscall.c | 17 ++++++++++------- ipc/util.h | 13 +++++++++++++ 3 files changed, 41 insertions(+), 12 deletions(-) (limited to 'ipc') diff --git a/ipc/sem.c b/ipc/sem.c index a4af04979fd2..e21ceb8b4af1 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -2120,8 +2120,8 @@ out_free: return error; } -SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, - unsigned, nsops, const struct timespec __user *, timeout) +long ksys_semtimedop(int semid, struct sembuf __user *tsops, + unsigned int nsops, const struct timespec __user *timeout) { if (timeout) { struct timespec64 ts; @@ -2132,10 +2132,16 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, return do_semtimedop(semid, tsops, nsops, NULL); } +SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, + unsigned int, nsops, const struct timespec __user *, timeout) +{ + return ksys_semtimedop(semid, tsops, nsops, timeout); +} + #ifdef CONFIG_COMPAT -COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems, - unsigned, nsops, - const struct compat_timespec __user *, timeout) +long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems, + unsigned int nsops, + const struct compat_timespec __user *timeout) { if (timeout) { struct timespec64 ts; @@ -2145,6 +2151,13 @@ COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems, } return do_semtimedop(semid, tsems, nsops, NULL); } + +COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems, + unsigned int, nsops, + const struct compat_timespec __user *, timeout) +{ + return compat_ksys_semtimedop(semid, tsems, nsops, timeout); +} #endif SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops, diff --git a/ipc/syscall.c b/ipc/syscall.c index 3763b4293b74..84d6a7691baa 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -7,6 +7,9 @@ */ #include #include +#include +#include +#include "util.h" #ifdef __ARCH_WANT_SYS_IPC #include @@ -24,12 +27,12 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, switch (call) { case SEMOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, - second, NULL); + return ksys_semtimedop(first, (struct sembuf __user *)ptr, + second, NULL); case SEMTIMEDOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, - second, - (const struct timespec __user *)fifth); + return ksys_semtimedop(first, (struct sembuf __user *)ptr, + second, + (const struct timespec __user *)fifth); case SEMGET: return sys_semget(first, second, third); @@ -124,9 +127,9 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, switch (call) { case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ - return sys_semtimedop(first, compat_ptr(ptr), second, NULL); + return ksys_semtimedop(first, compat_ptr(ptr), second, NULL); case SEMTIMEDOP: - return compat_sys_semtimedop(first, compat_ptr(ptr), second, + return compat_ksys_semtimedop(first, compat_ptr(ptr), second, compat_ptr(fifth)); case SEMGET: return sys_semget(first, second, third); diff --git a/ipc/util.h b/ipc/util.h index 89b8ec176fc4..6deadf77547e 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -235,4 +235,17 @@ static inline int compat_ipc_parse_version(int *cmd) #endif } #endif + +/* for __ARCH_WANT_SYS_IPC */ +long ksys_semtimedop(int semid, struct sembuf __user *tsops, + unsigned int nsops, + const struct timespec __user *timeout); + +/* for CONFIG_ARCH_WANT_OLD_COMPAT_IPC */ +#ifdef CONFIG_COMPAT +long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems, + unsigned int nsops, + const struct compat_timespec __user *timeout); +#endif /* CONFIG_COMPAT */ + #endif -- cgit v1.2.3-59-g8ed1b From 69894718a515fef7ff633cf354fcd7ed73a88891 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 20 Mar 2018 19:53:58 +0100 Subject: ipc: add semget syscall wrapper Provide ksys_semget() wrapper to avoid in-kernel calls to this 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_semget(). 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 --- ipc/sem.c | 7 ++++++- ipc/syscall.c | 4 ++-- ipc/util.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'ipc') diff --git a/ipc/sem.c b/ipc/sem.c index e21ceb8b4af1..2e5f7ec7a7db 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -556,7 +556,7 @@ static inline int sem_more_checks(struct kern_ipc_perm *ipcp, return 0; } -SYSCALL_DEFINE3(semget, key_t, key, int, nsems, int, semflg) +long ksys_semget(key_t key, int nsems, int semflg) { struct ipc_namespace *ns; static const struct ipc_ops sem_ops = { @@ -578,6 +578,11 @@ SYSCALL_DEFINE3(semget, key_t, key, int, nsems, int, semflg) return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params); } +SYSCALL_DEFINE3(semget, key_t, key, int, nsems, int, semflg) +{ + return ksys_semget(key, nsems, semflg); +} + /** * perform_atomic_semop[_slow] - Attempt to perform semaphore * operations on a given array. diff --git a/ipc/syscall.c b/ipc/syscall.c index 84d6a7691baa..21fcdf0b4836 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -35,7 +35,7 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, (const struct timespec __user *)fifth); case SEMGET: - return sys_semget(first, second, third); + return ksys_semget(first, second, third); case SEMCTL: { unsigned long arg; if (!ptr) @@ -132,7 +132,7 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, return compat_ksys_semtimedop(first, compat_ptr(ptr), second, compat_ptr(fifth)); case SEMGET: - return sys_semget(first, second, third); + return ksys_semget(first, second, third); case SEMCTL: if (!ptr) return -EINVAL; diff --git a/ipc/util.h b/ipc/util.h index 6deadf77547e..0f07056e5a73 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -240,6 +240,7 @@ static inline int compat_ipc_parse_version(int *cmd) long ksys_semtimedop(int semid, struct sembuf __user *tsops, unsigned int nsops, const struct timespec __user *timeout); +long ksys_semget(key_t key, int nsems, int semflg); /* for CONFIG_ARCH_WANT_OLD_COMPAT_IPC */ #ifdef CONFIG_COMPAT -- cgit v1.2.3-59-g8ed1b From d969c6fa7263c8fc1928f528bb68587872350b6c Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 20 Mar 2018 20:00:39 +0100 Subject: ipc: add semctl syscall/compat_syscall wrappers Provide ksys_semctl() and compat_ksys_semctl() wrappers to avoid in-kernel calls to these 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_semctl() and compat_sys_semctl(). 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 --- ipc/sem.c | 14 ++++++++++++-- ipc/syscall.c | 4 ++-- ipc/util.h | 2 ++ 3 files changed, 16 insertions(+), 4 deletions(-) (limited to 'ipc') diff --git a/ipc/sem.c b/ipc/sem.c index 2e5f7ec7a7db..1cf56279a84c 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -1581,7 +1581,7 @@ out_up: return err; } -SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg) +long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg) { int version; struct ipc_namespace *ns; @@ -1635,6 +1635,11 @@ SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg) } } +SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg) +{ + return ksys_semctl(semid, semnum, cmd, arg); +} + #ifdef CONFIG_COMPAT struct compat_semid_ds { @@ -1683,7 +1688,7 @@ static int copy_compat_semid_to_user(void __user *buf, struct semid64_ds *in, } } -COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg) +long compat_ksys_semctl(int semid, int semnum, int cmd, int arg) { void __user *p = compat_ptr(arg); struct ipc_namespace *ns; @@ -1727,6 +1732,11 @@ COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg) return -EINVAL; } } + +COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg) +{ + return compat_ksys_semctl(semid, semnum, cmd, arg); +} #endif /* If the task doesn't already have a undo_list, then allocate one diff --git a/ipc/syscall.c b/ipc/syscall.c index 21fcdf0b4836..a536cca37661 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -42,7 +42,7 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, return -EINVAL; if (get_user(arg, (unsigned long __user *) ptr)) return -EFAULT; - return sys_semctl(first, second, third, arg); + return ksys_semctl(first, second, third, arg); } case MSGSND: @@ -138,7 +138,7 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, return -EINVAL; if (get_user(pad, (u32 __user *) compat_ptr(ptr))) return -EFAULT; - return compat_sys_semctl(first, second, third, pad); + return compat_ksys_semctl(first, second, third, pad); case MSGSND: return compat_sys_msgsnd(first, ptr, second, third); diff --git a/ipc/util.h b/ipc/util.h index 0f07056e5a73..1f1109b83437 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -241,12 +241,14 @@ long ksys_semtimedop(int semid, struct sembuf __user *tsops, unsigned int nsops, const struct timespec __user *timeout); long ksys_semget(key_t key, int nsems, int semflg); +long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg); /* for CONFIG_ARCH_WANT_OLD_COMPAT_IPC */ #ifdef CONFIG_COMPAT long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems, unsigned int nsops, const struct compat_timespec __user *timeout); +long compat_ksys_semctl(int semid, int semnum, int cmd, int arg); #endif /* CONFIG_COMPAT */ #endif -- cgit v1.2.3-59-g8ed1b From 3d65661a494a11266500c2532b4f163537c379db Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 20 Mar 2018 20:06:04 +0100 Subject: ipc: add msgget syscall wrapper Provide ksys_msgget() wrapper to avoid in-kernel calls to this 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_msgget(). 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 --- ipc/msg.c | 7 ++++++- ipc/syscall.c | 4 ++-- ipc/util.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'ipc') diff --git a/ipc/msg.c b/ipc/msg.c index 0dcc6699dc53..64e8276be164 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -263,7 +263,7 @@ static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg) return security_msg_queue_associate(msq, msgflg); } -SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg) +long ksys_msgget(key_t key, int msgflg) { struct ipc_namespace *ns; static const struct ipc_ops msg_ops = { @@ -280,6 +280,11 @@ SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg) return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params); } +SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg) +{ + return ksys_msgget(key, msgflg); +} + static inline unsigned long copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version) { diff --git a/ipc/syscall.c b/ipc/syscall.c index a536cca37661..355c4a644bbf 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -68,7 +68,7 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, second, fifth, third); } case MSGGET: - return sys_msgget((key_t) first, second); + return ksys_msgget((key_t) first, second); case MSGCTL: return sys_msgctl(first, second, (struct msqid_ds __user *)ptr); @@ -161,7 +161,7 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, return compat_sys_msgrcv(first, ptr, second, fifth, third); } case MSGGET: - return sys_msgget(first, second); + return ksys_msgget(first, second); case MSGCTL: return compat_sys_msgctl(first, second, compat_ptr(ptr)); diff --git a/ipc/util.h b/ipc/util.h index 1f1109b83437..b35c0dfe3bc3 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -242,6 +242,7 @@ long ksys_semtimedop(int semid, struct sembuf __user *tsops, const struct timespec __user *timeout); long ksys_semget(key_t key, int nsems, int semflg); long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg); +long ksys_msgget(key_t key, int msgflg); /* for CONFIG_ARCH_WANT_OLD_COMPAT_IPC */ #ifdef CONFIG_COMPAT -- cgit v1.2.3-59-g8ed1b From 65749e0bb5e7de876ee43d3f601e32afe17e9248 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 20 Mar 2018 20:07:53 +0100 Subject: ipc: add shmget syscall wrapper Provide ksys_shmget() wrapper to avoid in-kernel calls to this 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_shmget(). 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 --- ipc/shm.c | 7 ++++++- ipc/syscall.c | 4 ++-- ipc/util.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'ipc') diff --git a/ipc/shm.c b/ipc/shm.c index 4643865e9171..9f3cdb259a51 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -656,7 +656,7 @@ static inline int shm_more_checks(struct kern_ipc_perm *ipcp, return 0; } -SYSCALL_DEFINE3(shmget, key_t, key, size_t, size, int, shmflg) +long ksys_shmget(key_t key, size_t size, int shmflg) { struct ipc_namespace *ns; static const struct ipc_ops shm_ops = { @@ -675,6 +675,11 @@ SYSCALL_DEFINE3(shmget, key_t, key, size_t, size, int, shmflg) return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params); } +SYSCALL_DEFINE3(shmget, key_t, key, size_t, size, int, shmflg) +{ + return ksys_shmget(key, size, shmflg); +} + static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version) { switch (version) { diff --git a/ipc/syscall.c b/ipc/syscall.c index 355c4a644bbf..60bceb19b6f0 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -92,7 +92,7 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, case SHMDT: return sys_shmdt((char __user *)ptr); case SHMGET: - return sys_shmget(first, second, third); + return ksys_shmget(first, second, third); case SHMCTL: return sys_shmctl(first, second, (struct shmid_ds __user *) ptr); @@ -180,7 +180,7 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, case SHMDT: return sys_shmdt(compat_ptr(ptr)); case SHMGET: - return sys_shmget(first, (unsigned)second, third); + return ksys_shmget(first, (unsigned int)second, third); case SHMCTL: return compat_sys_shmctl(first, second, compat_ptr(ptr)); } diff --git a/ipc/util.h b/ipc/util.h index b35c0dfe3bc3..51002c0b2a21 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -243,6 +243,7 @@ long ksys_semtimedop(int semid, struct sembuf __user *tsops, long ksys_semget(key_t key, int nsems, int semflg); long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg); long ksys_msgget(key_t key, int msgflg); +long ksys_shmget(key_t key, size_t size, int shmflg); /* for CONFIG_ARCH_WANT_OLD_COMPAT_IPC */ #ifdef CONFIG_COMPAT -- cgit v1.2.3-59-g8ed1b From da1e2744341542e404c172bcf6a321f509408b14 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 20 Mar 2018 20:09:48 +0100 Subject: ipc: add shmdt syscall wrapper Provide ksys_shmdt() wrapper to avoid in-kernel calls to this 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_shmdt(). 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 --- ipc/shm.c | 7 ++++++- ipc/syscall.c | 4 ++-- ipc/util.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'ipc') diff --git a/ipc/shm.c b/ipc/shm.c index 9f3cdb259a51..e5838e3328dc 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -1481,7 +1481,7 @@ COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg) * detach and kill segment if marked destroyed. * The work is done in shm_close. */ -SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) +long ksys_shmdt(char __user *shmaddr) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; @@ -1588,6 +1588,11 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) return retval; } +SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) +{ + return ksys_shmdt(shmaddr); +} + #ifdef CONFIG_PROC_FS static int sysvipc_shm_proc_show(struct seq_file *s, void *it) { diff --git a/ipc/syscall.c b/ipc/syscall.c index 60bceb19b6f0..b3aa71564815 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -90,7 +90,7 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, return -EINVAL; } case SHMDT: - return sys_shmdt((char __user *)ptr); + return ksys_shmdt((char __user *)ptr); case SHMGET: return ksys_shmget(first, second, third); case SHMCTL: @@ -178,7 +178,7 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, return put_user(raddr, (compat_ulong_t __user *)compat_ptr(third)); } case SHMDT: - return sys_shmdt(compat_ptr(ptr)); + return ksys_shmdt(compat_ptr(ptr)); case SHMGET: return ksys_shmget(first, (unsigned int)second, third); case SHMCTL: diff --git a/ipc/util.h b/ipc/util.h index 51002c0b2a21..7770bcad1168 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -244,6 +244,7 @@ long ksys_semget(key_t key, int nsems, int semflg); long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg); long ksys_msgget(key_t key, int msgflg); long ksys_shmget(key_t key, size_t size, int shmflg); +long ksys_shmdt(char __user *shmaddr); /* for CONFIG_ARCH_WANT_OLD_COMPAT_IPC */ #ifdef CONFIG_COMPAT -- cgit v1.2.3-59-g8ed1b From c84d0791dfa7fe8f051082c09a558eb3e2d01931 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 20 Mar 2018 20:12:33 +0100 Subject: ipc: add shmctl syscall/compat_syscall wrappers Provide ksys_shmctl() and compat_ksys_shmctl() wrappers to avoid in-kernel calls to these 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_shmctl() and compat_sys_shmctl(). 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 --- ipc/shm.c | 14 ++++++++++++-- ipc/syscall.c | 4 ++-- ipc/util.h | 2 ++ 3 files changed, 16 insertions(+), 4 deletions(-) (limited to 'ipc') diff --git a/ipc/shm.c b/ipc/shm.c index e5838e3328dc..0aae3e55bc56 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -1045,7 +1045,7 @@ out_unlock1: return err; } -SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) +long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) { int err, version; struct ipc_namespace *ns; @@ -1099,6 +1099,11 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) } } +SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) +{ + return ksys_shmctl(shmid, cmd, buf); +} + #ifdef CONFIG_COMPAT struct compat_shmid_ds { @@ -1218,7 +1223,7 @@ static int copy_compat_shmid_from_user(struct shmid64_ds *out, void __user *buf, } } -COMPAT_SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, void __user *, uptr) +long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr) { struct ipc_namespace *ns; struct shmid64_ds sem64; @@ -1273,6 +1278,11 @@ COMPAT_SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, void __user *, uptr) } return err; } + +COMPAT_SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, void __user *, uptr) +{ + return compat_ksys_shmctl(shmid, cmd, uptr); +} #endif /* diff --git a/ipc/syscall.c b/ipc/syscall.c index b3aa71564815..34bbabc9e672 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -94,7 +94,7 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, case SHMGET: return ksys_shmget(first, second, third); case SHMCTL: - return sys_shmctl(first, second, + return ksys_shmctl(first, second, (struct shmid_ds __user *) ptr); default: return -ENOSYS; @@ -182,7 +182,7 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, case SHMGET: return ksys_shmget(first, (unsigned int)second, third); case SHMCTL: - return compat_sys_shmctl(first, second, compat_ptr(ptr)); + return compat_ksys_shmctl(first, second, compat_ptr(ptr)); } return -ENOSYS; diff --git a/ipc/util.h b/ipc/util.h index 7770bcad1168..16e8b5b8c416 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -245,6 +245,7 @@ long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg); long ksys_msgget(key_t key, int msgflg); long ksys_shmget(key_t key, size_t size, int shmflg); long ksys_shmdt(char __user *shmaddr); +long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); /* for CONFIG_ARCH_WANT_OLD_COMPAT_IPC */ #ifdef CONFIG_COMPAT @@ -252,6 +253,7 @@ long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems, unsigned int nsops, const struct compat_timespec __user *timeout); long compat_ksys_semctl(int semid, int semnum, int cmd, int arg); +long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr); #endif /* CONFIG_COMPAT */ #endif -- cgit v1.2.3-59-g8ed1b From e340db56483b6e10bd5e5f281071876808801a41 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 20 Mar 2018 20:15:28 +0100 Subject: ipc: add msgctl syscall/compat_syscall wrappers Provide ksys_msgctl() and compat_ksys_msgctl() wrappers to avoid in-kernel calls to these 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_msgctl() and compat_sys_msgctl(). 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 --- ipc/msg.c | 14 ++++++++++++-- ipc/syscall.c | 5 +++-- ipc/util.h | 2 ++ 3 files changed, 17 insertions(+), 4 deletions(-) (limited to 'ipc') diff --git a/ipc/msg.c b/ipc/msg.c index 64e8276be164..5b026868df07 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -538,7 +538,7 @@ out_unlock: return err; } -SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) +long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) { int version; struct ipc_namespace *ns; @@ -581,6 +581,11 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) } } +SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) +{ + return ksys_msgctl(msqid, cmd, buf); +} + #ifdef CONFIG_COMPAT struct compat_msqid_ds { @@ -651,7 +656,7 @@ static int copy_compat_msqid_to_user(void __user *buf, struct msqid64_ds *in, } } -COMPAT_SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, void __user *, uptr) +long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr) { struct ipc_namespace *ns; int err; @@ -692,6 +697,11 @@ COMPAT_SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, void __user *, uptr) return -EINVAL; } } + +COMPAT_SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, void __user *, uptr) +{ + return compat_ksys_msgctl(msqid, cmd, uptr); +} #endif static int testmsg(struct msg_msg *msg, long type, int mode) diff --git a/ipc/syscall.c b/ipc/syscall.c index 34bbabc9e672..aa29b0802e26 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -70,7 +70,8 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, case MSGGET: return ksys_msgget((key_t) first, second); case MSGCTL: - return sys_msgctl(first, second, (struct msqid_ds __user *)ptr); + return ksys_msgctl(first, second, + (struct msqid_ds __user *)ptr); case SHMAT: switch (version) { @@ -163,7 +164,7 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, case MSGGET: return ksys_msgget(first, second); case MSGCTL: - return compat_sys_msgctl(first, second, compat_ptr(ptr)); + return compat_ksys_msgctl(first, second, compat_ptr(ptr)); case SHMAT: { int err; diff --git a/ipc/util.h b/ipc/util.h index 16e8b5b8c416..47837b4af3f2 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -243,6 +243,7 @@ long ksys_semtimedop(int semid, struct sembuf __user *tsops, long ksys_semget(key_t key, int nsems, int semflg); long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg); long ksys_msgget(key_t key, int msgflg); +long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf); long ksys_shmget(key_t key, size_t size, int shmflg); long ksys_shmdt(char __user *shmaddr); long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); @@ -253,6 +254,7 @@ long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems, unsigned int nsops, const struct compat_timespec __user *timeout); long compat_ksys_semctl(int semid, int semnum, int cmd, int arg); +long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr); long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr); #endif /* CONFIG_COMPAT */ -- cgit v1.2.3-59-g8ed1b From 078faac9e8b6c8124bc012bbf97cca59caf6d4ea Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 20 Mar 2018 21:25:57 +0100 Subject: ipc: add msgrcv syscall/compat_syscall wrappers Provide ksys_msgrcv() and compat_ksys_msgrcv() wrappers to avoid in-kernel calls to these 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_msgrcv() and compat_sys_msgrcv(). 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 --- ipc/msg.c | 19 ++++++++++++++++--- ipc/syscall.c | 8 ++++---- ipc/util.h | 4 ++++ 3 files changed, 24 insertions(+), 7 deletions(-) (limited to 'ipc') diff --git a/ipc/msg.c b/ipc/msg.c index 5b026868df07..abc5826270a6 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -1150,10 +1150,16 @@ out_unlock1: return bufsz; } +long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, + long msgtyp, int msgflg) +{ + return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill); +} + SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, long, msgtyp, int, msgflg) { - return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill); + return ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg); } #ifdef CONFIG_COMPAT @@ -1171,12 +1177,19 @@ static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bu return msgsz; } -COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp, - compat_ssize_t, msgsz, compat_long_t, msgtyp, int, msgflg) +long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz, + compat_long_t msgtyp, int msgflg) { return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp, msgflg, compat_do_msg_fill); } + +COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp, + compat_ssize_t, msgsz, compat_long_t, msgtyp, + int, msgflg) +{ + return compat_ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg); +} #endif int msg_init_ns(struct ipc_namespace *ns) diff --git a/ipc/syscall.c b/ipc/syscall.c index aa29b0802e26..0228c7afd882 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -59,11 +59,11 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, (struct ipc_kludge __user *) ptr, sizeof(tmp))) return -EFAULT; - return sys_msgrcv(first, tmp.msgp, second, + return ksys_msgrcv(first, tmp.msgp, second, tmp.msgtyp, third); } default: - return sys_msgrcv(first, + return ksys_msgrcv(first, (struct msgbuf __user *) ptr, second, fifth, third); } @@ -156,10 +156,10 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, return -EINVAL; if (copy_from_user(&ipck, uptr, sizeof(ipck))) return -EFAULT; - return compat_sys_msgrcv(first, ipck.msgp, second, + return compat_ksys_msgrcv(first, ipck.msgp, second, ipck.msgtyp, third); } - return compat_sys_msgrcv(first, ptr, second, fifth, third); + return compat_ksys_msgrcv(first, ptr, second, fifth, third); } case MSGGET: return ksys_msgget(first, second); diff --git a/ipc/util.h b/ipc/util.h index 47837b4af3f2..c16aceb1bdec 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -244,6 +244,8 @@ long ksys_semget(key_t key, int nsems, int semflg); long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg); long ksys_msgget(key_t key, int msgflg); long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf); +long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, + long msgtyp, int msgflg); long ksys_shmget(key_t key, size_t size, int shmflg); long ksys_shmdt(char __user *shmaddr); long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); @@ -255,6 +257,8 @@ long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems, const struct compat_timespec __user *timeout); long compat_ksys_semctl(int semid, int semnum, int cmd, int arg); long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr); +long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz, + compat_long_t msgtyp, int msgflg); long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr); #endif /* CONFIG_COMPAT */ -- cgit v1.2.3-59-g8ed1b From 31c213f2106b7ea06f7fdc94ef8b785ed5342cf7 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 20 Mar 2018 21:29:00 +0100 Subject: ipc: add msgsnd syscall/compat_syscall wrappers Provide ksys_msgsnd() and compat_ksys_msgsnd() wrappers to avoid in-kernel calls to these 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_msgsnd() and compat_sys_msgsnd(). 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 --- ipc/msg.c | 20 ++++++++++++++++---- ipc/syscall.c | 4 ++-- ipc/util.h | 4 ++++ 3 files changed, 22 insertions(+), 6 deletions(-) (limited to 'ipc') diff --git a/ipc/msg.c b/ipc/msg.c index abc5826270a6..9de48065c1ac 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -867,8 +867,8 @@ out_unlock1: return err; } -SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, - int, msgflg) +long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, + int msgflg) { long mtype; @@ -877,6 +877,12 @@ SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); } +SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, + int, msgflg) +{ + return ksys_msgsnd(msqid, msgp, msgsz, msgflg); +} + #ifdef CONFIG_COMPAT struct compat_msgbuf { @@ -884,8 +890,8 @@ struct compat_msgbuf { char mtext[1]; }; -COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp, - compat_ssize_t, msgsz, int, msgflg) +long compat_ksys_msgsnd(int msqid, compat_uptr_t msgp, + compat_ssize_t msgsz, int msgflg) { struct compat_msgbuf __user *up = compat_ptr(msgp); compat_long_t mtype; @@ -894,6 +900,12 @@ COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp, return -EFAULT; return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg); } + +COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp, + compat_ssize_t, msgsz, int, msgflg) +{ + return compat_ksys_msgsnd(msqid, msgp, msgsz, msgflg); +} #endif static inline int convert_mode(long *msgtyp, int msgflg) diff --git a/ipc/syscall.c b/ipc/syscall.c index 0228c7afd882..77a883ef2eca 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -46,7 +46,7 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, } case MSGSND: - return sys_msgsnd(first, (struct msgbuf __user *) ptr, + return ksys_msgsnd(first, (struct msgbuf __user *) ptr, second, third); case MSGRCV: switch (version) { @@ -142,7 +142,7 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, return compat_ksys_semctl(first, second, third, pad); case MSGSND: - return compat_sys_msgsnd(first, ptr, second, third); + return compat_ksys_msgsnd(first, ptr, second, third); case MSGRCV: { void __user *uptr = compat_ptr(ptr); diff --git a/ipc/util.h b/ipc/util.h index c16aceb1bdec..51853dc2f340 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -246,6 +246,8 @@ long ksys_msgget(key_t key, int msgflg); long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf); long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, long msgtyp, int msgflg); +long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, + int msgflg); long ksys_shmget(key_t key, size_t size, int shmflg); long ksys_shmdt(char __user *shmaddr); long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); @@ -259,6 +261,8 @@ long compat_ksys_semctl(int semid, int semnum, int cmd, int arg); long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr); long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg); +long compat_ksys_msgsnd(int msqid, compat_uptr_t msgp, + compat_ssize_t msgsz, int msgflg); long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr); #endif /* CONFIG_COMPAT */ -- cgit v1.2.3-59-g8ed1b