svr4_sysvec.c revision 241394
1139743Simp/*-
249267Snewton * Copyright (c) 1998 Mark Newton
349267Snewton * All rights reserved.
449267Snewton *
549267Snewton * Redistribution and use in source and binary forms, with or without
649267Snewton * modification, are permitted provided that the following conditions
749267Snewton * are met:
849267Snewton * 1. Redistributions of source code must retain the above copyright
949267Snewton *    notice, this list of conditions and the following disclaimer.
1049267Snewton * 2. Redistributions in binary form must reproduce the above copyright
1149267Snewton *    notice, this list of conditions and the following disclaimer in the
1249267Snewton *    documentation and/or other materials provided with the distribution.
1349267Snewton * 3. All advertising materials mentioning features or use of this software
1449267Snewton *    must display the following acknowledgement:
1549267Snewton *      This product includes software developed by Christos Zoulas.
1649267Snewton * 4. The name of the author may not be used to endorse or promote products
1749267Snewton *    derived from this software without specific prior written permission.
1849267Snewton *
1949267Snewton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2049267Snewton * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2149267Snewton * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2249267Snewton * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2349267Snewton * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2449267Snewton * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2549267Snewton * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2649267Snewton * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2749267Snewton * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2849267Snewton * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2949267Snewton */
3049267Snewton
31116174Sobrien#include <sys/cdefs.h>
32116174Sobrien__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_sysvec.c 241394 2012-10-10 08:36:38Z kevlo $");
33116174Sobrien
3443412Snewton/* XXX we use functions that might not exist. */
3543412Snewton#include "opt_compat.h"
3643412Snewton
3743412Snewton#include <sys/param.h>
3848503Sgreen#include <sys/systm.h>
3943412Snewton#include <sys/proc.h>
4043412Snewton#include <sys/sysent.h>
4143412Snewton#include <sys/imgact.h>
4243412Snewton#include <sys/imgact_elf.h>
43177785Skib#include <sys/fcntl.h>
4494455Sjhb#include <sys/lock.h>
4543412Snewton#include <sys/malloc.h>
46141486Sjhb#include <sys/module.h>
4794455Sjhb#include <sys/mutex.h>
4843412Snewton#include <sys/namei.h>
49141486Sjhb#include <sys/socket.h>
50141486Sjhb#include <sys/syscallsubr.h>
5143412Snewton#include <sys/vnode.h>
5243412Snewton#include <vm/vm.h>
5343412Snewton#include <sys/exec.h>
5443412Snewton#include <sys/kernel.h>
5543412Snewton#include <machine/cpu.h>
5643412Snewton#include <netinet/in.h>
5743412Snewton
5865302Sobrien#include <compat/svr4/svr4.h>
5965302Sobrien#include <compat/svr4/svr4_types.h>
6065302Sobrien#include <compat/svr4/svr4_syscall.h>
6165302Sobrien#include <compat/svr4/svr4_signal.h>
62160558Sjhb#include <compat/svr4/svr4_socket.h>
6365302Sobrien#include <compat/svr4/svr4_sockio.h>
6465302Sobrien#include <compat/svr4/svr4_errno.h>
6565302Sobrien#include <compat/svr4/svr4_proto.h>
6665302Sobrien#include <compat/svr4/svr4_siginfo.h>
6765302Sobrien#include <compat/svr4/svr4_util.h>
6843412Snewton
6943412Snewtonint bsd_to_svr4_errno[ELAST+1] = {
7043412Snewton        0,
7143412Snewton        SVR4_EPERM,
7243412Snewton        SVR4_ENOENT,
7343412Snewton        SVR4_ESRCH,
7443412Snewton        SVR4_EINTR,
7543412Snewton        SVR4_EIO,
7643412Snewton        SVR4_ENXIO,
7743412Snewton        SVR4_E2BIG,
7843412Snewton        SVR4_ENOEXEC,
7943412Snewton        SVR4_EBADF,
8043412Snewton        SVR4_ECHILD,
8143412Snewton        SVR4_EDEADLK,
8243412Snewton        SVR4_ENOMEM,
8343412Snewton        SVR4_EACCES,
8443412Snewton        SVR4_EFAULT,
8543412Snewton        SVR4_ENOTBLK,
8643412Snewton        SVR4_EBUSY,
8743412Snewton        SVR4_EEXIST,
8843412Snewton        SVR4_EXDEV,
8943412Snewton        SVR4_ENODEV,
9043412Snewton        SVR4_ENOTDIR,
9143412Snewton        SVR4_EISDIR,
9243412Snewton        SVR4_EINVAL,
9343412Snewton        SVR4_ENFILE,
9443412Snewton        SVR4_EMFILE,
9543412Snewton        SVR4_ENOTTY,
9643412Snewton        SVR4_ETXTBSY,
9743412Snewton        SVR4_EFBIG,
9843412Snewton        SVR4_ENOSPC,
9943412Snewton        SVR4_ESPIPE,
10043412Snewton        SVR4_EROFS,
10143412Snewton        SVR4_EMLINK,
10243412Snewton        SVR4_EPIPE,
10343412Snewton        SVR4_EDOM,
10443412Snewton        SVR4_ERANGE,
10543412Snewton        SVR4_EAGAIN,
10643412Snewton        SVR4_EINPROGRESS,
10743412Snewton        SVR4_EALREADY,
10843412Snewton        SVR4_ENOTSOCK,
10943412Snewton        SVR4_EDESTADDRREQ,
11043412Snewton        SVR4_EMSGSIZE,
11143412Snewton        SVR4_EPROTOTYPE,
11243412Snewton        SVR4_ENOPROTOOPT,
11343412Snewton        SVR4_EPROTONOSUPPORT,
11443412Snewton        SVR4_ESOCKTNOSUPPORT,
11543412Snewton        SVR4_EOPNOTSUPP,
11643412Snewton        SVR4_EPFNOSUPPORT,
11743412Snewton        SVR4_EAFNOSUPPORT,
11843412Snewton        SVR4_EADDRINUSE,
11943412Snewton        SVR4_EADDRNOTAVAIL,
12043412Snewton        SVR4_ENETDOWN,
12143412Snewton        SVR4_ENETUNREACH,
12243412Snewton        SVR4_ENETRESET,
12343412Snewton        SVR4_ECONNABORTED,
12443412Snewton        SVR4_ECONNRESET,
12543412Snewton        SVR4_ENOBUFS,
12643412Snewton        SVR4_EISCONN,
12743412Snewton        SVR4_ENOTCONN,
12843412Snewton        SVR4_ESHUTDOWN,
12943412Snewton        SVR4_ETOOMANYREFS,
13043412Snewton        SVR4_ETIMEDOUT,
13143412Snewton        SVR4_ECONNREFUSED,
13243412Snewton        SVR4_ELOOP,
13343412Snewton        SVR4_ENAMETOOLONG,
13443412Snewton        SVR4_EHOSTDOWN,
13543412Snewton        SVR4_EHOSTUNREACH,
13643412Snewton        SVR4_ENOTEMPTY,
13743412Snewton        SVR4_EPROCLIM,
13843412Snewton        SVR4_EUSERS,
13943412Snewton        SVR4_EDQUOT,
14043412Snewton        SVR4_ESTALE,
14143412Snewton        SVR4_EREMOTE,
14243412Snewton        SVR4_EBADRPC,
14343412Snewton        SVR4_ERPCMISMATCH,
14443412Snewton        SVR4_EPROGUNAVAIL,
14543412Snewton        SVR4_EPROGMISMATCH,
14643412Snewton        SVR4_EPROCUNAVAIL,
14743412Snewton        SVR4_ENOLCK,
14843412Snewton        SVR4_ENOSYS,
14943412Snewton        SVR4_EFTYPE,
15043412Snewton        SVR4_EAUTH,
15143412Snewton        SVR4_ENEEDAUTH,
15243412Snewton        SVR4_EIDRM,
15343412Snewton        SVR4_ENOMSG,
15443412Snewton};
15543412Snewton
15643412Snewton
15759342Sobrienstatic int 	svr4_fixup(register_t **stack_base, struct image_params *imgp);
15843412Snewton
15943412Snewtonextern struct sysent svr4_sysent[];
16043412Snewton#undef szsigcode
16143412Snewton#undef sigcode
16243412Snewton
16343412Snewtonextern int svr4_szsigcode;
16443412Snewtonextern char svr4_sigcode[];
16543412Snewton
16643412Snewtonstruct sysentvec svr4_sysvec = {
167183322Skib	.sv_size	= SVR4_SYS_MAXSYSCALL,
168183322Skib	.sv_table	= svr4_sysent,
169183322Skib	.sv_mask	= 0xff,
170183322Skib	.sv_sigsize	= SVR4_NSIG-1, /* NB: signal trans table indexed with signno-1 */
171183322Skib	.sv_sigtbl	= bsd_to_svr4_sig+1,
172183322Skib	.sv_errsize	= ELAST,  /* ELAST */
173183322Skib	.sv_errtbl	= bsd_to_svr4_errno,
174183322Skib	.sv_transtrap	= NULL,
175183322Skib	.sv_fixup	= svr4_fixup,
176183322Skib	.sv_sendsig	= svr4_sendsig,
177183322Skib	.sv_sigcode	= svr4_sigcode,
178183322Skib	.sv_szsigcode	= &svr4_szsigcode,
179183322Skib	.sv_prepsyscall	= NULL,
180183322Skib	.sv_name	= "SVR4",
181183322Skib	.sv_coredump	= elf32_coredump,
182183322Skib	.sv_imgact_try	= NULL,
183183322Skib	.sv_minsigstksz	= SVR4_MINSIGSTKSZ,
184183322Skib	.sv_pagesize	= PAGE_SIZE,
185183322Skib	.sv_minuser	= VM_MIN_ADDRESS,
186183322Skib	.sv_maxuser	= VM_MAXUSER_ADDRESS,
187183322Skib	.sv_usrstack	= USRSTACK,
188183322Skib	.sv_psstrings	= PS_STRINGS,
189183322Skib	.sv_stackprot	= VM_PROT_ALL,
190183322Skib	.sv_copyout_strings = exec_copyout_strings,
191183322Skib	.sv_setregs	= exec_setregs,
192183322Skib	.sv_fixlimit	= NULL,
193185169Skib	.sv_maxssiz     = NULL,
194208453Skib	.sv_flags	= SV_ABI_UNDEF | SV_IA32 | SV_ILP32,
195208453Skib	.sv_set_syscall_retval = cpu_set_syscall_retval,
196208453Skib	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
197208453Skib	.sv_syscallnames = NULL,
198219405Sdchagin	.sv_schedtail	= NULL,
19943412Snewton};
20043412Snewton
201141486Sjhbconst char      svr4_emul_path[] = "/compat/svr4";
202141486Sjhb
20343412SnewtonElf32_Brandinfo svr4_brand = {
204183322Skib	.brand		= ELFOSABI_SYSV,
205183322Skib	.machine	= EM_386, /* XXX only implemented for x86 so far. */
206183322Skib	.compat_3_brand	= "SVR4",
207183322Skib	.emul_path	= svr4_emul_path,
208183322Skib	.interp_path	= "/lib/libc.so.1",
209183322Skib	.sysvec		= &svr4_sysvec,
210183322Skib	.interp_newpath	= NULL,
211189771Sdchagin	.brand_note	= NULL,
212183322Skib	.flags		= 0
21343412Snewton};
21443412Snewton
21543412Snewtonstatic int
21659342Sobriensvr4_fixup(register_t **stack_base, struct image_params *imgp)
21743412Snewton{
218112470Sjhb	Elf32_Auxargs *args;
21959342Sobrien	register_t *pos;
22043412Snewton
221177127Sjeff	KASSERT(curthread->td_proc == imgp->proc,
222112470Sjhb	    ("unsafe svr4_fixup(), should be curproc"));
223112470Sjhb	args = (Elf32_Auxargs *)imgp->auxargs;
224140992Ssobomax	pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
22543412Snewton
226112470Sjhb	if (args->execfd != -1)
22743412Snewton		AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
22843412Snewton	AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
22943412Snewton	AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
23043412Snewton	AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
23143412Snewton	AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
23243412Snewton	AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
23343412Snewton	AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
23443412Snewton	AUXARGS_ENTRY(pos, AT_BASE, args->base);
23577183Srwatson	AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
23677183Srwatson	AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
23777183Srwatson	AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
23877183Srwatson	AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
23943412Snewton	AUXARGS_ENTRY(pos, AT_NULL, 0);
24043412Snewton
24143412Snewton	free(imgp->auxargs, M_TEMP);
24243412Snewton	imgp->auxargs = NULL;
24343412Snewton
24443412Snewton	(*stack_base)--;
245140992Ssobomax	**stack_base = (register_t)imgp->args->argc;
24643412Snewton	return 0;
24743412Snewton}
24843412Snewton
24943412Snewton/*
25043412Snewton * Search an alternate path before passing pathname arguments on
25172091Sasmodai * to system calls. Useful for keeping a separate 'emulation tree'.
25243412Snewton *
25343412Snewton * If cflag is set, we check if an attempt can be made to create
25443412Snewton * the named file, i.e. we check if the directory it should
25543412Snewton * be in exists.
25643412Snewton */
25743412Snewtonint
258141486Sjhbsvr4_emul_find(struct thread *td, char *path, enum uio_seg pathseg,
259141486Sjhb    char **pbuf, int create)
26043412Snewton{
26143412Snewton
262141486Sjhb	return (kern_alternate_path(td, svr4_emul_path, path, pathseg, pbuf,
263177997Skib	    create, AT_FDCWD));
26443412Snewton}
26543412Snewton
26643412Snewtonstatic int
26743412Snewtonsvr4_elf_modevent(module_t mod, int type, void *data)
26843412Snewton{
26943412Snewton	int error;
27043412Snewton
27143412Snewton	error = 0;
27243412Snewton
27343412Snewton	switch(type) {
27443412Snewton	case MOD_LOAD:
275160558Sjhb		if (elf32_insert_brand_entry(&svr4_brand) < 0) {
276160558Sjhb			printf("cannot insert svr4 elf brand handler\n");
27743412Snewton			error = EINVAL;
278160558Sjhb			break;
279160558Sjhb		}
280160558Sjhb		if (bootverbose)
28143412Snewton			printf("svr4 ELF exec handler installed\n");
282160558Sjhb		svr4_sockcache_init();
28343412Snewton		break;
28443412Snewton	case MOD_UNLOAD:
28543597Snewton		/* Only allow the emulator to be removed if it isn't in use. */
286100384Speter		if (elf32_brand_inuse(&svr4_brand) != 0) {
28743597Snewton			error = EBUSY;
288100384Speter		} else if (elf32_remove_brand_entry(&svr4_brand) < 0) {
28943412Snewton			error = EINVAL;
29043597Snewton		}
29143597Snewton
292160558Sjhb		if (error) {
29343597Snewton			printf("Could not deinstall ELF interpreter entry (error %d)\n",
29443597Snewton			       error);
295160558Sjhb			break;
296160558Sjhb		}
297160558Sjhb		if (bootverbose)
29843412Snewton			printf("svr4 ELF exec handler removed\n");
299160558Sjhb		svr4_sockcache_destroy();
30043412Snewton		break;
30143412Snewton	default:
302132199Sphk		return (EOPNOTSUPP);
30343412Snewton		break;
30443412Snewton	}
30543412Snewton	return error;
30643412Snewton}
30743412Snewton
30843412Snewtonstatic moduledata_t svr4_elf_mod = {
30943412Snewton	"svr4elf",
31043412Snewton	svr4_elf_modevent,
311241394Skevlo	0
31243412Snewton};
313213716SkibDECLARE_MODULE_TIED(svr4elf, svr4_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
31460060SgreenMODULE_DEPEND(svr4elf, streams, 1, 1, 1);
315