1 /*-
2 * Copyright (c) 1998 Mark Newton
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Christos Zoulas.
16 * 4. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 /* XXX we use functions that might not exist. */
35 #include "opt_compat.h"
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/proc.h>
40 #include <sys/sysent.h>
41 #include <sys/imgact.h>
42 #include <sys/imgact_elf.h>
43 #include <sys/fcntl.h>
44 #include <sys/lock.h>
45 #include <sys/malloc.h>
46 #include <sys/module.h>
47 #include <sys/mutex.h>
48 #include <sys/namei.h>
49 #include <sys/socket.h>
50 #include <sys/syscallsubr.h>
51 #include <sys/vnode.h>
52 #include <vm/vm.h>
53 #include <sys/exec.h>
54 #include <sys/kernel.h>
55 #include <machine/cpu.h>
56 #include <netinet/in.h>
57
58 #include <compat/svr4/svr4.h>
59 #include <compat/svr4/svr4_types.h>
60 #include <compat/svr4/svr4_syscall.h>
61 #include <compat/svr4/svr4_signal.h>
62 #include <compat/svr4/svr4_socket.h>
63 #include <compat/svr4/svr4_sockio.h>
64 #include <compat/svr4/svr4_errno.h>
65 #include <compat/svr4/svr4_proto.h>
66 #include <compat/svr4/svr4_siginfo.h>
67 #include <compat/svr4/svr4_util.h>
68
69 int bsd_to_svr4_errno[ELAST+1] = {
70 0,
71 SVR4_EPERM,
72 SVR4_ENOENT,
73 SVR4_ESRCH,
74 SVR4_EINTR,
75 SVR4_EIO,
76 SVR4_ENXIO,
77 SVR4_E2BIG,
78 SVR4_ENOEXEC,
79 SVR4_EBADF,
80 SVR4_ECHILD,
81 SVR4_EDEADLK,
82 SVR4_ENOMEM,
83 SVR4_EACCES,
84 SVR4_EFAULT,
85 SVR4_ENOTBLK,
86 SVR4_EBUSY,
87 SVR4_EEXIST,
88 SVR4_EXDEV,
89 SVR4_ENODEV,
90 SVR4_ENOTDIR,
91 SVR4_EISDIR,
92 SVR4_EINVAL,
93 SVR4_ENFILE,
94 SVR4_EMFILE,
95 SVR4_ENOTTY,
96 SVR4_ETXTBSY,
97 SVR4_EFBIG,
98 SVR4_ENOSPC,
99 SVR4_ESPIPE,
100 SVR4_EROFS,
101 SVR4_EMLINK,
102 SVR4_EPIPE,
103 SVR4_EDOM,
104 SVR4_ERANGE,
105 SVR4_EAGAIN,
106 SVR4_EINPROGRESS,
107 SVR4_EALREADY,
108 SVR4_ENOTSOCK,
109 SVR4_EDESTADDRREQ,
110 SVR4_EMSGSIZE,
111 SVR4_EPROTOTYPE,
112 SVR4_ENOPROTOOPT,
113 SVR4_EPROTONOSUPPORT,
114 SVR4_ESOCKTNOSUPPORT,
115 SVR4_EOPNOTSUPP,
116 SVR4_EPFNOSUPPORT,
117 SVR4_EAFNOSUPPORT,
118 SVR4_EADDRINUSE,
119 SVR4_EADDRNOTAVAIL,
120 SVR4_ENETDOWN,
121 SVR4_ENETUNREACH,
122 SVR4_ENETRESET,
123 SVR4_ECONNABORTED,
124 SVR4_ECONNRESET,
125 SVR4_ENOBUFS,
126 SVR4_EISCONN,
127 SVR4_ENOTCONN,
128 SVR4_ESHUTDOWN,
129 SVR4_ETOOMANYREFS,
130 SVR4_ETIMEDOUT,
131 SVR4_ECONNREFUSED,
132 SVR4_ELOOP,
133 SVR4_ENAMETOOLONG,
134 SVR4_EHOSTDOWN,
135 SVR4_EHOSTUNREACH,
136 SVR4_ENOTEMPTY,
137 SVR4_EPROCLIM,
138 SVR4_EUSERS,
139 SVR4_EDQUOT,
140 SVR4_ESTALE,
141 SVR4_EREMOTE,
142 SVR4_EBADRPC,
143 SVR4_ERPCMISMATCH,
144 SVR4_EPROGUNAVAIL,
145 SVR4_EPROGMISMATCH,
146 SVR4_EPROCUNAVAIL,
147 SVR4_ENOLCK,
148 SVR4_ENOSYS,
149 SVR4_EFTYPE,
150 SVR4_EAUTH,
151 SVR4_ENEEDAUTH,
152 SVR4_EIDRM,
153 SVR4_ENOMSG,
154 };
155
156
157 static int svr4_fixup(register_t **stack_base, struct image_params *imgp);
158
159 extern struct sysent svr4_sysent[];
160 #undef szsigcode
161 #undef sigcode
162
163 extern int svr4_szsigcode;
164 extern char svr4_sigcode[];
165
166 struct sysentvec svr4_sysvec = {
167 .sv_size = SVR4_SYS_MAXSYSCALL,
168 .sv_table = svr4_sysent,
169 .sv_mask = 0xff,
170 .sv_sigsize = SVR4_NSIG-1, /* NB: signal trans table indexed with signno-1 */
171 .sv_sigtbl = bsd_to_svr4_sig+1,
172 .sv_errsize = ELAST, /* ELAST */
173 .sv_errtbl = bsd_to_svr4_errno,
174 .sv_transtrap = NULL,
175 .sv_fixup = svr4_fixup,
176 .sv_sendsig = svr4_sendsig,
177 .sv_sigcode = svr4_sigcode,
178 .sv_szsigcode = &svr4_szsigcode,
179 .sv_prepsyscall = NULL,
180 .sv_name = "SVR4",
181 .sv_coredump = elf32_coredump,
182 .sv_imgact_try = NULL,
183 .sv_minsigstksz = SVR4_MINSIGSTKSZ,
184 .sv_pagesize = PAGE_SIZE,
185 .sv_minuser = VM_MIN_ADDRESS,
186 .sv_maxuser = VM_MAXUSER_ADDRESS,
187 .sv_usrstack = USRSTACK,
188 .sv_psstrings = PS_STRINGS,
189 .sv_stackprot = VM_PROT_ALL,
190 .sv_copyout_strings = exec_copyout_strings,
191 .sv_setregs = exec_setregs,
192 .sv_fixlimit = NULL,
193 .sv_maxssiz = NULL,
194 .sv_flags = SV_ABI_UNDEF | SV_IA32 | SV_ILP32,
195 .sv_set_syscall_retval = cpu_set_syscall_retval,
196 .sv_fetch_syscall_args = cpu_fetch_syscall_args,
197 .sv_syscallnames = NULL,
198 .sv_schedtail = NULL,
199 };
200
201 const char svr4_emul_path[] = "/compat/svr4";
202
203 Elf32_Brandinfo svr4_brand = {
204 .brand = ELFOSABI_SYSV,
205 .machine = EM_386, /* XXX only implemented for x86 so far. */
206 .compat_3_brand = "SVR4",
207 .emul_path = svr4_emul_path,
208 .interp_path = "/lib/libc.so.1",
209 .sysvec = &svr4_sysvec,
210 .interp_newpath = NULL,
211 .brand_note = NULL,
212 .flags = 0
213 };
214
215 static int
216 svr4_fixup(register_t **stack_base, struct image_params *imgp)
217 {
218 Elf32_Auxargs *args;
219 register_t *pos;
220
221 KASSERT(curthread->td_proc == imgp->proc,
222 ("unsafe svr4_fixup(), should be curproc"));
223 args = (Elf32_Auxargs *)imgp->auxargs;
224 pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
225
226 if (args->execfd != -1)
227 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
228 AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
229 AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
230 AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
231 AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
232 AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
233 AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
234 AUXARGS_ENTRY(pos, AT_BASE, args->base);
235 AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
236 AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
237 AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
238 AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
239 AUXARGS_ENTRY(pos, AT_NULL, 0);
240
241 free(imgp->auxargs, M_TEMP);
242 imgp->auxargs = NULL;
243
244 (*stack_base)--;
245 **stack_base = (register_t)imgp->args->argc;
246 return 0;
247 }
248
249 /*
250 * Search an alternate path before passing pathname arguments on
251 * to system calls. Useful for keeping a separate 'emulation tree'.
252 *
253 * If cflag is set, we check if an attempt can be made to create
254 * the named file, i.e. we check if the directory it should
255 * be in exists.
256 */
257 int
258 svr4_emul_find(struct thread *td, char *path, enum uio_seg pathseg,
259 char **pbuf, int create)
260 {
261
262 return (kern_alternate_path(td, svr4_emul_path, path, pathseg, pbuf,
263 create, AT_FDCWD));
264 }
265
266 static int
267 svr4_elf_modevent(module_t mod, int type, void *data)
268 {
269 int error;
270
271 error = 0;
272
273 switch(type) {
274 case MOD_LOAD:
275 if (elf32_insert_brand_entry(&svr4_brand) < 0) {
276 printf("cannot insert svr4 elf brand handler\n");
277 error = EINVAL;
278 break;
279 }
280 if (bootverbose)
281 printf("svr4 ELF exec handler installed\n");
282 svr4_sockcache_init();
283 break;
284 case MOD_UNLOAD:
285 /* Only allow the emulator to be removed if it isn't in use. */
286 if (elf32_brand_inuse(&svr4_brand) != 0) {
287 error = EBUSY;
288 } else if (elf32_remove_brand_entry(&svr4_brand) < 0) {
289 error = EINVAL;
290 }
291
292 if (error) {
293 printf("Could not deinstall ELF interpreter entry (error %d)\n",
294 error);
295 break;
296 }
297 if (bootverbose)
298 printf("svr4 ELF exec handler removed\n");
299 svr4_sockcache_destroy();
300 break;
301 default:
302 return (EOPNOTSUPP);
303 break;
304 }
305 return error;
306 }
307
308 static moduledata_t svr4_elf_mod = {
309 "svr4elf",
310 svr4_elf_modevent,
311 0
312 };
313 DECLARE_MODULE_TIED(svr4elf, svr4_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
314 MODULE_DEPEND(svr4elf, streams, 1, 1, 1);
Cache object: 0691938a02ad9bb293c32d7d824230a9
|