shim_getpid.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /* Copyright (C) 2014 Stony Brook University
  2. This file is part of Graphene Library OS.
  3. Graphene Library OS is free software: you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public License
  5. as published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. Graphene Library OS is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. /*
  14. * shim_getpid.c
  15. *
  16. * Implementation of system call "getpid", "gettid", "getppid",
  17. * "set_tid_address", "getuid", "getgid", "setuid", "setgid", "geteuid",
  18. * "getegid", "setpgid", "getpgid", "getpgrp", "setgroups", "getgroups",
  19. * "setsid" and "getsid".
  20. */
  21. #include <shim_internal.h>
  22. #include <shim_table.h>
  23. #include <shim_thread.h>
  24. #include <shim_ipc.h>
  25. #include <shim_checkpoint.h>
  26. #include <pal.h>
  27. #include <pal_error.h>
  28. #include <sys/syscall.h>
  29. #include <sys/mman.h>
  30. #include <asm/prctl.h>
  31. #include <errno.h>
  32. pid_t shim_do_getpid (void)
  33. {
  34. struct shim_thread * cur = get_cur_thread();
  35. return cur ? cur->tgid : 0;
  36. }
  37. pid_t shim_do_gettid (void)
  38. {
  39. struct shim_thread * cur = get_cur_thread();
  40. return cur ? cur->tid : 0;
  41. }
  42. pid_t shim_do_getppid (void)
  43. {
  44. struct shim_thread * cur = get_cur_thread();
  45. return cur ? (cur->parent ? cur->parent->tid : cur->ppid) : 0;
  46. }
  47. int shim_do_set_tid_address (int * tidptr)
  48. {
  49. /* http://man7.org/linux/man-pages/man2/set_tid_address.2.html */
  50. struct shim_thread * cur = get_cur_thread();
  51. cur->clear_child_tid = tidptr;
  52. return cur->tid;
  53. }
  54. uid_t shim_do_getuid (void)
  55. {
  56. struct shim_thread * cur = get_cur_thread();
  57. return cur ? cur->uid : 0;
  58. }
  59. gid_t shim_do_getgid (void)
  60. {
  61. struct shim_thread * cur = get_cur_thread();
  62. return cur ? cur->gid : 0;
  63. }
  64. int shim_do_setuid (uid_t uid)
  65. {
  66. struct shim_thread * cur = get_cur_thread();
  67. cur->euid = (uint16_t) uid;
  68. return 0;
  69. }
  70. int shim_do_setgid (gid_t gid)
  71. {
  72. struct shim_thread * cur = get_cur_thread();
  73. cur->egid = (uint16_t) gid;
  74. return 0;
  75. }
  76. /* shim_do_set{get}groups() do not propagate group info to host OS but rather are dummies */
  77. #define NGROUPS_MAX 65536 /* # of supplemental group IDs; has to be same as host OS */
  78. static struct groups_info_t {
  79. int size;
  80. gid_t spl_gid[NGROUPS_MAX];
  81. } g_groups_info __attribute_migratable = { .size = -1 };
  82. int shim_do_setgroups(int gidsetsize, gid_t* grouplist) {
  83. if ((unsigned)gidsetsize > NGROUPS_MAX)
  84. return -EINVAL;
  85. if (gidsetsize && test_user_memory(grouplist, gidsetsize * sizeof(gid_t), true))
  86. return -EFAULT;
  87. lock(&cur_process.lock);
  88. g_groups_info.size = gidsetsize;
  89. for (int i = 0; i < gidsetsize; i++)
  90. g_groups_info.spl_gid[i] = grouplist[i];
  91. unlock(&cur_process.lock);
  92. return 0;
  93. }
  94. int shim_do_getgroups(int gidsetsize, gid_t* grouplist) {
  95. int cur_groups_size;
  96. if (gidsetsize < 0)
  97. return -EINVAL;
  98. if (gidsetsize && test_user_memory(grouplist, gidsetsize * sizeof(gid_t), true))
  99. return -EFAULT;
  100. lock(&cur_process.lock);
  101. if (g_groups_info.size == -1) {
  102. /* initialize with getgid() */
  103. g_groups_info.size = 1;
  104. g_groups_info.spl_gid[0] = shim_do_getgid();
  105. }
  106. cur_groups_size = g_groups_info.size;
  107. if (gidsetsize) {
  108. if (cur_groups_size > gidsetsize) {
  109. unlock(&cur_process.lock);
  110. return -EINVAL;
  111. }
  112. for (int i = 0; i < cur_groups_size; i++)
  113. grouplist[i] = g_groups_info.spl_gid[i];
  114. }
  115. unlock(&cur_process.lock);
  116. return cur_groups_size;
  117. }
  118. uid_t shim_do_geteuid (void)
  119. {
  120. struct shim_thread * cur = get_cur_thread();
  121. return cur ? cur->euid : 0;
  122. }
  123. gid_t shim_do_getegid (void)
  124. {
  125. struct shim_thread * cur = get_cur_thread();
  126. return cur ? cur->egid : 0;
  127. }
  128. int shim_do_setpgid (pid_t pid, pid_t pgid)
  129. {
  130. struct shim_thread * thread =
  131. pid ? lookup_thread(pid) : get_cur_thread();
  132. if (!pid)
  133. assert(thread);
  134. if (!thread)
  135. return -ESRCH;
  136. thread->pgid = (IDTYPE) pgid ? : thread->tgid;
  137. return 0;
  138. }
  139. int shim_do_getpgid (pid_t pid)
  140. {
  141. struct shim_thread * thread =
  142. pid ? lookup_thread(pid) : get_cur_thread();
  143. if (!thread)
  144. return -ESRCH;
  145. return thread->pgid;
  146. }
  147. pid_t shim_do_getpgrp (void)
  148. {
  149. struct shim_thread * cur_thread = get_cur_thread();
  150. assert(cur_thread);
  151. return cur_thread->pgid;
  152. }
  153. int shim_do_setsid (void)
  154. {
  155. struct shim_thread * cur_thread = get_cur_thread();
  156. assert(cur_thread);
  157. if (cur_thread->pgid == cur_thread->tgid)
  158. return -EPERM;
  159. cur_thread->pgid = cur_thread->tgid;
  160. /* TODO: the calling process may haveto be detached from the
  161. tty, but there is no need to handle it for now. */
  162. return 0;
  163. }
  164. int shim_do_getsid (pid_t pid)
  165. {
  166. struct shim_thread * thread =
  167. pid ? lookup_thread(pid) : get_cur_thread();
  168. if (!thread)
  169. return -ESRCH;
  170. return thread->pgid;
  171. }