svr4_sysvec.c revision 141486
1260684Skaiw/*-
2260684Skaiw * Copyright (c) 1998 Mark Newton
3260684Skaiw * All rights reserved.
4260684Skaiw *
5260684Skaiw * Redistribution and use in source and binary forms, with or without
6260684Skaiw * modification, are permitted provided that the following conditions
7260684Skaiw * are met:
8260684Skaiw * 1. Redistributions of source code must retain the above copyright
9260684Skaiw *    notice, this list of conditions and the following disclaimer.
10260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright
11260684Skaiw *    notice, this list of conditions and the following disclaimer in the
12260684Skaiw *    documentation and/or other materials provided with the distribution.
13260684Skaiw * 3. All advertising materials mentioning features or use of this software
14260684Skaiw *    must display the following acknowledgement:
15260684Skaiw *      This product includes software developed by Christos Zoulas.
16260684Skaiw * 4. The name of the author may not be used to endorse or promote products
17260684Skaiw *    derived from this software without specific prior written permission.
18260684Skaiw *
19260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20260684Skaiw * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21260684Skaiw * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22260684Skaiw * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23260684Skaiw * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24260684Skaiw * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25260684Skaiw * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26260684Skaiw * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27260684Skaiw * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28260684Skaiw * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29260684Skaiw */
30260684Skaiw
31260684Skaiw#include <sys/cdefs.h>
32260684Skaiw__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_sysvec.c 141486 2005-02-07 21:53:42Z jhb $");
33260684Skaiw
34260684Skaiw/* XXX we use functions that might not exist. */
35260684Skaiw#include "opt_compat.h"
36260684Skaiw
37260684Skaiw#ifndef COMPAT_43
38260684Skaiw#error "Unable to compile SVR4-emulator due to missing COMPAT_43 option!"
39260684Skaiw#endif
40260684Skaiw
41260684Skaiw#include <sys/param.h>
42260684Skaiw#include <sys/systm.h>
43260684Skaiw#include <sys/proc.h>
44260684Skaiw#include <sys/sysent.h>
45260684Skaiw#include <sys/imgact.h>
46260684Skaiw#include <sys/imgact_elf.h>
47260684Skaiw#include <sys/lock.h>
48260684Skaiw#include <sys/malloc.h>
49260684Skaiw#include <sys/module.h>
50260684Skaiw#include <sys/mutex.h>
51260684Skaiw#include <sys/namei.h>
52260684Skaiw#include <sys/socket.h>
53260684Skaiw#include <sys/syscallsubr.h>
54260684Skaiw#include <sys/vnode.h>
55260684Skaiw#include <vm/vm.h>
56260684Skaiw#include <sys/exec.h>
57260684Skaiw#include <sys/kernel.h>
58260684Skaiw#include <machine/cpu.h>
59260684Skaiw#include <netinet/in.h>
60260684Skaiw
61260684Skaiw#include <compat/svr4/svr4.h>
62260684Skaiw#include <compat/svr4/svr4_types.h>
63260684Skaiw#include <compat/svr4/svr4_syscall.h>
64260684Skaiw#include <compat/svr4/svr4_signal.h>
65260684Skaiw#include <compat/svr4/svr4_sockio.h>
66#include <compat/svr4/svr4_errno.h>
67#include <compat/svr4/svr4_proto.h>
68#include <compat/svr4/svr4_siginfo.h>
69#include <compat/svr4/svr4_util.h>
70
71int bsd_to_svr4_errno[ELAST+1] = {
72        0,
73        SVR4_EPERM,
74        SVR4_ENOENT,
75        SVR4_ESRCH,
76        SVR4_EINTR,
77        SVR4_EIO,
78        SVR4_ENXIO,
79        SVR4_E2BIG,
80        SVR4_ENOEXEC,
81        SVR4_EBADF,
82        SVR4_ECHILD,
83        SVR4_EDEADLK,
84        SVR4_ENOMEM,
85        SVR4_EACCES,
86        SVR4_EFAULT,
87        SVR4_ENOTBLK,
88        SVR4_EBUSY,
89        SVR4_EEXIST,
90        SVR4_EXDEV,
91        SVR4_ENODEV,
92        SVR4_ENOTDIR,
93        SVR4_EISDIR,
94        SVR4_EINVAL,
95        SVR4_ENFILE,
96        SVR4_EMFILE,
97        SVR4_ENOTTY,
98        SVR4_ETXTBSY,
99        SVR4_EFBIG,
100        SVR4_ENOSPC,
101        SVR4_ESPIPE,
102        SVR4_EROFS,
103        SVR4_EMLINK,
104        SVR4_EPIPE,
105        SVR4_EDOM,
106        SVR4_ERANGE,
107        SVR4_EAGAIN,
108        SVR4_EINPROGRESS,
109        SVR4_EALREADY,
110        SVR4_ENOTSOCK,
111        SVR4_EDESTADDRREQ,
112        SVR4_EMSGSIZE,
113        SVR4_EPROTOTYPE,
114        SVR4_ENOPROTOOPT,
115        SVR4_EPROTONOSUPPORT,
116        SVR4_ESOCKTNOSUPPORT,
117        SVR4_EOPNOTSUPP,
118        SVR4_EPFNOSUPPORT,
119        SVR4_EAFNOSUPPORT,
120        SVR4_EADDRINUSE,
121        SVR4_EADDRNOTAVAIL,
122        SVR4_ENETDOWN,
123        SVR4_ENETUNREACH,
124        SVR4_ENETRESET,
125        SVR4_ECONNABORTED,
126        SVR4_ECONNRESET,
127        SVR4_ENOBUFS,
128        SVR4_EISCONN,
129        SVR4_ENOTCONN,
130        SVR4_ESHUTDOWN,
131        SVR4_ETOOMANYREFS,
132        SVR4_ETIMEDOUT,
133        SVR4_ECONNREFUSED,
134        SVR4_ELOOP,
135        SVR4_ENAMETOOLONG,
136        SVR4_EHOSTDOWN,
137        SVR4_EHOSTUNREACH,
138        SVR4_ENOTEMPTY,
139        SVR4_EPROCLIM,
140        SVR4_EUSERS,
141        SVR4_EDQUOT,
142        SVR4_ESTALE,
143        SVR4_EREMOTE,
144        SVR4_EBADRPC,
145        SVR4_ERPCMISMATCH,
146        SVR4_EPROGUNAVAIL,
147        SVR4_EPROGMISMATCH,
148        SVR4_EPROCUNAVAIL,
149        SVR4_ENOLCK,
150        SVR4_ENOSYS,
151        SVR4_EFTYPE,
152        SVR4_EAUTH,
153        SVR4_ENEEDAUTH,
154        SVR4_EIDRM,
155        SVR4_ENOMSG,
156};
157
158
159static int 	svr4_fixup(register_t **stack_base, struct image_params *imgp);
160
161extern struct sysent svr4_sysent[];
162#undef szsigcode
163#undef sigcode
164
165extern int svr4_szsigcode;
166extern char svr4_sigcode[];
167
168struct sysentvec svr4_sysvec = {
169  SVR4_SYS_MAXSYSCALL,
170  svr4_sysent,
171  0xff,
172  SVR4_SIGTBLSZ,
173  bsd_to_svr4_sig,
174  ELAST,  /* ELAST */
175  bsd_to_svr4_errno,
176  NULL,
177  svr4_fixup,
178  svr4_sendsig,
179  svr4_sigcode,
180  &svr4_szsigcode,
181  NULL,
182  "SVR4",
183  elf32_coredump,
184  NULL,
185  SVR4_MINSIGSTKSZ,
186  PAGE_SIZE,
187  VM_MIN_ADDRESS,
188  VM_MAXUSER_ADDRESS,
189  USRSTACK,
190  PS_STRINGS,
191  VM_PROT_ALL,
192  exec_copyout_strings,
193  exec_setregs,
194  NULL
195};
196
197const char      svr4_emul_path[] = "/compat/svr4";
198
199Elf32_Brandinfo svr4_brand = {
200  ELFOSABI_SYSV,
201  EM_386,			/* XXX only implemented for x86 so far. */
202  "SVR4",
203  svr4_emul_path,
204  "/lib/libc.so.1",
205  &svr4_sysvec,
206  NULL,
207};
208
209static int
210svr4_fixup(register_t **stack_base, struct image_params *imgp)
211{
212	Elf32_Auxargs *args;
213	register_t *pos;
214
215	KASSERT(curthread->td_proc == imgp->proc &&
216	    (curthread->td_proc->p_flag & P_SA) == 0,
217	    ("unsafe svr4_fixup(), should be curproc"));
218	args = (Elf32_Auxargs *)imgp->auxargs;
219	pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
220
221	if (args->trace)
222		AUXARGS_ENTRY(pos, AT_DEBUG, 1);
223	if (args->execfd != -1)
224		AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
225	AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
226	AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
227	AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
228	AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
229	AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
230	AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
231	AUXARGS_ENTRY(pos, AT_BASE, args->base);
232	AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
233	AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
234	AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
235	AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
236	AUXARGS_ENTRY(pos, AT_NULL, 0);
237
238	free(imgp->auxargs, M_TEMP);
239	imgp->auxargs = NULL;
240
241	(*stack_base)--;
242	**stack_base = (register_t)imgp->args->argc;
243	return 0;
244}
245
246/*
247 * Search an alternate path before passing pathname arguments on
248 * to system calls. Useful for keeping a separate 'emulation tree'.
249 *
250 * If cflag is set, we check if an attempt can be made to create
251 * the named file, i.e. we check if the directory it should
252 * be in exists.
253 */
254int
255svr4_emul_find(struct thread *td, char *path, enum uio_seg pathseg,
256    char **pbuf, int create)
257{
258
259	return (kern_alternate_path(td, svr4_emul_path, path, pathseg, pbuf,
260	    create));
261}
262
263static int
264svr4_elf_modevent(module_t mod, int type, void *data)
265{
266	int error;
267
268	error = 0;
269
270	switch(type) {
271	case MOD_LOAD:
272		if (elf32_insert_brand_entry(&svr4_brand) < 0)
273			error = EINVAL;
274		if (error)
275			printf("cannot insert svr4 elf brand handler\n");
276		else if (bootverbose)
277			printf("svr4 ELF exec handler installed\n");
278		break;
279	case MOD_UNLOAD:
280		/* Only allow the emulator to be removed if it isn't in use. */
281		if (elf32_brand_inuse(&svr4_brand) != 0) {
282			error = EBUSY;
283		} else if (elf32_remove_brand_entry(&svr4_brand) < 0) {
284			error = EINVAL;
285		}
286
287		if (error)
288			printf("Could not deinstall ELF interpreter entry (error %d)\n",
289			       error);
290		else if (bootverbose)
291			printf("svr4 ELF exec handler removed\n");
292		break;
293	default:
294		return (EOPNOTSUPP);
295		break;
296	}
297	return error;
298}
299
300static moduledata_t svr4_elf_mod = {
301	"svr4elf",
302	svr4_elf_modevent,
303	0
304};
305DECLARE_MODULE(svr4elf, svr4_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
306MODULE_DEPEND(svr4elf, streams, 1, 1, 1);
307