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/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  * $FreeBSD$
   31  */
   32 
   33 /* XXX we use functions that might not exist. */
   34 #include "opt_compat.h"
   35 
   36 #ifndef COMPAT_43
   37 #error "Unable to compile SVR4-emulator due to missing COMPAT_43 option!"
   38 #endif
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/buf.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/malloc.h>
   49 #include <sys/namei.h>
   50 #include <sys/vnode.h>
   51 #include <sys/module.h>
   52 #include <vm/vm.h>
   53 #include <vm/vm_zone.h>
   54 #include <sys/exec.h>
   55 #include <sys/kernel.h>
   56 #include <machine/cpu.h>
   57 #include <netinet/in.h>
   58 
   59 #include <svr4/svr4.h>
   60 #include <svr4/svr4_types.h>
   61 #include <svr4/svr4_syscall.h>
   62 #include <svr4/svr4_signal.h>
   63 #include <svr4/svr4_sockio.h>
   64 #include <svr4/svr4_socket.h>
   65 #include <svr4/svr4_errno.h>
   66 #include <svr4/svr4_proto.h>
   67 #include <svr4/svr4_siginfo.h>
   68 #include <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(long **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   0,
  176   svr4_fixup,
  177   svr4_sendsig,
  178   svr4_sigcode,
  179   &svr4_szsigcode,
  180   NULL,
  181   "SVR4",
  182   elf_coredump,
  183   NULL,
  184   SVR4_MINSIGSTKSZ
  185 };
  186 
  187 Elf32_Brandinfo svr4_brand = {
  188   ELFOSABI_SYSV,
  189   "SVR4",
  190   "/compat/svr4",
  191   "/lib/libc.so.1",
  192   &svr4_sysvec
  193 };
  194 
  195 const char      svr4_emul_path[] = "/compat/svr4";
  196 
  197 static int
  198 svr4_fixup(long **stack_base, struct image_params *imgp)
  199 {
  200         Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs;
  201         long *pos;
  202              
  203         pos = *stack_base + (imgp->argc + imgp->envc + 2);  
  204     
  205         if (args->trace) {
  206                 AUXARGS_ENTRY(pos, AT_DEBUG, 1);
  207         }
  208         if (args->execfd != -1) {
  209                 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
  210         }       
  211         AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
  212         AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
  213         AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
  214         AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
  215         AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
  216         AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
  217         AUXARGS_ENTRY(pos, AT_BASE, args->base);
  218         AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_cred->p_ruid);
  219         AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_cred->p_svuid);
  220         AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_cred->p_rgid);
  221         AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_cred->p_svgid);
  222         AUXARGS_ENTRY(pos, AT_NULL, 0);
  223         
  224         free(imgp->auxargs, M_TEMP);      
  225         imgp->auxargs = NULL;
  226 
  227         (*stack_base)--;
  228         **stack_base = (int)imgp->argc;
  229         return 0;
  230 }
  231 
  232 /*
  233  * Search an alternate path before passing pathname arguments on
  234  * to system calls. Useful for keeping a seperate 'emulation tree'.
  235  *
  236  * If cflag is set, we check if an attempt can be made to create
  237  * the named file, i.e. we check if the directory it should
  238  * be in exists.
  239  *
  240  * Code shamelessly stolen by Mark Newton from IBCS2 emulation code.
  241  */
  242 int
  243 svr4_emul_find(p, sgp, prefix, path, pbuf, cflag)
  244         struct proc      *p;
  245         caddr_t          *sgp;          /* Pointer to stackgap memory */
  246         const char       *prefix;
  247         char             *path;
  248         char            **pbuf;
  249         int               cflag;
  250 {
  251         struct nameidata         nd;
  252         struct nameidata         ndroot;
  253         struct vattr             vat;
  254         struct vattr             vatroot;
  255         int                      error;
  256         char                    *ptr, *buf, *cp;
  257         size_t                   sz, len;
  258 
  259         buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
  260         *pbuf = path;
  261 
  262         for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++)
  263                 continue;
  264 
  265         sz = MAXPATHLEN - (ptr - buf);
  266 
  267         /* 
  268          * If sgp is not given then the path is already in kernel space
  269          */
  270         if (sgp == NULL)
  271                 error = copystr(path, ptr, sz, &len);
  272         else
  273                 error = copyinstr(path, ptr, sz, &len);
  274 
  275         if (error) {
  276                 free(buf, M_TEMP);
  277                 return error;
  278         }
  279 
  280         if (*ptr != '/') {
  281                 free(buf, M_TEMP);
  282                 return EINVAL;
  283         }
  284 
  285         /*
  286          * We know that there is a / somewhere in this pathname.
  287          * Search backwards for it, to find the file's parent dir
  288          * to see if it exists in the alternate tree. If it does,
  289          * and we want to create a file (cflag is set). We don't
  290          * need to worry about the root comparison in this case.
  291          */
  292 
  293         if (cflag) {
  294                 for (cp = &ptr[len] - 1; *cp != '/'; cp--);
  295                 *cp = '\0';
  296 
  297                 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);
  298 
  299                 if ((error = namei(&nd)) != 0) {
  300                         free(buf, M_TEMP);
  301                         return error;
  302                 }
  303                 NDFREE(&nd, NDF_ONLY_PNBUF);
  304 
  305                 *cp = '/';
  306         }
  307         else {
  308                 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);
  309 
  310                 if ((error = namei(&nd)) != 0) {
  311                         free(buf, M_TEMP);
  312                         return error;
  313                 }
  314                 NDFREE(&nd, NDF_ONLY_PNBUF);
  315 
  316                 /*
  317                  * We now compare the vnode of the svr4_root to the one
  318                  * vnode asked. If they resolve to be the same, then we
  319                  * ignore the match so that the real root gets used.
  320                  * This avoids the problem of traversing "../.." to find the
  321                  * root directory and never finding it, because "/" resolves
  322                  * to the emulation root directory. This is expensive :-(
  323                  */
  324                 NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, svr4_emul_path,
  325                        p);
  326 
  327                 if ((error = namei(&ndroot)) != 0) {
  328                         /* Cannot happen! */
  329                         free(buf, M_TEMP);
  330                         vrele(nd.ni_vp);
  331                         return error;
  332                 }
  333                 NDFREE(&ndroot, NDF_ONLY_PNBUF);
  334 
  335                 if ((error = VOP_GETATTR(nd.ni_vp, &vat, p->p_ucred, p)) != 0) {
  336                         goto done;
  337                 }
  338 
  339                 if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, p->p_ucred, p))
  340                     != 0) {
  341                         goto done;
  342                 }
  343 
  344                 if (vat.va_fsid == vatroot.va_fsid &&
  345                     vat.va_fileid == vatroot.va_fileid) {
  346                         error = ENOENT;
  347                         goto done;
  348                 }
  349 
  350         }
  351         if (sgp == NULL)
  352                 *pbuf = buf;
  353         else {
  354                 sz = &ptr[len] - buf;
  355                 *pbuf = stackgap_alloc(sgp, sz + 1);
  356                 error = copyout(buf, *pbuf, sz);
  357                 free(buf, M_TEMP);
  358         }
  359 
  360 
  361 done:
  362         vrele(nd.ni_vp);
  363         if (!cflag)
  364                 vrele(ndroot.ni_vp);
  365         return error;
  366 }
  367 
  368 static int
  369 svr4_elf_modevent(module_t mod, int type, void *data)
  370 {
  371         int error;
  372 
  373         error = 0;
  374 
  375         switch(type) {
  376         case MOD_LOAD:
  377                 if (elf_insert_brand_entry(&svr4_brand) < 0)
  378                         error = EINVAL;
  379                 if (error)
  380                         printf("cannot insert svr4 elf brand handler\n");
  381                 else if (bootverbose)
  382                         printf("svr4 ELF exec handler installed\n");
  383                 break;
  384         case MOD_UNLOAD:
  385                 /* Only allow the emulator to be removed if it isn't in use. */
  386                 if (elf_brand_inuse(&svr4_brand) != 0) {
  387                         error = EBUSY;
  388                 } else if (elf_remove_brand_entry(&svr4_brand) < 0) {
  389                         error = EINVAL;
  390                 }
  391 
  392                 if (error)
  393                         printf("Could not deinstall ELF interpreter entry (error %d)\n",
  394                                error);
  395                 else if (bootverbose)
  396                         printf("svr4 ELF exec handler removed\n");
  397                 break;
  398         default:
  399                 break;
  400         }
  401         return error;
  402 }
  403 
  404 static moduledata_t svr4_elf_mod = {
  405         "svr4elf",
  406         svr4_elf_modevent,
  407         0
  408 };
  409 DECLARE_MODULE(svr4elf, svr4_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);

Cache object: 3563f99e30635d7df10799bc2ef9770d


[ 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.