2
0

linuxload.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /* Code for loading Linux executables. Mostly linux kernel code. */
  2. #include "qemu/osdep.h"
  3. #include "qemu.h"
  4. #include "user-internals.h"
  5. #include "user-mmap.h"
  6. #include "loader.h"
  7. #include "qapi/error.h"
  8. #define NGROUPS 32
  9. /* ??? This should really be somewhere else. */
  10. abi_long memcpy_to_target(abi_ulong dest, const void *src, unsigned long len)
  11. {
  12. void *host_ptr;
  13. host_ptr = lock_user(VERIFY_WRITE, dest, len, 0);
  14. if (!host_ptr) {
  15. return -TARGET_EFAULT;
  16. }
  17. memcpy(host_ptr, src, len);
  18. unlock_user(host_ptr, dest, 1);
  19. return 0;
  20. }
  21. static int count(char **vec)
  22. {
  23. int i;
  24. for (i = 0; *vec; i++) {
  25. vec++;
  26. }
  27. return i;
  28. }
  29. static int prepare_binprm(struct linux_binprm *bprm)
  30. {
  31. struct stat st;
  32. int mode;
  33. int retval;
  34. if (fstat(bprm->src.fd, &st) < 0) {
  35. return -errno;
  36. }
  37. mode = st.st_mode;
  38. if (!S_ISREG(mode)) { /* Must be regular file */
  39. return -EACCES;
  40. }
  41. if (!(mode & 0111)) { /* Must have at least one execute bit set */
  42. return -EACCES;
  43. }
  44. bprm->e_uid = geteuid();
  45. bprm->e_gid = getegid();
  46. /* Set-uid? */
  47. if (mode & S_ISUID) {
  48. bprm->e_uid = st.st_uid;
  49. }
  50. /* Set-gid? */
  51. /*
  52. * If setgid is set but no group execute bit then this
  53. * is a candidate for mandatory locking, not a setgid
  54. * executable.
  55. */
  56. if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
  57. bprm->e_gid = st.st_gid;
  58. }
  59. retval = read(bprm->src.fd, bprm->buf, BPRM_BUF_SIZE);
  60. if (retval < 0) {
  61. perror("prepare_binprm");
  62. exit(-1);
  63. }
  64. if (retval < BPRM_BUF_SIZE) {
  65. /* Make sure the rest of the loader won't read garbage. */
  66. memset(bprm->buf + retval, 0, BPRM_BUF_SIZE - retval);
  67. }
  68. bprm->src.cache = bprm->buf;
  69. bprm->src.cache_size = retval;
  70. return retval;
  71. }
  72. /* Construct the envp and argv tables on the target stack. */
  73. abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
  74. abi_ulong stringp, int push_ptr)
  75. {
  76. TaskState *ts = get_task_state(thread_cpu);
  77. int n = sizeof(abi_ulong);
  78. abi_ulong envp;
  79. abi_ulong argv;
  80. sp -= (envc + 1) * n;
  81. envp = sp;
  82. sp -= (argc + 1) * n;
  83. argv = sp;
  84. ts->info->envp = envp;
  85. ts->info->envc = envc;
  86. ts->info->argv = argv;
  87. ts->info->argc = argc;
  88. if (push_ptr) {
  89. /* FIXME - handle put_user() failures */
  90. sp -= n;
  91. put_user_ual(envp, sp);
  92. sp -= n;
  93. put_user_ual(argv, sp);
  94. }
  95. sp -= n;
  96. /* FIXME - handle put_user() failures */
  97. put_user_ual(argc, sp);
  98. ts->info->arg_strings = stringp;
  99. while (argc-- > 0) {
  100. /* FIXME - handle put_user() failures */
  101. put_user_ual(stringp, argv);
  102. argv += n;
  103. stringp += target_strlen(stringp) + 1;
  104. }
  105. /* FIXME - handle put_user() failures */
  106. put_user_ual(0, argv);
  107. ts->info->env_strings = stringp;
  108. while (envc-- > 0) {
  109. /* FIXME - handle put_user() failures */
  110. put_user_ual(stringp, envp);
  111. envp += n;
  112. stringp += target_strlen(stringp) + 1;
  113. }
  114. /* FIXME - handle put_user() failures */
  115. put_user_ual(0, envp);
  116. return sp;
  117. }
  118. int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
  119. struct target_pt_regs *regs, struct image_info *infop,
  120. struct linux_binprm *bprm)
  121. {
  122. int retval;
  123. bprm->src.fd = fdexec;
  124. bprm->filename = (char *)filename;
  125. bprm->argc = count(argv);
  126. bprm->argv = argv;
  127. bprm->envc = count(envp);
  128. bprm->envp = envp;
  129. retval = prepare_binprm(bprm);
  130. if (retval < 4) {
  131. return -ENOEXEC;
  132. }
  133. if (bprm->buf[0] == 0x7f
  134. && bprm->buf[1] == 'E'
  135. && bprm->buf[2] == 'L'
  136. && bprm->buf[3] == 'F') {
  137. retval = load_elf_binary(bprm, infop);
  138. #if defined(TARGET_HAS_BFLT)
  139. } else if (bprm->buf[0] == 'b'
  140. && bprm->buf[1] == 'F'
  141. && bprm->buf[2] == 'L'
  142. && bprm->buf[3] == 'T') {
  143. retval = load_flt_binary(bprm, infop);
  144. #endif
  145. } else {
  146. return -ENOEXEC;
  147. }
  148. if (retval < 0) {
  149. return retval;
  150. }
  151. /* Success. Initialize important registers. */
  152. do_init_thread(regs, infop);
  153. return 0;
  154. }
  155. bool imgsrc_read(void *dst, off_t offset, size_t len,
  156. const ImageSource *img, Error **errp)
  157. {
  158. ssize_t ret;
  159. if (offset + len <= img->cache_size) {
  160. memcpy(dst, img->cache + offset, len);
  161. return true;
  162. }
  163. if (img->fd < 0) {
  164. error_setg(errp, "read past end of buffer");
  165. return false;
  166. }
  167. ret = pread(img->fd, dst, len, offset);
  168. if (ret == len) {
  169. return true;
  170. }
  171. if (ret < 0) {
  172. error_setg_errno(errp, errno, "Error reading file header");
  173. } else {
  174. error_setg(errp, "Incomplete read of file header");
  175. }
  176. return false;
  177. }
  178. void *imgsrc_read_alloc(off_t offset, size_t len,
  179. const ImageSource *img, Error **errp)
  180. {
  181. void *alloc = g_malloc(len);
  182. bool ok = imgsrc_read(alloc, offset, len, img, errp);
  183. if (!ok) {
  184. g_free(alloc);
  185. alloc = NULL;
  186. }
  187. return alloc;
  188. }
  189. abi_long imgsrc_mmap(abi_ulong start, abi_ulong len, int prot,
  190. int flags, const ImageSource *src, abi_ulong offset)
  191. {
  192. const int prot_write = PROT_READ | PROT_WRITE;
  193. abi_long ret;
  194. void *haddr;
  195. assert(flags == (MAP_PRIVATE | MAP_FIXED));
  196. if (src->fd >= 0) {
  197. return target_mmap(start, len, prot, flags, src->fd, offset);
  198. }
  199. /*
  200. * This case is for the vdso; we don't expect bad images.
  201. * The mmap may extend beyond the end of the image, especially
  202. * to the end of the page. Zero fill.
  203. */
  204. assert(offset < src->cache_size);
  205. ret = target_mmap(start, len, prot_write, flags | MAP_ANON, -1, 0);
  206. if (ret == -1) {
  207. return ret;
  208. }
  209. haddr = lock_user(VERIFY_WRITE, start, len, 0);
  210. assert(haddr != NULL);
  211. if (offset + len <= src->cache_size) {
  212. memcpy(haddr, src->cache + offset, len);
  213. } else {
  214. size_t rest = src->cache_size - offset;
  215. memcpy(haddr, src->cache + offset, rest);
  216. memset(haddr + rest, 0, len - rest);
  217. }
  218. unlock_user(haddr, start, len);
  219. if (prot != prot_write) {
  220. target_mprotect(start, len, prot);
  221. }
  222. return ret;
  223. }