linux_exec.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /* $OpenBSD: linux_exec.c,v 1.43 2015/05/05 02:13:47 guenther Exp $ */
  2. /* $NetBSD: linux_exec.c,v 1.13 1996/04/05 00:01:10 christos Exp $ */
  3. /*-
  4. * Copyright (c) 1994, 1995, 1998, 2000 The NetBSD Foundation, Inc.
  5. * All rights reserved.
  6. *
  7. * This code is derived from software contributed to The NetBSD Foundation
  8. * by Christos Zoulas, Frank van der Linden, Eric Haszlakiewicz and
  9. * Thor Lancelot Simon.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  21. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  22. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  24. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30. * POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. #include <sys/param.h>
  33. #include <sys/systm.h>
  34. #include <sys/kernel.h>
  35. #include <sys/proc.h>
  36. #include <sys/malloc.h>
  37. #include <sys/namei.h>
  38. #include <sys/vnode.h>
  39. #include <sys/mount.h>
  40. #include <sys/exec.h>
  41. #include <sys/exec_elf.h>
  42. #include <sys/mman.h>
  43. #include <sys/syscallargs.h>
  44. #include <sys/signalvar.h>
  45. #include <uvm/uvm_extern.h>
  46. #include <machine/cpu.h>
  47. #include <machine/reg.h>
  48. #include <machine/linux_machdep.h>
  49. #include <compat/linux/linux_types.h>
  50. #include <compat/linux/linux_syscall.h>
  51. #include <compat/linux/linux_signal.h>
  52. #include <compat/linux/linux_syscallargs.h>
  53. #include <compat/linux/linux_util.h>
  54. #include <compat/linux/linux_exec.h>
  55. #include <compat/linux/linux_emuldata.h>
  56. #define LINUX_ELF_AUX_ARGSIZ (sizeof(AuxInfo) * 8 / sizeof(char *))
  57. const char linux_emul_path[] = "/emul/linux";
  58. extern int linux_error[];
  59. extern char linux_sigcode[], linux_esigcode[];
  60. extern struct sysent linux_sysent[];
  61. #ifdef SYSCALL_DEBUG
  62. extern char *linux_syscallnames[];
  63. #endif
  64. extern struct mutex futex_lock;
  65. extern void futex_pool_init(void);
  66. void linux_e_proc_exec(struct proc *, struct exec_package *);
  67. void linux_e_proc_fork(struct proc *, struct proc *);
  68. void linux_e_proc_exit(struct proc *);
  69. void linux_e_proc_init(struct proc *, struct vmspace *);
  70. struct emul emul_linux_elf = {
  71. "linux",
  72. linux_error,
  73. linux_sendsig,
  74. LINUX_SYS_syscall,
  75. LINUX_SYS_MAXSYSCALL,
  76. linux_sysent,
  77. #ifdef SYSCALL_DEBUG
  78. linux_syscallnames,
  79. #else
  80. NULL,
  81. #endif
  82. LINUX_ELF_AUX_ARGSIZ,
  83. elf32_copyargs,
  84. setregs,
  85. exec_elf32_fixup,
  86. NULL, /* coredump */
  87. linux_sigcode,
  88. linux_esigcode,
  89. 0,
  90. NULL,
  91. linux_e_proc_exec,
  92. linux_e_proc_fork,
  93. linux_e_proc_exit,
  94. };
  95. /*
  96. * Allocate per-process structures. Called when executing Linux
  97. * process. We can reuse the old emuldata - if it's not null,
  98. * the executed process is of same emulation as original forked one.
  99. */
  100. void
  101. linux_e_proc_init(struct proc *p, struct vmspace *vmspace)
  102. {
  103. if (!p->p_emuldata) {
  104. /* allocate new Linux emuldata */
  105. p->p_emuldata = malloc(sizeof(struct linux_emuldata),
  106. M_EMULDATA, M_WAITOK|M_ZERO);
  107. }
  108. else {
  109. memset(p->p_emuldata, '\0', sizeof(struct linux_emuldata));
  110. }
  111. /* Set the process idea of the break to the real value */
  112. ((struct linux_emuldata *)(p->p_emuldata))->p_break =
  113. vmspace->vm_daddr + ptoa(vmspace->vm_dsize);
  114. }
  115. void
  116. linux_e_proc_exec(struct proc *p, struct exec_package *epp)
  117. {
  118. /* exec, use our vmspace */
  119. linux_e_proc_init(p, p->p_vmspace);
  120. }
  121. /*
  122. * Emulation per-process exit hook.
  123. */
  124. void
  125. linux_e_proc_exit(struct proc *p)
  126. {
  127. struct linux_emuldata *emul = p->p_emuldata;
  128. if (emul->my_clear_tid) {
  129. pid_t zero = 0;
  130. if (copyout(&zero, emul->my_clear_tid, sizeof(zero)))
  131. psignal(p, SIGSEGV);
  132. /*
  133. * not yet: futex(my_clear_tid, FUTEX_WAKE, 1, NULL, NULL, 0)
  134. */
  135. }
  136. /* free Linux emuldata and set the pointer to null */
  137. free(p->p_emuldata, M_EMULDATA, 0);
  138. p->p_emuldata = NULL;
  139. }
  140. /*
  141. * Emulation fork hook.
  142. */
  143. void
  144. linux_e_proc_fork(struct proc *p, struct proc *parent)
  145. {
  146. struct linux_emuldata *emul;
  147. struct linux_emuldata *parent_emul;
  148. /* Allocate new emuldata for the new process. */
  149. p->p_emuldata = NULL;
  150. /* fork, use parent's vmspace (our vmspace may not be setup yet) */
  151. linux_e_proc_init(p, parent->p_vmspace);
  152. emul = p->p_emuldata;
  153. parent_emul = parent->p_emuldata;
  154. emul->my_set_tid = parent_emul->child_set_tid;
  155. emul->my_clear_tid = parent_emul->child_clear_tid;
  156. emul->my_tls_base = parent_emul->child_tls_base;
  157. emul->set_tls_base = parent_emul->set_tls_base;
  158. }
  159. int
  160. exec_linux_elf32_makecmds(struct proc *p, struct exec_package *epp)
  161. {
  162. if (!(emul_linux_elf.e_flags & EMUL_ENABLED))
  163. return (ENOEXEC);
  164. return exec_elf32_makecmds(p, epp);
  165. }
  166. int
  167. linux_elf_probe(struct proc *p, struct exec_package *epp, char *itp,
  168. u_long *pos)
  169. {
  170. Elf32_Ehdr *eh = epp->ep_hdr;
  171. char *bp, *brand;
  172. int error;
  173. size_t len;
  174. if (!(emul_linux_elf.e_flags & EMUL_ENABLED))
  175. return (ENOEXEC);
  176. /*
  177. * Modern Linux binaries carry an identification note.
  178. */
  179. if (ELFNAME(os_pt_note)(p, epp, epp->ep_hdr, "GNU", 4, 0x10) == 0) {
  180. goto recognized;
  181. }
  182. brand = elf32_check_brand(eh);
  183. if (brand != NULL && strcmp(brand, "Linux") != 0)
  184. return (EINVAL);
  185. /*
  186. * If this is a static binary, do not allow it to run, as it
  187. * has not been identified. We'll give non-static binaries a
  188. * chance to run, as the Linux ld.so name is usually unique
  189. * enough to clear any ambiguity.
  190. */
  191. if (itp == NULL)
  192. return (EINVAL);
  193. recognized:
  194. if (itp) {
  195. if ((error = emul_find(p, NULL, linux_emul_path, itp, &bp, 0)))
  196. return (error);
  197. error = copystr(bp, itp, MAXPATHLEN, &len);
  198. free(bp, M_TEMP, 0);
  199. if (error)
  200. return (error);
  201. }
  202. epp->ep_emul = &emul_linux_elf;
  203. *pos = ELF32_NO_ADDR;
  204. mtx_init(&futex_lock, IPL_NONE);
  205. futex_pool_init();
  206. return (0);
  207. }
  208. /*
  209. * Execve(2). Just check the alternate emulation path, and pass it on
  210. * to the regular execve().
  211. */
  212. int
  213. linux_sys_execve(struct proc *p, void *v, register_t *retval)
  214. {
  215. struct linux_sys_execve_args /* {
  216. syscallarg(char *) path;
  217. syscallarg(char **) argv;
  218. syscallarg(char **) envp;
  219. } */ *uap = v;
  220. struct sys_execve_args ap;
  221. caddr_t sg;
  222. sg = stackgap_init(p);
  223. LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  224. SCARG(&ap, path) = SCARG(uap, path);
  225. SCARG(&ap, argp) = SCARG(uap, argp);
  226. SCARG(&ap, envp) = SCARG(uap, envp);
  227. return (sys_execve(p, &ap, retval));
  228. }