svr4_sysvec.c revision 189771
12490Sjkh/*- 22490Sjkh * Copyright (c) 1998 Mark Newton 32490Sjkh * All rights reserved. 42490Sjkh * 52490Sjkh * Redistribution and use in source and binary forms, with or without 62490Sjkh * modification, are permitted provided that the following conditions 72490Sjkh * are met: 82490Sjkh * 1. Redistributions of source code must retain the above copyright 92490Sjkh * notice, this list of conditions and the following disclaimer. 102490Sjkh * 2. Redistributions in binary form must reproduce the above copyright 112490Sjkh * notice, this list of conditions and the following disclaimer in the 122490Sjkh * documentation and/or other materials provided with the distribution. 132490Sjkh * 3. All advertising materials mentioning features or use of this software 142490Sjkh * must display the following acknowledgement: 152490Sjkh * This product includes software developed by Christos Zoulas. 162490Sjkh * 4. The name of the author may not be used to endorse or promote products 172490Sjkh * derived from this software without specific prior written permission. 182490Sjkh * 192490Sjkh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 202490Sjkh * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 212490Sjkh * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 222490Sjkh * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 232490Sjkh * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 242490Sjkh * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 252490Sjkh * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 262490Sjkh * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 272490Sjkh * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 282490Sjkh * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 292490Sjkh */ 302490Sjkh 312490Sjkh#include <sys/cdefs.h> 322490Sjkh__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_sysvec.c 189771 2009-03-13 16:40:51Z dchagin $"); 332490Sjkh 3410352Sjoerg/* XXX we use functions that might not exist. */ 3510352Sjoerg#include "opt_compat.h" 3610352Sjoerg 3710352Sjoerg#include <sys/param.h> 3810352Sjoerg#include <sys/systm.h> 392490Sjkh#include <sys/proc.h> 402490Sjkh#include <sys/sysent.h> 412490Sjkh#include <sys/imgact.h> 422490Sjkh#include <sys/imgact_elf.h> 432490Sjkh#include <sys/fcntl.h> 442490Sjkh#include <sys/lock.h> 452490Sjkh#include <sys/malloc.h> 462490Sjkh#include <sys/module.h> 472490Sjkh#include <sys/mutex.h> 482490Sjkh#include <sys/namei.h> 492490Sjkh#include <sys/socket.h> 502490Sjkh#include <sys/syscallsubr.h> 5110352Sjoerg#include <sys/vnode.h> 5210352Sjoerg#include <vm/vm.h> 532490Sjkh#include <sys/exec.h> 5410352Sjoerg#include <sys/kernel.h> 5510352Sjoerg#include <machine/cpu.h> 5610352Sjoerg#include <netinet/in.h> 5710352Sjoerg 5810352Sjoerg#include <compat/svr4/svr4.h> 5910352Sjoerg#include <compat/svr4/svr4_types.h> 6010352Sjoerg#include <compat/svr4/svr4_syscall.h> 6110352Sjoerg#include <compat/svr4/svr4_signal.h> 622490Sjkh#include <compat/svr4/svr4_socket.h> 632490Sjkh#include <compat/svr4/svr4_sockio.h> 6410352Sjoerg#include <compat/svr4/svr4_errno.h> 652490Sjkh#include <compat/svr4/svr4_proto.h> 6610352Sjoerg#include <compat/svr4/svr4_siginfo.h> 6710352Sjoerg#include <compat/svr4/svr4_util.h> 6810352Sjoerg 6910352Sjoergint bsd_to_svr4_errno[ELAST+1] = { 7010352Sjoerg 0, 7110352Sjoerg SVR4_EPERM, 7210352Sjoerg SVR4_ENOENT, 7310352Sjoerg SVR4_ESRCH, 7410352Sjoerg SVR4_EINTR, 7510352Sjoerg SVR4_EIO, 7610352Sjoerg SVR4_ENXIO, 7710352Sjoerg SVR4_E2BIG, 7810352Sjoerg SVR4_ENOEXEC, 7910352Sjoerg SVR4_EBADF, 8010352Sjoerg SVR4_ECHILD, 8110352Sjoerg SVR4_EDEADLK, 8210352Sjoerg SVR4_ENOMEM, 8310352Sjoerg SVR4_EACCES, 8410352Sjoerg SVR4_EFAULT, 8510352Sjoerg SVR4_ENOTBLK, 8610352Sjoerg SVR4_EBUSY, 8710352Sjoerg SVR4_EEXIST, 8810352Sjoerg SVR4_EXDEV, 8910352Sjoerg SVR4_ENODEV, 9010352Sjoerg SVR4_ENOTDIR, 9110352Sjoerg SVR4_EISDIR, 9210352Sjoerg SVR4_EINVAL, 9310352Sjoerg SVR4_ENFILE, 9410352Sjoerg SVR4_EMFILE, 9510352Sjoerg SVR4_ENOTTY, 9610352Sjoerg SVR4_ETXTBSY, 9710352Sjoerg SVR4_EFBIG, 9810352Sjoerg SVR4_ENOSPC, 9910352Sjoerg SVR4_ESPIPE, 10010352Sjoerg SVR4_EROFS, 10110352Sjoerg SVR4_EMLINK, 10210352Sjoerg SVR4_EPIPE, 10310352Sjoerg SVR4_EDOM, 10410352Sjoerg SVR4_ERANGE, 10510352Sjoerg SVR4_EAGAIN, 10610352Sjoerg SVR4_EINPROGRESS, 10710352Sjoerg SVR4_EALREADY, 10810352Sjoerg SVR4_ENOTSOCK, 10910352Sjoerg SVR4_EDESTADDRREQ, 11010352Sjoerg SVR4_EMSGSIZE, 11110352Sjoerg SVR4_EPROTOTYPE, 11210352Sjoerg SVR4_ENOPROTOOPT, 11310352Sjoerg SVR4_EPROTONOSUPPORT, 11410352Sjoerg SVR4_ESOCKTNOSUPPORT, 11510352Sjoerg SVR4_EOPNOTSUPP, 11610352Sjoerg SVR4_EPFNOSUPPORT, 11710352Sjoerg SVR4_EAFNOSUPPORT, 11810352Sjoerg SVR4_EADDRINUSE, 11910352Sjoerg SVR4_EADDRNOTAVAIL, 12010352Sjoerg SVR4_ENETDOWN, 12110352Sjoerg SVR4_ENETUNREACH, 12210352Sjoerg SVR4_ENETRESET, 12310352Sjoerg SVR4_ECONNABORTED, 12410352Sjoerg SVR4_ECONNRESET, 12510352Sjoerg SVR4_ENOBUFS, 12610352Sjoerg SVR4_EISCONN, 12710352Sjoerg SVR4_ENOTCONN, 12810352Sjoerg SVR4_ESHUTDOWN, 12910352Sjoerg SVR4_ETOOMANYREFS, 13010352Sjoerg SVR4_ETIMEDOUT, 13110352Sjoerg SVR4_ECONNREFUSED, 13210352Sjoerg SVR4_ELOOP, 13310352Sjoerg SVR4_ENAMETOOLONG, 13410352Sjoerg SVR4_EHOSTDOWN, 13510352Sjoerg SVR4_EHOSTUNREACH, 13610352Sjoerg SVR4_ENOTEMPTY, 13710352Sjoerg SVR4_EPROCLIM, 13810352Sjoerg SVR4_EUSERS, 13910352Sjoerg SVR4_EDQUOT, 14010352Sjoerg SVR4_ESTALE, 14110352Sjoerg SVR4_EREMOTE, 14210352Sjoerg SVR4_EBADRPC, 14310352Sjoerg SVR4_ERPCMISMATCH, 14410352Sjoerg SVR4_EPROGUNAVAIL, 14510352Sjoerg SVR4_EPROGMISMATCH, 14610352Sjoerg SVR4_EPROCUNAVAIL, 14710352Sjoerg SVR4_ENOLCK, 14810352Sjoerg SVR4_ENOSYS, 14910352Sjoerg SVR4_EFTYPE, 15010352Sjoerg SVR4_EAUTH, 15110352Sjoerg SVR4_ENEEDAUTH, 15210352Sjoerg SVR4_EIDRM, 15310352Sjoerg SVR4_ENOMSG, 15410352Sjoerg}; 15510352Sjoerg 15610352Sjoerg 15710352Sjoergstatic int svr4_fixup(register_t **stack_base, struct image_params *imgp); 15810352Sjoerg 15910352Sjoergextern struct sysent svr4_sysent[]; 16010352Sjoerg#undef szsigcode 16110352Sjoerg#undef sigcode 16210352Sjoerg 16310352Sjoergextern int svr4_szsigcode; 16410352Sjoergextern char svr4_sigcode[]; 16510352Sjoerg 16610352Sjoergstruct sysentvec svr4_sysvec = { 16710352Sjoerg .sv_size = SVR4_SYS_MAXSYSCALL, 16810352Sjoerg .sv_table = svr4_sysent, 16910352Sjoerg .sv_mask = 0xff, 17010352Sjoerg .sv_sigsize = SVR4_NSIG-1, /* NB: signal trans table indexed with signno-1 */ 17110352Sjoerg .sv_sigtbl = bsd_to_svr4_sig+1, 17210352Sjoerg .sv_errsize = ELAST, /* ELAST */ 17310352Sjoerg .sv_errtbl = bsd_to_svr4_errno, 17410352Sjoerg .sv_transtrap = NULL, 17510352Sjoerg .sv_fixup = svr4_fixup, 17610352Sjoerg .sv_sendsig = svr4_sendsig, 17710352Sjoerg .sv_sigcode = svr4_sigcode, 17810352Sjoerg .sv_szsigcode = &svr4_szsigcode, 17910352Sjoerg .sv_prepsyscall = NULL, 18010352Sjoerg .sv_name = "SVR4", 18110352Sjoerg .sv_coredump = elf32_coredump, 18210352Sjoerg .sv_imgact_try = NULL, 18310352Sjoerg .sv_minsigstksz = SVR4_MINSIGSTKSZ, 18410352Sjoerg .sv_pagesize = PAGE_SIZE, 18510352Sjoerg .sv_minuser = VM_MIN_ADDRESS, 18610352Sjoerg .sv_maxuser = VM_MAXUSER_ADDRESS, 18710352Sjoerg .sv_usrstack = USRSTACK, 18810352Sjoerg .sv_psstrings = PS_STRINGS, 18910352Sjoerg .sv_stackprot = VM_PROT_ALL, 19010352Sjoerg .sv_copyout_strings = exec_copyout_strings, 19110352Sjoerg .sv_setregs = exec_setregs, 19210352Sjoerg .sv_fixlimit = NULL, 19310352Sjoerg .sv_maxssiz = NULL, 19410352Sjoerg .sv_flags = SV_ABI_UNDEF | SV_IA32 | SV_ILP32 19510352Sjoerg}; 19610352Sjoerg 19710352Sjoergconst char svr4_emul_path[] = "/compat/svr4"; 19810352Sjoerg 19910352SjoergElf32_Brandinfo svr4_brand = { 20010352Sjoerg .brand = ELFOSABI_SYSV, 20110352Sjoerg .machine = EM_386, /* XXX only implemented for x86 so far. */ 20210352Sjoerg .compat_3_brand = "SVR4", 20310352Sjoerg .emul_path = svr4_emul_path, 20410352Sjoerg .interp_path = "/lib/libc.so.1", 20510352Sjoerg .sysvec = &svr4_sysvec, 20610352Sjoerg .interp_newpath = NULL, 20710352Sjoerg .brand_note = NULL, 20810352Sjoerg .flags = 0 2092490Sjkh}; 21010352Sjoerg 21110352Sjoergstatic int 21210352Sjoergsvr4_fixup(register_t **stack_base, struct image_params *imgp) 21310352Sjoerg{ 2142490Sjkh Elf32_Auxargs *args; 21510352Sjoerg register_t *pos; 21610352Sjoerg 21710352Sjoerg KASSERT(curthread->td_proc == imgp->proc, 21810352Sjoerg ("unsafe svr4_fixup(), should be curproc")); 21910352Sjoerg args = (Elf32_Auxargs *)imgp->auxargs; 22010352Sjoerg pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2); 22110352Sjoerg 22210352Sjoerg if (args->execfd != -1) 2232490Sjkh AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); 2242490Sjkh AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); 2252490Sjkh AUXARGS_ENTRY(pos, AT_PHENT, args->phent); 22610352Sjoerg AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); 22710352Sjoerg AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); 22810352Sjoerg AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); 2292490Sjkh AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); 2302490Sjkh AUXARGS_ENTRY(pos, AT_BASE, args->base); 23110352Sjoerg AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid); 2322490Sjkh AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); 2332490Sjkh AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); 23410352Sjoerg AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); 23510352Sjoerg AUXARGS_ENTRY(pos, AT_NULL, 0); 23610352Sjoerg 23710352Sjoerg free(imgp->auxargs, M_TEMP); 23810352Sjoerg imgp->auxargs = NULL; 23910352Sjoerg 24010352Sjoerg (*stack_base)--; 24110352Sjoerg **stack_base = (register_t)imgp->args->argc; 24210352Sjoerg return 0; 24310352Sjoerg} 24410352Sjoerg 24510352Sjoerg/* 24610352Sjoerg * Search an alternate path before passing pathname arguments on 24710352Sjoerg * to system calls. Useful for keeping a separate 'emulation tree'. 24810352Sjoerg * 24910352Sjoerg * If cflag is set, we check if an attempt can be made to create 25010352Sjoerg * the named file, i.e. we check if the directory it should 25110352Sjoerg * be in exists. 25210352Sjoerg */ 25310352Sjoergint 25410352Sjoergsvr4_emul_find(struct thread *td, char *path, enum uio_seg pathseg, 25510352Sjoerg char **pbuf, int create) 25610352Sjoerg{ 25710352Sjoerg 25810352Sjoerg return (kern_alternate_path(td, svr4_emul_path, path, pathseg, pbuf, 2592490Sjkh create, AT_FDCWD)); 2602490Sjkh} 2612490Sjkh 26210352Sjoergstatic int 26310352Sjoergsvr4_elf_modevent(module_t mod, int type, void *data) 26410352Sjoerg{ 26510352Sjoerg int error; 26610352Sjoerg 26710352Sjoerg error = 0; 26810352Sjoerg 26910352Sjoerg switch(type) { 27010352Sjoerg case MOD_LOAD: 27110352Sjoerg if (elf32_insert_brand_entry(&svr4_brand) < 0) { 2722490Sjkh printf("cannot insert svr4 elf brand handler\n"); 27310352Sjoerg error = EINVAL; 27410352Sjoerg break; 27510352Sjoerg } 27610352Sjoerg if (bootverbose) 2772490Sjkh printf("svr4 ELF exec handler installed\n"); 27810352Sjoerg svr4_sockcache_init(); 27910352Sjoerg break; 28010352Sjoerg case MOD_UNLOAD: 28110352Sjoerg /* Only allow the emulator to be removed if it isn't in use. */ 28210352Sjoerg if (elf32_brand_inuse(&svr4_brand) != 0) { 2832490Sjkh error = EBUSY; 2842490Sjkh } else if (elf32_remove_brand_entry(&svr4_brand) < 0) { 28510352Sjoerg error = EINVAL; 28610352Sjoerg } 2872490Sjkh 28810352Sjoerg if (error) { 28910352Sjoerg printf("Could not deinstall ELF interpreter entry (error %d)\n", 2902490Sjkh error); 29110352Sjoerg break; 29210352Sjoerg } 29310352Sjoerg if (bootverbose) 29410352Sjoerg printf("svr4 ELF exec handler removed\n"); 29510352Sjoerg svr4_sockcache_destroy(); 29610352Sjoerg break; 29710352Sjoerg default: 29810352Sjoerg return (EOPNOTSUPP); 29910352Sjoerg break; 30010352Sjoerg } 30110352Sjoerg return error; 30210352Sjoerg} 30310352Sjoerg 30410352Sjoergstatic moduledata_t svr4_elf_mod = { 30510352Sjoerg "svr4elf", 30610352Sjoerg svr4_elf_modevent, 30710352Sjoerg 0 30810352Sjoerg}; 30910352SjoergDECLARE_MODULE(svr4elf, svr4_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY); 31010352SjoergMODULE_DEPEND(svr4elf, streams, 1, 1, 1); 31110352Sjoerg