diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2018-03-20 16:25:57 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2018-04-02 14:15:27 -0400 |
commit | 078faac9e8b6c8124bc012bbf97cca59caf6d4ea (patch) | |
tree | 565af5f9110fd70f649f41af3b296077fd3aa646 | |
parent | e340db56483b6e10bd5e5f281071876808801a41 (diff) |
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 <viro@zeniv.linux.org.uk>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r-- | ipc/msg.c | 19 | ||||
-rw-r--r-- | ipc/syscall.c | 8 | ||||
-rw-r--r-- | ipc/util.h | 4 |
3 files changed, 24 insertions, 7 deletions
@@ -1150,10 +1150,16 @@ out_unlock1: | |||
1150 | return bufsz; | 1150 | return bufsz; |
1151 | } | 1151 | } |
1152 | 1152 | ||
1153 | long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, | ||
1154 | long msgtyp, int msgflg) | ||
1155 | { | ||
1156 | return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill); | ||
1157 | } | ||
1158 | |||
1153 | SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, | 1159 | SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, |
1154 | long, msgtyp, int, msgflg) | 1160 | long, msgtyp, int, msgflg) |
1155 | { | 1161 | { |
1156 | return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill); | 1162 | return ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg); |
1157 | } | 1163 | } |
1158 | 1164 | ||
1159 | #ifdef CONFIG_COMPAT | 1165 | #ifdef CONFIG_COMPAT |
@@ -1171,12 +1177,19 @@ static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bu | |||
1171 | return msgsz; | 1177 | return msgsz; |
1172 | } | 1178 | } |
1173 | 1179 | ||
1174 | COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp, | 1180 | long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz, |
1175 | compat_ssize_t, msgsz, compat_long_t, msgtyp, int, msgflg) | 1181 | compat_long_t msgtyp, int msgflg) |
1176 | { | 1182 | { |
1177 | return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp, | 1183 | return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp, |
1178 | msgflg, compat_do_msg_fill); | 1184 | msgflg, compat_do_msg_fill); |
1179 | } | 1185 | } |
1186 | |||
1187 | COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp, | ||
1188 | compat_ssize_t, msgsz, compat_long_t, msgtyp, | ||
1189 | int, msgflg) | ||
1190 | { | ||
1191 | return compat_ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg); | ||
1192 | } | ||
1180 | #endif | 1193 | #endif |
1181 | 1194 | ||
1182 | int msg_init_ns(struct ipc_namespace *ns) | 1195 | 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, | |||
59 | (struct ipc_kludge __user *) ptr, | 59 | (struct ipc_kludge __user *) ptr, |
60 | sizeof(tmp))) | 60 | sizeof(tmp))) |
61 | return -EFAULT; | 61 | return -EFAULT; |
62 | return sys_msgrcv(first, tmp.msgp, second, | 62 | return ksys_msgrcv(first, tmp.msgp, second, |
63 | tmp.msgtyp, third); | 63 | tmp.msgtyp, third); |
64 | } | 64 | } |
65 | default: | 65 | default: |
66 | return sys_msgrcv(first, | 66 | return ksys_msgrcv(first, |
67 | (struct msgbuf __user *) ptr, | 67 | (struct msgbuf __user *) ptr, |
68 | second, fifth, third); | 68 | second, fifth, third); |
69 | } | 69 | } |
@@ -156,10 +156,10 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, | |||
156 | return -EINVAL; | 156 | return -EINVAL; |
157 | if (copy_from_user(&ipck, uptr, sizeof(ipck))) | 157 | if (copy_from_user(&ipck, uptr, sizeof(ipck))) |
158 | return -EFAULT; | 158 | return -EFAULT; |
159 | return compat_sys_msgrcv(first, ipck.msgp, second, | 159 | return compat_ksys_msgrcv(first, ipck.msgp, second, |
160 | ipck.msgtyp, third); | 160 | ipck.msgtyp, third); |
161 | } | 161 | } |
162 | return compat_sys_msgrcv(first, ptr, second, fifth, third); | 162 | return compat_ksys_msgrcv(first, ptr, second, fifth, third); |
163 | } | 163 | } |
164 | case MSGGET: | 164 | case MSGGET: |
165 | return ksys_msgget(first, second); | 165 | 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); | |||
244 | long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg); | 244 | long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg); |
245 | long ksys_msgget(key_t key, int msgflg); | 245 | long ksys_msgget(key_t key, int msgflg); |
246 | long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf); | 246 | long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf); |
247 | long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, | ||
248 | long msgtyp, int msgflg); | ||
247 | long ksys_shmget(key_t key, size_t size, int shmflg); | 249 | long ksys_shmget(key_t key, size_t size, int shmflg); |
248 | long ksys_shmdt(char __user *shmaddr); | 250 | long ksys_shmdt(char __user *shmaddr); |
249 | long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); | 251 | 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, | |||
255 | const struct compat_timespec __user *timeout); | 257 | const struct compat_timespec __user *timeout); |
256 | long compat_ksys_semctl(int semid, int semnum, int cmd, int arg); | 258 | long compat_ksys_semctl(int semid, int semnum, int cmd, int arg); |
257 | long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr); | 259 | long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr); |
260 | long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz, | ||
261 | compat_long_t msgtyp, int msgflg); | ||
258 | long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr); | 262 | long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr); |
259 | #endif /* CONFIG_COMPAT */ | 263 | #endif /* CONFIG_COMPAT */ |
260 | 264 | ||