compat.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * 32 bit compatibility code for System V IPC
  3. *
  4. * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  5. * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
  6. * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
  7. * Copyright (C) 2000 VA Linux Co
  8. * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
  9. * Copyright (C) 2000 Hewlett-Packard Co.
  10. * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
  11. * Copyright (C) 2000 Gerhard Tonn (ton@de.ibm.com)
  12. * Copyright (C) 2000-2002 Andi Kleen, SuSE Labs (x86-64 port)
  13. * Copyright (C) 2000 Silicon Graphics, Inc.
  14. * Copyright (C) 2001 IBM
  15. * Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation
  16. * Copyright (C) 2004 Arnd Bergmann (arnd@arndb.de)
  17. *
  18. * This code is collected from the versions for sparc64, mips64, s390x, ia64,
  19. * ppc64 and x86_64, all of which are based on the original sparc64 version
  20. * by Jakub Jelinek.
  21. *
  22. */
  23. #include <linux/compat.h>
  24. #include <linux/errno.h>
  25. #include <linux/highuid.h>
  26. #include <linux/init.h>
  27. #include <linux/msg.h>
  28. #include <linux/shm.h>
  29. #include <linux/syscalls.h>
  30. #include <linux/ptrace.h>
  31. #include <linux/mutex.h>
  32. #include <linux/uaccess.h>
  33. #include "util.h"
  34. struct compat_msgbuf {
  35. compat_long_t mtype;
  36. char mtext[1];
  37. };
  38. int get_compat_ipc64_perm(struct ipc64_perm *to,
  39. struct compat_ipc64_perm __user *from)
  40. {
  41. struct compat_ipc64_perm v;
  42. if (copy_from_user(&v, from, sizeof(v)))
  43. return -EFAULT;
  44. to->uid = v.uid;
  45. to->gid = v.gid;
  46. to->mode = v.mode;
  47. return 0;
  48. }
  49. int get_compat_ipc_perm(struct ipc64_perm *to,
  50. struct compat_ipc_perm __user *from)
  51. {
  52. struct compat_ipc_perm v;
  53. if (copy_from_user(&v, from, sizeof(v)))
  54. return -EFAULT;
  55. to->uid = v.uid;
  56. to->gid = v.gid;
  57. to->mode = v.mode;
  58. return 0;
  59. }
  60. void to_compat_ipc64_perm(struct compat_ipc64_perm *to, struct ipc64_perm *from)
  61. {
  62. to->key = from->key;
  63. to->uid = from->uid;
  64. to->gid = from->gid;
  65. to->cuid = from->cuid;
  66. to->cgid = from->cgid;
  67. to->mode = from->mode;
  68. to->seq = from->seq;
  69. }
  70. void to_compat_ipc_perm(struct compat_ipc_perm *to, struct ipc64_perm *from)
  71. {
  72. to->key = from->key;
  73. SET_UID(to->uid, from->uid);
  74. SET_GID(to->gid, from->gid);
  75. SET_UID(to->cuid, from->cuid);
  76. SET_GID(to->cgid, from->cgid);
  77. to->mode = from->mode;
  78. to->seq = from->seq;
  79. }
  80. static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
  81. {
  82. struct compat_msgbuf __user *msgp = dest;
  83. size_t msgsz;
  84. if (put_user(msg->m_type, &msgp->mtype))
  85. return -EFAULT;
  86. msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz;
  87. if (store_msg(msgp->mtext, msg, msgsz))
  88. return -EFAULT;
  89. return msgsz;
  90. }
  91. COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
  92. compat_ssize_t, msgsz, int, msgflg)
  93. {
  94. struct compat_msgbuf __user *up = compat_ptr(msgp);
  95. compat_long_t mtype;
  96. if (get_user(mtype, &up->mtype))
  97. return -EFAULT;
  98. return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg);
  99. }
  100. COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
  101. compat_ssize_t, msgsz, compat_long_t, msgtyp, int, msgflg)
  102. {
  103. return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp,
  104. msgflg, compat_do_msg_fill);
  105. }
  106. #ifndef COMPAT_SHMLBA
  107. #define COMPAT_SHMLBA SHMLBA
  108. #endif
  109. COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg)
  110. {
  111. unsigned long ret;
  112. long err;
  113. err = do_shmat(shmid, compat_ptr(shmaddr), shmflg, &ret, COMPAT_SHMLBA);
  114. if (err)
  115. return err;
  116. force_successful_syscall_return();
  117. return (long)ret;
  118. }
  119. COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems,
  120. unsigned, nsops,
  121. const struct compat_timespec __user *, timeout)
  122. {
  123. struct timespec __user *ts64;
  124. if (compat_convert_timespec(&ts64, timeout))
  125. return -EFAULT;
  126. return sys_semtimedop(semid, tsems, nsops, ts64);
  127. }