shim_getpid.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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 <asm/prctl.h>
  22. #include <errno.h>
  23. #include <pal.h>
  24. #include <pal_error.h>
  25. #include <shim_checkpoint.h>
  26. #include <shim_internal.h>
  27. #include <shim_ipc.h>
  28. #include <shim_table.h>
  29. #include <shim_thread.h>
  30. #include <sys/mman.h>
  31. #include <sys/syscall.h>
  32. pid_t shim_do_getpid(void) {
  33. struct shim_thread* cur = get_cur_thread();
  34. return cur ? cur->tgid : 0;
  35. }
  36. pid_t shim_do_gettid(void) {
  37. struct shim_thread* cur = get_cur_thread();
  38. return cur ? cur->tid : 0;
  39. }
  40. pid_t shim_do_getppid(void) {
  41. struct shim_thread* cur = get_cur_thread();
  42. return cur ? (cur->parent ? cur->parent->tid : cur->ppid) : 0;
  43. }
  44. int shim_do_set_tid_address(int* tidptr) {
  45. /* http://man7.org/linux/man-pages/man2/set_tid_address.2.html */
  46. struct shim_thread* cur = get_cur_thread();
  47. cur->clear_child_tid = tidptr;
  48. return cur->tid;
  49. }
  50. uid_t shim_do_getuid(void) {
  51. struct shim_thread* cur = get_cur_thread();
  52. return cur ? cur->uid : 0;
  53. }
  54. gid_t shim_do_getgid(void) {
  55. struct shim_thread* cur = get_cur_thread();
  56. return cur ? cur->gid : 0;
  57. }
  58. int shim_do_setuid(uid_t uid) {
  59. struct shim_thread* cur = get_cur_thread();
  60. cur->euid = (uint16_t)uid;
  61. return 0;
  62. }
  63. int shim_do_setgid(gid_t gid) {
  64. struct shim_thread* cur = get_cur_thread();
  65. cur->egid = (uint16_t)gid;
  66. return 0;
  67. }
  68. /* shim_do_set{get}groups() do not propagate group info to host OS but rather are dummies */
  69. #define NGROUPS_MAX 65536 /* # of supplemental group IDs; has to be same as host OS */
  70. static struct groups_info_t {
  71. int size;
  72. gid_t spl_gid[NGROUPS_MAX];
  73. } g_groups_info __attribute_migratable = {.size = -1};
  74. int shim_do_setgroups(int gidsetsize, gid_t* grouplist) {
  75. if ((unsigned)gidsetsize > NGROUPS_MAX)
  76. return -EINVAL;
  77. if (gidsetsize && test_user_memory(grouplist, gidsetsize * sizeof(gid_t), true))
  78. return -EFAULT;
  79. lock(&cur_process.lock);
  80. g_groups_info.size = gidsetsize;
  81. for (int i = 0; i < gidsetsize; i++) {
  82. g_groups_info.spl_gid[i] = grouplist[i];
  83. }
  84. unlock(&cur_process.lock);
  85. return 0;
  86. }
  87. int shim_do_getgroups(int gidsetsize, gid_t* grouplist) {
  88. int cur_groups_size;
  89. if (gidsetsize < 0)
  90. return -EINVAL;
  91. if (gidsetsize && test_user_memory(grouplist, gidsetsize * sizeof(gid_t), true))
  92. return -EFAULT;
  93. lock(&cur_process.lock);
  94. if (g_groups_info.size == -1) {
  95. /* initialize with getgid() */
  96. g_groups_info.size = 1;
  97. g_groups_info.spl_gid[0] = shim_do_getgid();
  98. }
  99. cur_groups_size = g_groups_info.size;
  100. if (gidsetsize) {
  101. if (cur_groups_size > gidsetsize) {
  102. unlock(&cur_process.lock);
  103. return -EINVAL;
  104. }
  105. for (int i = 0; i < cur_groups_size; i++) {
  106. grouplist[i] = g_groups_info.spl_gid[i];
  107. }
  108. }
  109. unlock(&cur_process.lock);
  110. return cur_groups_size;
  111. }
  112. uid_t shim_do_geteuid(void) {
  113. struct shim_thread* cur = get_cur_thread();
  114. return cur ? cur->euid : 0;
  115. }
  116. gid_t shim_do_getegid(void) {
  117. struct shim_thread* cur = get_cur_thread();
  118. return cur ? cur->egid : 0;
  119. }
  120. int shim_do_setpgid(pid_t pid, pid_t pgid) {
  121. struct shim_thread* thread = pid ? lookup_thread(pid) : get_cur_thread();
  122. if (!pid)
  123. assert(thread);
  124. if (!thread)
  125. return -ESRCH;
  126. thread->pgid = (IDTYPE)pgid ?: thread->tgid;
  127. return 0;
  128. }
  129. int shim_do_getpgid(pid_t pid) {
  130. struct shim_thread* thread = pid ? lookup_thread(pid) : get_cur_thread();
  131. if (!thread)
  132. return -ESRCH;
  133. return thread->pgid;
  134. }
  135. pid_t shim_do_getpgrp(void) {
  136. struct shim_thread* cur_thread = get_cur_thread();
  137. assert(cur_thread);
  138. return cur_thread->pgid;
  139. }
  140. int shim_do_setsid(void) {
  141. struct shim_thread* cur_thread = get_cur_thread();
  142. assert(cur_thread);
  143. if (cur_thread->pgid == cur_thread->tgid)
  144. return -EPERM;
  145. cur_thread->pgid = cur_thread->tgid;
  146. /* TODO: the calling process may haveto be detached from the
  147. tty, but there is no need to handle it for now. */
  148. return 0;
  149. }
  150. int shim_do_getsid(pid_t pid) {
  151. struct shim_thread* thread = pid ? lookup_thread(pid) : get_cur_thread();
  152. if (!thread)
  153. return -ESRCH;
  154. return thread->pgid;
  155. }