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_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