svr4_sysvec.c revision 185169
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 185169 2008-11-22 12:36:15Z kib $"); 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, 194185169Skib .sv_flags = SV_ABI_UNDEF | SV_IA32 | SV_ILP32 19543412Snewton}; 19643412Snewton 197141486Sjhbconst char svr4_emul_path[] = "/compat/svr4"; 198141486Sjhb 19943412SnewtonElf32_Brandinfo svr4_brand = { 200183322Skib .brand = ELFOSABI_SYSV, 201183322Skib .machine = EM_386, /* XXX only implemented for x86 so far. */ 202183322Skib .compat_3_brand = "SVR4", 203183322Skib .emul_path = svr4_emul_path, 204183322Skib .interp_path = "/lib/libc.so.1", 205183322Skib .sysvec = &svr4_sysvec, 206183322Skib .interp_newpath = NULL, 207183322Skib .flags = 0 20843412Snewton}; 20943412Snewton 21043412Snewtonstatic int 21159342Sobriensvr4_fixup(register_t **stack_base, struct image_params *imgp) 21243412Snewton{ 213112470Sjhb Elf32_Auxargs *args; 21459342Sobrien register_t *pos; 21543412Snewton 216177127Sjeff KASSERT(curthread->td_proc == imgp->proc, 217112470Sjhb ("unsafe svr4_fixup(), should be curproc")); 218112470Sjhb args = (Elf32_Auxargs *)imgp->auxargs; 219140992Ssobomax pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2); 22043412Snewton 221112470Sjhb if (args->trace) 22243412Snewton AUXARGS_ENTRY(pos, AT_DEBUG, 1); 223112470Sjhb if (args->execfd != -1) 22443412Snewton AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); 22543412Snewton AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); 22643412Snewton AUXARGS_ENTRY(pos, AT_PHENT, args->phent); 22743412Snewton AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); 22843412Snewton AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); 22943412Snewton AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); 23043412Snewton AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); 23143412Snewton AUXARGS_ENTRY(pos, AT_BASE, args->base); 23277183Srwatson AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid); 23377183Srwatson AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); 23477183Srwatson AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); 23577183Srwatson AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); 23643412Snewton AUXARGS_ENTRY(pos, AT_NULL, 0); 23743412Snewton 23843412Snewton free(imgp->auxargs, M_TEMP); 23943412Snewton imgp->auxargs = NULL; 24043412Snewton 24143412Snewton (*stack_base)--; 242140992Ssobomax **stack_base = (register_t)imgp->args->argc; 24343412Snewton return 0; 24443412Snewton} 24543412Snewton 24643412Snewton/* 24743412Snewton * Search an alternate path before passing pathname arguments on 24872091Sasmodai * to system calls. Useful for keeping a separate 'emulation tree'. 24943412Snewton * 25043412Snewton * If cflag is set, we check if an attempt can be made to create 25143412Snewton * the named file, i.e. we check if the directory it should 25243412Snewton * be in exists. 25343412Snewton */ 25443412Snewtonint 255141486Sjhbsvr4_emul_find(struct thread *td, char *path, enum uio_seg pathseg, 256141486Sjhb char **pbuf, int create) 25743412Snewton{ 25843412Snewton 259141486Sjhb return (kern_alternate_path(td, svr4_emul_path, path, pathseg, pbuf, 260177997Skib create, AT_FDCWD)); 26143412Snewton} 26243412Snewton 26343412Snewtonstatic int 26443412Snewtonsvr4_elf_modevent(module_t mod, int type, void *data) 26543412Snewton{ 26643412Snewton int error; 26743412Snewton 26843412Snewton error = 0; 26943412Snewton 27043412Snewton switch(type) { 27143412Snewton case MOD_LOAD: 272160558Sjhb if (elf32_insert_brand_entry(&svr4_brand) < 0) { 273160558Sjhb printf("cannot insert svr4 elf brand handler\n"); 27443412Snewton error = EINVAL; 275160558Sjhb break; 276160558Sjhb } 277160558Sjhb if (bootverbose) 27843412Snewton printf("svr4 ELF exec handler installed\n"); 279160558Sjhb svr4_sockcache_init(); 28043412Snewton break; 28143412Snewton case MOD_UNLOAD: 28243597Snewton /* Only allow the emulator to be removed if it isn't in use. */ 283100384Speter if (elf32_brand_inuse(&svr4_brand) != 0) { 28443597Snewton error = EBUSY; 285100384Speter } else if (elf32_remove_brand_entry(&svr4_brand) < 0) { 28643412Snewton error = EINVAL; 28743597Snewton } 28843597Snewton 289160558Sjhb if (error) { 29043597Snewton printf("Could not deinstall ELF interpreter entry (error %d)\n", 29143597Snewton error); 292160558Sjhb break; 293160558Sjhb } 294160558Sjhb if (bootverbose) 29543412Snewton printf("svr4 ELF exec handler removed\n"); 296160558Sjhb svr4_sockcache_destroy(); 29743412Snewton break; 29843412Snewton default: 299132199Sphk return (EOPNOTSUPP); 30043412Snewton break; 30143412Snewton } 30243412Snewton return error; 30343412Snewton} 30443412Snewton 30543412Snewtonstatic moduledata_t svr4_elf_mod = { 30643412Snewton "svr4elf", 30743412Snewton svr4_elf_modevent, 30843412Snewton 0 30943412Snewton}; 31043412SnewtonDECLARE_MODULE(svr4elf, svr4_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY); 31160060SgreenMODULE_DEPEND(svr4elf, streams, 1, 1, 1); 312