uid16.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*
  2. * Wrapper functions for 16bit uid back compatibility. All nicely tied
  3. * together in the faint hope we can take the out in five years time.
  4. */
  5. #include <linux/mm.h>
  6. #include <linux/utsname.h>
  7. #include <linux/mman.h>
  8. #include <linux/notifier.h>
  9. #include <linux/reboot.h>
  10. #include <linux/prctl.h>
  11. #include <linux/capability.h>
  12. #include <linux/init.h>
  13. #include <linux/highuid.h>
  14. #include <linux/security.h>
  15. #include <linux/syscalls.h>
  16. #include <asm/uaccess.h>
  17. asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gid_t group)
  18. {
  19. long ret = sys_chown(filename, low2highuid(user), low2highgid(group));
  20. /* avoid REGPARM breakage on x86: */
  21. prevent_tail_call(ret);
  22. return ret;
  23. }
  24. asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_gid_t group)
  25. {
  26. long ret = sys_lchown(filename, low2highuid(user), low2highgid(group));
  27. /* avoid REGPARM breakage on x86: */
  28. prevent_tail_call(ret);
  29. return ret;
  30. }
  31. asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group)
  32. {
  33. long ret = sys_fchown(fd, low2highuid(user), low2highgid(group));
  34. /* avoid REGPARM breakage on x86: */
  35. prevent_tail_call(ret);
  36. return ret;
  37. }
  38. asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid)
  39. {
  40. long ret = sys_setregid(low2highgid(rgid), low2highgid(egid));
  41. /* avoid REGPARM breakage on x86: */
  42. prevent_tail_call(ret);
  43. return ret;
  44. }
  45. asmlinkage long sys_setgid16(old_gid_t gid)
  46. {
  47. long ret = sys_setgid(low2highgid(gid));
  48. /* avoid REGPARM breakage on x86: */
  49. prevent_tail_call(ret);
  50. return ret;
  51. }
  52. asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid)
  53. {
  54. long ret = sys_setreuid(low2highuid(ruid), low2highuid(euid));
  55. /* avoid REGPARM breakage on x86: */
  56. prevent_tail_call(ret);
  57. return ret;
  58. }
  59. asmlinkage long sys_setuid16(old_uid_t uid)
  60. {
  61. long ret = sys_setuid(low2highuid(uid));
  62. /* avoid REGPARM breakage on x86: */
  63. prevent_tail_call(ret);
  64. return ret;
  65. }
  66. asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid)
  67. {
  68. long ret = sys_setresuid(low2highuid(ruid), low2highuid(euid),
  69. low2highuid(suid));
  70. /* avoid REGPARM breakage on x86: */
  71. prevent_tail_call(ret);
  72. return ret;
  73. }
  74. asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, old_uid_t __user *suid)
  75. {
  76. int retval;
  77. if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
  78. !(retval = put_user(high2lowuid(current->euid), euid)))
  79. retval = put_user(high2lowuid(current->suid), suid);
  80. return retval;
  81. }
  82. asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid)
  83. {
  84. long ret = sys_setresgid(low2highgid(rgid), low2highgid(egid),
  85. low2highgid(sgid));
  86. /* avoid REGPARM breakage on x86: */
  87. prevent_tail_call(ret);
  88. return ret;
  89. }
  90. asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, old_gid_t __user *sgid)
  91. {
  92. int retval;
  93. if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
  94. !(retval = put_user(high2lowgid(current->egid), egid)))
  95. retval = put_user(high2lowgid(current->sgid), sgid);
  96. return retval;
  97. }
  98. asmlinkage long sys_setfsuid16(old_uid_t uid)
  99. {
  100. long ret = sys_setfsuid(low2highuid(uid));
  101. /* avoid REGPARM breakage on x86: */
  102. prevent_tail_call(ret);
  103. return ret;
  104. }
  105. asmlinkage long sys_setfsgid16(old_gid_t gid)
  106. {
  107. long ret = sys_setfsgid(low2highgid(gid));
  108. /* avoid REGPARM breakage on x86: */
  109. prevent_tail_call(ret);
  110. return ret;
  111. }
  112. static int groups16_to_user(old_gid_t __user *grouplist,
  113. struct group_info *group_info)
  114. {
  115. int i;
  116. old_gid_t group;
  117. for (i = 0; i < group_info->ngroups; i++) {
  118. group = high2lowgid(GROUP_AT(group_info, i));
  119. if (put_user(group, grouplist+i))
  120. return -EFAULT;
  121. }
  122. return 0;
  123. }
  124. static int groups16_from_user(struct group_info *group_info,
  125. old_gid_t __user *grouplist)
  126. {
  127. int i;
  128. old_gid_t group;
  129. for (i = 0; i < group_info->ngroups; i++) {
  130. if (get_user(group, grouplist+i))
  131. return -EFAULT;
  132. GROUP_AT(group_info, i) = low2highgid(group);
  133. }
  134. return 0;
  135. }
  136. asmlinkage long sys_getgroups16(int gidsetsize, old_gid_t __user *grouplist)
  137. {
  138. int i = 0;
  139. if (gidsetsize < 0)
  140. return -EINVAL;
  141. get_group_info(current->group_info);
  142. i = current->group_info->ngroups;
  143. if (gidsetsize) {
  144. if (i > gidsetsize) {
  145. i = -EINVAL;
  146. goto out;
  147. }
  148. if (groups16_to_user(grouplist, current->group_info)) {
  149. i = -EFAULT;
  150. goto out;
  151. }
  152. }
  153. out:
  154. put_group_info(current->group_info);
  155. return i;
  156. }
  157. asmlinkage long sys_setgroups16(int gidsetsize, old_gid_t __user *grouplist)
  158. {
  159. struct group_info *group_info;
  160. int retval;
  161. if (!capable(CAP_SETGID))
  162. return -EPERM;
  163. if ((unsigned)gidsetsize > NGROUPS_MAX)
  164. return -EINVAL;
  165. group_info = groups_alloc(gidsetsize);
  166. if (!group_info)
  167. return -ENOMEM;
  168. retval = groups16_from_user(group_info, grouplist);
  169. if (retval) {
  170. put_group_info(group_info);
  171. return retval;
  172. }
  173. retval = set_current_groups(group_info);
  174. put_group_info(group_info);
  175. return retval;
  176. }
  177. asmlinkage long sys_getuid16(void)
  178. {
  179. return high2lowuid(current->uid);
  180. }
  181. asmlinkage long sys_geteuid16(void)
  182. {
  183. return high2lowuid(current->euid);
  184. }
  185. asmlinkage long sys_getgid16(void)
  186. {
  187. return high2lowgid(current->gid);
  188. }
  189. asmlinkage long sys_getegid16(void)
  190. {
  191. return high2lowgid(current->egid);
  192. }