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: releng/11.1/sys/compat/svr4/svr4_sysvec.c 298519 2016-04-23 20:29:55Z dchagin $");
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_errsize = ELAST, /* ELAST */
171 .sv_errtbl = bsd_to_svr4_errno,
172 .sv_transtrap = NULL,
173 .sv_fixup = svr4_fixup,
174 .sv_sendsig = svr4_sendsig,
175 .sv_sigcode = svr4_sigcode,
176 .sv_szsigcode = &svr4_szsigcode,
177 .sv_name = "SVR4",
178 .sv_coredump = elf32_coredump,
179 .sv_imgact_try = NULL,
180 .sv_minsigstksz = SVR4_MINSIGSTKSZ,
181 .sv_pagesize = PAGE_SIZE,
182 .sv_minuser = VM_MIN_ADDRESS,
183 .sv_maxuser = VM_MAXUSER_ADDRESS,
184 .sv_usrstack = USRSTACK,
185 .sv_psstrings = PS_STRINGS,
186 .sv_stackprot = VM_PROT_ALL,
187 .sv_copyout_strings = exec_copyout_strings,
188 .sv_setregs = exec_setregs,
189 .sv_fixlimit = NULL,
190 .sv_maxssiz = NULL,
191 .sv_flags = SV_ABI_UNDEF | SV_IA32 | SV_ILP32,
192 .sv_set_syscall_retval = cpu_set_syscall_retval,
193 .sv_fetch_syscall_args = cpu_fetch_syscall_args,
194 .sv_syscallnames = NULL,
195 .sv_schedtail = NULL,
196 .sv_thread_detach = NULL,
197 .sv_trap = NULL,
198 };
199
200 const char svr4_emul_path[] = "/compat/svr4";
201
202 Elf32_Brandinfo svr4_brand = {
203 .brand = ELFOSABI_SYSV,
204 .machine = EM_386, /* XXX only implemented for x86 so far. */
205 .compat_3_brand = "SVR4",
206 .emul_path = svr4_emul_path,
207 .interp_path = "/lib/libc.so.1",
208 .sysvec = &svr4_sysvec,
209 .interp_newpath = NULL,
210 .brand_note = NULL,
211 .flags = 0
212 };
213
214 static int
215 svr4_fixup(register_t **stack_base, struct image_params *imgp)
216 {
217 Elf32_Auxargs *args;
218 register_t *pos;
219
220 KASSERT(curthread->td_proc == imgp->proc,
221 ("unsafe svr4_fixup(), should be curproc"));
222 args = (Elf32_Auxargs *)imgp->auxargs;
223 pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
224
225 if (args->execfd != -1)
226 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
227 AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
228 AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
229 AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
230 AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
231 AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
232 AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
233 AUXARGS_ENTRY(pos, AT_BASE, args->base);
234 AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
235 AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
236 AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
237 AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
238 AUXARGS_ENTRY(pos, AT_NULL, 0);
239
240 free(imgp->auxargs, M_TEMP);
241 imgp->auxargs = NULL;
242
243 (*stack_base)--;
244 **stack_base = (register_t)imgp->args->argc;
245 return 0;
246 }
247
248 /*
249 * Search an alternate path before passing pathname arguments on
250 * to system calls. Useful for keeping a separate 'emulation tree'.
251 *
252 * If cflag is set, we check if an attempt can be made to create
253 * the named file, i.e. we check if the directory it should
254 * be in exists.
255 */
256 int
257 svr4_emul_find(struct thread *td, char *path, enum uio_seg pathseg,
258 char **pbuf, int create)
259 {
260
261 return (kern_alternate_path(td, svr4_emul_path, path, pathseg, pbuf,
262 create, AT_FDCWD));
263 }
264
265 static int
266 svr4_elf_modevent(module_t mod, int type, void *data)
267 {
268 int error;
269
270 error = 0;
271
272 switch(type) {
273 case MOD_LOAD:
274 if (elf32_insert_brand_entry(&svr4_brand) < 0) {
275 printf("cannot insert svr4 elf brand handler\n");
276 error = EINVAL;
277 break;
278 }
279 if (bootverbose)
280 printf("svr4 ELF exec handler installed\n");
281 svr4_sockcache_init();
282 break;
283 case MOD_UNLOAD:
284 /* Only allow the emulator to be removed if it isn't in use. */
285 if (elf32_brand_inuse(&svr4_brand) != 0) {
286 error = EBUSY;
287 } else if (elf32_remove_brand_entry(&svr4_brand) < 0) {
288 error = EINVAL;
289 }
290
291 if (error) {
292 printf("Could not deinstall ELF interpreter entry (error %d)\n",
293 error);
294 break;
295 }
296 if (bootverbose)
297 printf("svr4 ELF exec handler removed\n");
298 svr4_sockcache_destroy();
299 break;
300 default:
301 return (EOPNOTSUPP);
302 break;
303 }
304 return error;
305 }
306
307 static moduledata_t svr4_elf_mod = {
308 "svr4elf",
309 svr4_elf_modevent,
310 0
311 };
312 DECLARE_MODULE_TIED(svr4elf, svr4_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
313 MODULE_VERSION(svr4elf, 1);
Cache object: 7c2b99ba01f0506597e6f77571ca9e18
|