2
0

bsdload.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * Load BSD executables.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "qemu/osdep.h"
  18. #include "qemu.h"
  19. /* ??? This should really be somewhere else. */
  20. abi_long memcpy_to_target(abi_ulong dest, const void *src,
  21. unsigned long len)
  22. {
  23. void *host_ptr;
  24. host_ptr = lock_user(VERIFY_WRITE, dest, len, 0);
  25. if (!host_ptr) {
  26. return -TARGET_EFAULT;
  27. }
  28. memcpy(host_ptr, src, len);
  29. unlock_user(host_ptr, dest, 1);
  30. return 0;
  31. }
  32. static int count(char **vec)
  33. {
  34. int i;
  35. for (i = 0; *vec; i++) {
  36. vec++;
  37. }
  38. return i;
  39. }
  40. static int prepare_binprm(struct bsd_binprm *bprm)
  41. {
  42. struct stat st;
  43. int mode;
  44. int retval;
  45. if (fstat(bprm->fd, &st) < 0) {
  46. return -errno;
  47. }
  48. mode = st.st_mode;
  49. if (!S_ISREG(mode)) { /* Must be regular file */
  50. return -EACCES;
  51. }
  52. if (!(mode & 0111)) { /* Must have at least one execute bit set */
  53. return -EACCES;
  54. }
  55. bprm->e_uid = geteuid();
  56. bprm->e_gid = getegid();
  57. /* Set-uid? */
  58. if (mode & S_ISUID) {
  59. bprm->e_uid = st.st_uid;
  60. }
  61. /* Set-gid? */
  62. /*
  63. * If setgid is set but no group execute bit then this
  64. * is a candidate for mandatory locking, not a setgid
  65. * executable.
  66. */
  67. if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
  68. bprm->e_gid = st.st_gid;
  69. }
  70. memset(bprm->buf, 0, sizeof(bprm->buf));
  71. retval = lseek(bprm->fd, 0L, SEEK_SET);
  72. if (retval >= 0) {
  73. retval = read(bprm->fd, bprm->buf, 128);
  74. }
  75. if (retval < 0) {
  76. perror("prepare_binprm");
  77. exit(-1);
  78. } else {
  79. return retval;
  80. }
  81. }
  82. /* Construct the envp and argv tables on the target stack. */
  83. abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
  84. abi_ulong stringp)
  85. {
  86. int n = sizeof(abi_ulong);
  87. abi_ulong envp;
  88. abi_ulong argv;
  89. sp -= (envc + 1) * n;
  90. envp = sp;
  91. sp -= (argc + 1) * n;
  92. argv = sp;
  93. sp -= n;
  94. /* FIXME - handle put_user() failures */
  95. put_user_ual(argc, sp);
  96. while (argc-- > 0) {
  97. /* FIXME - handle put_user() failures */
  98. put_user_ual(stringp, argv);
  99. argv += n;
  100. stringp += target_strlen(stringp) + 1;
  101. }
  102. /* FIXME - handle put_user() failures */
  103. put_user_ual(0, argv);
  104. while (envc-- > 0) {
  105. /* FIXME - handle put_user() failures */
  106. put_user_ual(stringp, envp);
  107. envp += n;
  108. stringp += target_strlen(stringp) + 1;
  109. }
  110. /* FIXME - handle put_user() failures */
  111. put_user_ual(0, envp);
  112. return sp;
  113. }
  114. static bool is_there(const char *candidate)
  115. {
  116. struct stat fin;
  117. /* XXX work around access(2) false positives for superuser */
  118. if (access(candidate, X_OK) == 0 && stat(candidate, &fin) == 0 &&
  119. S_ISREG(fin.st_mode) && (getuid() != 0 ||
  120. (fin.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0)) {
  121. return true;
  122. }
  123. return false;
  124. }
  125. int loader_exec(const char *filename, char **argv, char **envp,
  126. struct target_pt_regs *regs, struct image_info *infop,
  127. struct bsd_binprm *bprm)
  128. {
  129. char *path, fullpath[PATH_MAX];
  130. int retval, i;
  131. bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES;
  132. for (i = 0; i < MAX_ARG_PAGES; i++) { /* clear page-table */
  133. bprm->page[i] = NULL;
  134. }
  135. if (strchr(filename, '/') != NULL) {
  136. path = realpath(filename, fullpath);
  137. if (path == NULL) {
  138. /* Failed to resolve. */
  139. return -1;
  140. }
  141. if (!is_there(path)) {
  142. return -1;
  143. }
  144. } else {
  145. path = g_find_program_in_path(filename);
  146. if (path == NULL) {
  147. return -1;
  148. }
  149. }
  150. retval = open(path, O_RDONLY);
  151. if (retval < 0) {
  152. g_free(path);
  153. return retval;
  154. }
  155. bprm->fullpath = path;
  156. bprm->fd = retval;
  157. bprm->filename = (char *)filename;
  158. bprm->argc = count(argv);
  159. bprm->argv = argv;
  160. bprm->envc = count(envp);
  161. bprm->envp = envp;
  162. retval = prepare_binprm(bprm);
  163. if (retval >= 0) {
  164. if (bprm->buf[0] == 0x7f
  165. && bprm->buf[1] == 'E'
  166. && bprm->buf[2] == 'L'
  167. && bprm->buf[3] == 'F') {
  168. retval = load_elf_binary(bprm, regs, infop);
  169. } else {
  170. fprintf(stderr, "Unknown binary format\n");
  171. return -1;
  172. }
  173. }
  174. if (retval >= 0) {
  175. /* success. Initialize important registers */
  176. do_init_thread(regs, infop);
  177. return retval;
  178. }
  179. /* Something went wrong, return the inode and free the argument pages*/
  180. for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
  181. g_free(bprm->page[i]);
  182. }
  183. return retval;
  184. }