aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/compat.c')
-rw-r--r--ipc/compat.c70
1 files changed, 64 insertions, 6 deletions
diff --git a/ipc/compat.c b/ipc/compat.c
index 845a28738d3a..a6df704f521e 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -27,6 +27,7 @@
27#include <linux/msg.h> 27#include <linux/msg.h>
28#include <linux/shm.h> 28#include <linux/shm.h>
29#include <linux/syscalls.h> 29#include <linux/syscalls.h>
30#include <linux/ptrace.h>
30 31
31#include <linux/mutex.h> 32#include <linux/mutex.h>
32#include <asm/uaccess.h> 33#include <asm/uaccess.h>
@@ -117,6 +118,7 @@ extern int sem_ctls[];
117 118
118static inline int compat_ipc_parse_version(int *cmd) 119static inline int compat_ipc_parse_version(int *cmd)
119{ 120{
121#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
120 int version = *cmd & IPC_64; 122 int version = *cmd & IPC_64;
121 123
122 /* this is tricky: architectures that have support for the old 124 /* this is tricky: architectures that have support for the old
@@ -128,6 +130,10 @@ static inline int compat_ipc_parse_version(int *cmd)
128 *cmd &= ~IPC_64; 130 *cmd &= ~IPC_64;
129#endif 131#endif
130 return version; 132 return version;
133#else
134 /* With the asm-generic APIs, we always use the 64-bit versions. */
135 return IPC_64;
136#endif
131} 137}
132 138
133static inline int __get_compat_ipc64_perm(struct ipc64_perm *p64, 139static inline int __get_compat_ipc64_perm(struct ipc64_perm *p64,
@@ -232,10 +238,9 @@ static inline int put_compat_semid_ds(struct semid64_ds *s,
232 return err; 238 return err;
233} 239}
234 240
235long compat_sys_semctl(int first, int second, int third, void __user *uptr) 241static long do_compat_semctl(int first, int second, int third, u32 pad)
236{ 242{
237 union semun fourth; 243 union semun fourth;
238 u32 pad;
239 int err, err2; 244 int err, err2;
240 struct semid64_ds s64; 245 struct semid64_ds s64;
241 struct semid64_ds __user *up64; 246 struct semid64_ds __user *up64;
@@ -243,10 +248,6 @@ long compat_sys_semctl(int first, int second, int third, void __user *uptr)
243 248
244 memset(&s64, 0, sizeof(s64)); 249 memset(&s64, 0, sizeof(s64));
245 250
246 if (!uptr)
247 return -EINVAL;
248 if (get_user(pad, (u32 __user *) uptr))
249 return -EFAULT;
250 if ((third & (~IPC_64)) == SETVAL) 251 if ((third & (~IPC_64)) == SETVAL)
251 fourth.val = (int) pad; 252 fourth.val = (int) pad;
252 else 253 else
@@ -305,6 +306,18 @@ long compat_sys_semctl(int first, int second, int third, void __user *uptr)
305 return err; 306 return err;
306} 307}
307 308
309#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
310long compat_sys_semctl(int first, int second, int third, void __user *uptr)
311{
312 u32 pad;
313
314 if (!uptr)
315 return -EINVAL;
316 if (get_user(pad, (u32 __user *) uptr))
317 return -EFAULT;
318 return do_compat_semctl(first, second, third, pad);
319}
320
308long compat_sys_msgsnd(int first, int second, int third, void __user *uptr) 321long compat_sys_msgsnd(int first, int second, int third, void __user *uptr)
309{ 322{
310 struct compat_msgbuf __user *up = uptr; 323 struct compat_msgbuf __user *up = uptr;
@@ -353,6 +366,37 @@ long compat_sys_msgrcv(int first, int second, int msgtyp, int third,
353out: 366out:
354 return err; 367 return err;
355} 368}
369#else
370long compat_sys_semctl(int semid, int semnum, int cmd, int arg)
371{
372 return do_compat_semctl(semid, semnum, cmd, arg);
373}
374
375long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp,
376 size_t msgsz, int msgflg)
377{
378 compat_long_t mtype;
379
380 if (get_user(mtype, &msgp->mtype))
381 return -EFAULT;
382 return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg);
383}
384
385long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp,
386 size_t msgsz, long msgtyp, int msgflg)
387{
388 long err, mtype;
389
390 err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg);
391 if (err < 0)
392 goto out;
393
394 if (put_user(mtype, &msgp->mtype))
395 err = -EFAULT;
396 out:
397 return err;
398}
399#endif
356 400
357static inline int get_compat_msqid64(struct msqid64_ds *m64, 401static inline int get_compat_msqid64(struct msqid64_ds *m64,
358 struct compat_msqid64_ds __user *up64) 402 struct compat_msqid64_ds __user *up64)
@@ -470,6 +514,7 @@ long compat_sys_msgctl(int first, int second, void __user *uptr)
470 return err; 514 return err;
471} 515}
472 516
517#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
473long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, 518long compat_sys_shmat(int first, int second, compat_uptr_t third, int version,
474 void __user *uptr) 519 void __user *uptr)
475{ 520{
@@ -485,6 +530,19 @@ long compat_sys_shmat(int first, int second, compat_uptr_t third, int version,
485 uaddr = compat_ptr(third); 530 uaddr = compat_ptr(third);
486 return put_user(raddr, uaddr); 531 return put_user(raddr, uaddr);
487} 532}
533#else
534long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg)
535{
536 unsigned long ret;
537 long err;
538
539 err = do_shmat(shmid, compat_ptr(shmaddr), shmflg, &ret);
540 if (err)
541 return err;
542 force_successful_syscall_return();
543 return (long)ret;
544}
545#endif
488 546
489static inline int get_compat_shmid64_ds(struct shmid64_ds *s64, 547static inline int get_compat_shmid64_ds(struct shmid64_ds *s64,
490 struct compat_shmid64_ds __user *up64) 548 struct compat_shmid64_ds __user *up64)