The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/svr4/svr4_sysvec.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1998 Mark Newton
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by Christos Zoulas.
   16  * 4. The name of the author may not be used to endorse or promote products
   17  *    derived from this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD$");
   33 
   34 /* XXX we use functions that might not exist. */
   35 #include "opt_compat.h"
   36 
   37 #ifndef COMPAT_43
   38 #error "Unable to compile SVR4-emulator due to missing COMPAT_43 option!"
   39 #endif
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/proc.h>
   44 #include <sys/sysent.h>
   45 #include <sys/imgact.h>
   46 #include <sys/imgact_elf.h>
   47 #include <sys/socket.h>
   48 #include <sys/lock.h>
   49 #include <sys/malloc.h>
   50 #include <sys/mutex.h>
   51 #include <sys/namei.h>
   52 #include <sys/vnode.h>
   53 #include <sys/module.h>
   54 #include <vm/vm.h>
   55 #include <sys/exec.h>
   56 #include <sys/kernel.h>
   57 #include <machine/cpu.h>
   58 #include <netinet/in.h>
   59 
   60 #include <compat/svr4/svr4.h>
   61 #include <compat/svr4/svr4_types.h>
   62 #include <compat/svr4/svr4_syscall.h>
   63 #include <compat/svr4/svr4_signal.h>
   64 #include <compat/svr4/svr4_sockio.h>
   65 #include <compat/svr4/svr4_errno.h>
   66 #include <compat/svr4/svr4_proto.h>
   67 #include <compat/svr4/svr4_siginfo.h>
   68 #include <compat/svr4/svr4_util.h>
   69 
   70 int bsd_to_svr4_errno[ELAST+1] = {
   71         0,
   72         SVR4_EPERM,
   73         SVR4_ENOENT,
   74         SVR4_ESRCH,
   75         SVR4_EINTR,
   76         SVR4_EIO,
   77         SVR4_ENXIO,
   78         SVR4_E2BIG,
   79         SVR4_ENOEXEC,
   80         SVR4_EBADF,
   81         SVR4_ECHILD,
   82         SVR4_EDEADLK,
   83         SVR4_ENOMEM,
   84         SVR4_EACCES,
   85         SVR4_EFAULT,
   86         SVR4_ENOTBLK,
   87         SVR4_EBUSY,
   88         SVR4_EEXIST,
   89         SVR4_EXDEV,
   90         SVR4_ENODEV,
   91         SVR4_ENOTDIR,
   92         SVR4_EISDIR,
   93         SVR4_EINVAL,
   94         SVR4_ENFILE,
   95         SVR4_EMFILE,
   96         SVR4_ENOTTY,
   97         SVR4_ETXTBSY,
   98         SVR4_EFBIG,
   99         SVR4_ENOSPC,
  100         SVR4_ESPIPE,
  101         SVR4_EROFS,
  102         SVR4_EMLINK,
  103         SVR4_EPIPE,
  104         SVR4_EDOM,
  105         SVR4_ERANGE,
  106         SVR4_EAGAIN,
  107         SVR4_EINPROGRESS,
  108         SVR4_EALREADY,
  109         SVR4_ENOTSOCK,
  110         SVR4_EDESTADDRREQ,
  111         SVR4_EMSGSIZE,
  112         SVR4_EPROTOTYPE,
  113         SVR4_ENOPROTOOPT,
  114         SVR4_EPROTONOSUPPORT,
  115         SVR4_ESOCKTNOSUPPORT,
  116         SVR4_EOPNOTSUPP,
  117         SVR4_EPFNOSUPPORT,
  118         SVR4_EAFNOSUPPORT,
  119         SVR4_EADDRINUSE,
  120         SVR4_EADDRNOTAVAIL,
  121         SVR4_ENETDOWN,
  122         SVR4_ENETUNREACH,
  123         SVR4_ENETRESET,
  124         SVR4_ECONNABORTED,
  125         SVR4_ECONNRESET,
  126         SVR4_ENOBUFS,
  127         SVR4_EISCONN,
  128         SVR4_ENOTCONN,
  129         SVR4_ESHUTDOWN,
  130         SVR4_ETOOMANYREFS,
  131         SVR4_ETIMEDOUT,
  132         SVR4_ECONNREFUSED,
  133         SVR4_ELOOP,
  134         SVR4_ENAMETOOLONG,
  135         SVR4_EHOSTDOWN,
  136         SVR4_EHOSTUNREACH,
  137         SVR4_ENOTEMPTY,
  138         SVR4_EPROCLIM,
  139         SVR4_EUSERS,
  140         SVR4_EDQUOT,
  141         SVR4_ESTALE,
  142         SVR4_EREMOTE,
  143         SVR4_EBADRPC,
  144         SVR4_ERPCMISMATCH,
  145         SVR4_EPROGUNAVAIL,
  146         SVR4_EPROGMISMATCH,
  147         SVR4_EPROCUNAVAIL,
  148         SVR4_ENOLCK,
  149         SVR4_ENOSYS,
  150         SVR4_EFTYPE,
  151         SVR4_EAUTH,
  152         SVR4_ENEEDAUTH,
  153         SVR4_EIDRM,
  154         SVR4_ENOMSG,
  155 };
  156 
  157 
  158 static int      svr4_fixup(register_t **stack_base, struct image_params *imgp);
  159 
  160 extern struct sysent svr4_sysent[];
  161 #undef szsigcode
  162 #undef sigcode
  163 
  164 extern int svr4_szsigcode;
  165 extern char svr4_sigcode[];
  166 
  167 struct sysentvec svr4_sysvec = {
  168   SVR4_SYS_MAXSYSCALL,
  169   svr4_sysent,
  170   0xff,
  171   SVR4_SIGTBLSZ,
  172   bsd_to_svr4_sig,
  173   ELAST,  /* ELAST */
  174   bsd_to_svr4_errno,
  175   NULL,
  176   svr4_fixup,
  177   svr4_sendsig,
  178   svr4_sigcode,
  179   &svr4_szsigcode,
  180   NULL,
  181   "SVR4",
  182   elf32_coredump,
  183   NULL,
  184   SVR4_MINSIGSTKSZ,
  185   PAGE_SIZE,
  186   VM_MIN_ADDRESS,
  187   VM_MAXUSER_ADDRESS,
  188   USRSTACK,
  189   PS_STRINGS,
  190   VM_PROT_ALL,
  191   exec_copyout_strings,
  192   exec_setregs,
  193   NULL
  194 };
  195 
  196 Elf32_Brandinfo svr4_brand = {
  197   ELFOSABI_SYSV,
  198   EM_386,                       /* XXX only implemented for x86 so far. */
  199   "SVR4",
  200   svr4_emul_path,
  201   "/lib/libc.so.1",
  202   &svr4_sysvec,
  203   NULL,
  204 };
  205 
  206 const char      svr4_emul_path[] = "/compat/svr4";
  207 
  208 static int
  209 svr4_fixup(register_t **stack_base, struct image_params *imgp)
  210 {
  211         Elf32_Auxargs *args;
  212         register_t *pos;
  213              
  214         KASSERT(curthread->td_proc == imgp->proc &&
  215             (curthread->td_proc->p_flag & P_SA) == 0,
  216             ("unsafe svr4_fixup(), should be curproc"));
  217         args = (Elf32_Auxargs *)imgp->auxargs;
  218         pos = *stack_base + (imgp->argc + imgp->envc + 2);  
  219     
  220         if (args->trace)
  221                 AUXARGS_ENTRY(pos, AT_DEBUG, 1);
  222         if (args->execfd != -1)
  223                 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
  224         AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
  225         AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
  226         AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
  227         AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
  228         AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
  229         AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
  230         AUXARGS_ENTRY(pos, AT_BASE, args->base);
  231         AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
  232         AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
  233         AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
  234         AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
  235         AUXARGS_ENTRY(pos, AT_NULL, 0);
  236         
  237         free(imgp->auxargs, M_TEMP);      
  238         imgp->auxargs = NULL;
  239 
  240         (*stack_base)--;
  241         **stack_base = (register_t)imgp->argc;
  242         return 0;
  243 }
  244 
  245 /*
  246  * Search an alternate path before passing pathname arguments on
  247  * to system calls. Useful for keeping a separate 'emulation tree'.
  248  *
  249  * If cflag is set, we check if an attempt can be made to create
  250  * the named file, i.e. we check if the directory it should
  251  * be in exists.
  252  *
  253  * Code shamelessly stolen by Mark Newton from IBCS2 emulation code.
  254  */
  255 int
  256 svr4_emul_find(td, sgp, prefix, path, pbuf, cflag)
  257         struct thread    *td;
  258         caddr_t          *sgp;          /* Pointer to stackgap memory */
  259         const char       *prefix;
  260         char             *path;
  261         char            **pbuf;
  262         int               cflag;
  263 {
  264         struct nameidata         nd;
  265         struct nameidata         ndroot;
  266         struct vattr             vat;
  267         struct vattr             vatroot;
  268         int                      error;
  269         char                    *ptr, *buf, *cp;
  270         size_t                   sz, len;
  271 
  272         buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
  273         *pbuf = path;
  274 
  275         for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++)
  276                 continue;
  277 
  278         sz = MAXPATHLEN - (ptr - buf);
  279 
  280         /* 
  281          * If sgp is not given then the path is already in kernel space
  282          */
  283         if (sgp == NULL)
  284                 error = copystr(path, ptr, sz, &len);
  285         else
  286                 error = copyinstr(path, ptr, sz, &len);
  287 
  288         if (error) {
  289                 free(buf, M_TEMP);
  290                 return error;
  291         }
  292 
  293         if (*ptr != '/') {
  294                 free(buf, M_TEMP);
  295                 return EINVAL;
  296         }
  297 
  298         /*
  299          * We know that there is a / somewhere in this pathname.
  300          * Search backwards for it, to find the file's parent dir
  301          * to see if it exists in the alternate tree. If it does,
  302          * and we want to create a file (cflag is set). We don't
  303          * need to worry about the root comparison in this case.
  304          */
  305 
  306         if (cflag) {
  307                 for (cp = &ptr[len] - 1; *cp != '/'; cp--);
  308                 *cp = '\0';
  309 
  310                 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
  311 
  312                 if ((error = namei(&nd)) != 0) {
  313                         free(buf, M_TEMP);
  314                         return error;
  315                 }
  316                 NDFREE(&nd, NDF_ONLY_PNBUF);
  317 
  318                 *cp = '/';
  319         }
  320         else {
  321                 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
  322 
  323                 if ((error = namei(&nd)) != 0) {
  324                         free(buf, M_TEMP);
  325                         return error;
  326                 }
  327                 NDFREE(&nd, NDF_ONLY_PNBUF);
  328 
  329                 /*
  330                  * We now compare the vnode of the svr4_root to the one
  331                  * vnode asked. If they resolve to be the same, then we
  332                  * ignore the match so that the real root gets used.
  333                  * This avoids the problem of traversing "../.." to find the
  334                  * root directory and never finding it, because "/" resolves
  335                  * to the emulation root directory. This is expensive :-(
  336                  */
  337                 NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, svr4_emul_path,
  338                        td);
  339 
  340                 if ((error = namei(&ndroot)) != 0) {
  341                         /* Cannot happen! */
  342                         free(buf, M_TEMP);
  343                         vrele(nd.ni_vp);
  344                         return error;
  345                 }
  346                 NDFREE(&ndroot, NDF_ONLY_PNBUF);
  347 
  348                 if ((error = VOP_GETATTR(nd.ni_vp, &vat, td->td_ucred, td)) != 0) {
  349                         goto done;
  350                 }
  351 
  352                 if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, td->td_ucred, td))
  353                     != 0) {
  354                         goto done;
  355                 }
  356 
  357                 if (vat.va_fsid == vatroot.va_fsid &&
  358                     vat.va_fileid == vatroot.va_fileid) {
  359                         error = ENOENT;
  360                         goto done;
  361                 }
  362 
  363         }
  364         if (sgp == NULL)
  365                 *pbuf = buf;
  366         else {
  367                 sz = &ptr[len] - buf;
  368                 if ((*pbuf = stackgap_alloc(sgp, sz + 1)) != NULL)
  369                         error = copyout(buf, *pbuf, sz);
  370                 else
  371                         error = ENAMETOOLONG;
  372                 free(buf, M_TEMP);
  373         }
  374 
  375 
  376 done:
  377         vrele(nd.ni_vp);
  378         if (!cflag)
  379                 vrele(ndroot.ni_vp);
  380         return error;
  381 }
  382 
  383 static int
  384 svr4_elf_modevent(module_t mod, int type, void *data)
  385 {
  386         int error;
  387 
  388         error = 0;
  389 
  390         switch(type) {
  391         case MOD_LOAD:
  392                 if (elf32_insert_brand_entry(&svr4_brand) < 0)
  393                         error = EINVAL;
  394                 if (error)
  395                         printf("cannot insert svr4 elf brand handler\n");
  396                 else if (bootverbose)
  397                         printf("svr4 ELF exec handler installed\n");
  398                 break;
  399         case MOD_UNLOAD:
  400                 /* Only allow the emulator to be removed if it isn't in use. */
  401                 if (elf32_brand_inuse(&svr4_brand) != 0) {
  402                         error = EBUSY;
  403                 } else if (elf32_remove_brand_entry(&svr4_brand) < 0) {
  404                         error = EINVAL;
  405                 }
  406 
  407                 if (error)
  408                         printf("Could not deinstall ELF interpreter entry (error %d)\n",
  409                                error);
  410                 else if (bootverbose)
  411                         printf("svr4 ELF exec handler removed\n");
  412                 break;
  413         default:
  414                 return (EOPNOTSUPP);
  415                 break;
  416         }
  417         return error;
  418 }
  419 
  420 static moduledata_t svr4_elf_mod = {
  421         "svr4elf",
  422         svr4_elf_modevent,
  423         0
  424 };
  425 DECLARE_MODULE(svr4elf, svr4_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
  426 MODULE_DEPEND(svr4elf, streams, 1, 1, 1);

Cache object: 0f93bafdc5a2c6b6f736cc7a133b2057


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.