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$");
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_errsize	= ELAST,  /* ELAST */
171183322Skib	.sv_errtbl	= bsd_to_svr4_errno,
172183322Skib	.sv_transtrap	= NULL,
173183322Skib	.sv_fixup	= svr4_fixup,
174183322Skib	.sv_sendsig	= svr4_sendsig,
175183322Skib	.sv_sigcode	= svr4_sigcode,
176183322Skib	.sv_szsigcode	= &svr4_szsigcode,
177183322Skib	.sv_name	= "SVR4",
178183322Skib	.sv_coredump	= elf32_coredump,
179183322Skib	.sv_imgact_try	= NULL,
180183322Skib	.sv_minsigstksz	= SVR4_MINSIGSTKSZ,
181183322Skib	.sv_pagesize	= PAGE_SIZE,
182183322Skib	.sv_minuser	= VM_MIN_ADDRESS,
183183322Skib	.sv_maxuser	= VM_MAXUSER_ADDRESS,
184183322Skib	.sv_usrstack	= USRSTACK,
185183322Skib	.sv_psstrings	= PS_STRINGS,
186183322Skib	.sv_stackprot	= VM_PROT_ALL,
187183322Skib	.sv_copyout_strings = exec_copyout_strings,
188183322Skib	.sv_setregs	= exec_setregs,
189183322Skib	.sv_fixlimit	= NULL,
190185169Skib	.sv_maxssiz     = NULL,
191208453Skib	.sv_flags	= SV_ABI_UNDEF | SV_IA32 | SV_ILP32,
192208453Skib	.sv_set_syscall_retval = cpu_set_syscall_retval,
193208453Skib	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
194208453Skib	.sv_syscallnames = NULL,
195219405Sdchagin	.sv_schedtail	= NULL,
196283382Sdchagin	.sv_thread_detach = NULL,
197293613Sdchagin	.sv_trap	= NULL,
19843412Snewton};
19943412Snewton
200141486Sjhbconst char      svr4_emul_path[] = "/compat/svr4";
201141486Sjhb
20243412SnewtonElf32_Brandinfo svr4_brand = {
203183322Skib	.brand		= ELFOSABI_SYSV,
204183322Skib	.machine	= EM_386, /* XXX only implemented for x86 so far. */
205183322Skib	.compat_3_brand	= "SVR4",
206183322Skib	.emul_path	= svr4_emul_path,
207183322Skib	.interp_path	= "/lib/libc.so.1",
208183322Skib	.sysvec		= &svr4_sysvec,
209183322Skib	.interp_newpath	= NULL,
210189771Sdchagin	.brand_note	= NULL,
211183322Skib	.flags		= 0
21243412Snewton};
21343412Snewton
21443412Snewtonstatic int
21559342Sobriensvr4_fixup(register_t **stack_base, struct image_params *imgp)
21643412Snewton{
217112470Sjhb	Elf32_Auxargs *args;
21859342Sobrien	register_t *pos;
21943412Snewton
220177127Sjeff	KASSERT(curthread->td_proc == imgp->proc,
221112470Sjhb	    ("unsafe svr4_fixup(), should be curproc"));
222112470Sjhb	args = (Elf32_Auxargs *)imgp->auxargs;
223140992Ssobomax	pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
22443412Snewton
225112470Sjhb	if (args->execfd != -1)
22643412Snewton		AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
22743412Snewton	AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
22843412Snewton	AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
22943412Snewton	AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
23043412Snewton	AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
23143412Snewton	AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
23243412Snewton	AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
23343412Snewton	AUXARGS_ENTRY(pos, AT_BASE, args->base);
23477183Srwatson	AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
23577183Srwatson	AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
23677183Srwatson	AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
23777183Srwatson	AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
23843412Snewton	AUXARGS_ENTRY(pos, AT_NULL, 0);
23943412Snewton
24043412Snewton	free(imgp->auxargs, M_TEMP);
24143412Snewton	imgp->auxargs = NULL;
24243412Snewton
24343412Snewton	(*stack_base)--;
244140992Ssobomax	**stack_base = (register_t)imgp->args->argc;
24543412Snewton	return 0;
24643412Snewton}
24743412Snewton
24843412Snewton/*
24943412Snewton * Search an alternate path before passing pathname arguments on
25072091Sasmodai * to system calls. Useful for keeping a separate 'emulation tree'.
25143412Snewton *
25243412Snewton * If cflag is set, we check if an attempt can be made to create
25343412Snewton * the named file, i.e. we check if the directory it should
25443412Snewton * be in exists.
25543412Snewton */
25643412Snewtonint
257141486Sjhbsvr4_emul_find(struct thread *td, char *path, enum uio_seg pathseg,
258141486Sjhb    char **pbuf, int create)
25943412Snewton{
26043412Snewton
261141486Sjhb	return (kern_alternate_path(td, svr4_emul_path, path, pathseg, pbuf,
262177997Skib	    create, AT_FDCWD));
26343412Snewton}
26443412Snewton
26543412Snewtonstatic int
26643412Snewtonsvr4_elf_modevent(module_t mod, int type, void *data)
26743412Snewton{
26843412Snewton	int error;
26943412Snewton
27043412Snewton	error = 0;
27143412Snewton
27243412Snewton	switch(type) {
27343412Snewton	case MOD_LOAD:
274160558Sjhb		if (elf32_insert_brand_entry(&svr4_brand) < 0) {
275160558Sjhb			printf("cannot insert svr4 elf brand handler\n");
27643412Snewton			error = EINVAL;
277160558Sjhb			break;
278160558Sjhb		}
279160558Sjhb		if (bootverbose)
28043412Snewton			printf("svr4 ELF exec handler installed\n");
281160558Sjhb		svr4_sockcache_init();
28243412Snewton		break;
28343412Snewton	case MOD_UNLOAD:
28443597Snewton		/* Only allow the emulator to be removed if it isn't in use. */
285100384Speter		if (elf32_brand_inuse(&svr4_brand) != 0) {
28643597Snewton			error = EBUSY;
287100384Speter		} else if (elf32_remove_brand_entry(&svr4_brand) < 0) {
28843412Snewton			error = EINVAL;
28943597Snewton		}
29043597Snewton
291160558Sjhb		if (error) {
29243597Snewton			printf("Could not deinstall ELF interpreter entry (error %d)\n",
29343597Snewton			       error);
294160558Sjhb			break;
295160558Sjhb		}
296160558Sjhb		if (bootverbose)
29743412Snewton			printf("svr4 ELF exec handler removed\n");
298160558Sjhb		svr4_sockcache_destroy();
29943412Snewton		break;
30043412Snewton	default:
301132199Sphk		return (EOPNOTSUPP);
30243412Snewton		break;
30343412Snewton	}
30443412Snewton	return error;
30543412Snewton}
30643412Snewton
30743412Snewtonstatic moduledata_t svr4_elf_mod = {
30843412Snewton	"svr4elf",
30943412Snewton	svr4_elf_modevent,
310241394Skevlo	0
31143412Snewton};
312213716SkibDECLARE_MODULE_TIED(svr4elf, svr4_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
313298519SdchaginMODULE_VERSION(svr4elf, 1);
314