root/kern/exec_elf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ELFNAME

    1 /*      $OpenBSD: exec_elf.c,v 1.61 2007/05/28 23:10:10 beck Exp $      */
    2 
    3 /*
    4  * Copyright (c) 1996 Per Fogelstrom
    5  * All rights reserved.
    6  *
    7  * Copyright (c) 1994 Christos Zoulas
    8  * All rights reserved.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  *
   32  */
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/kernel.h>
   37 #include <sys/proc.h>
   38 #include <sys/malloc.h>
   39 #include <sys/pool.h>
   40 #include <sys/mount.h>
   41 #include <sys/namei.h>
   42 #include <sys/vnode.h>
   43 #include <sys/exec.h>
   44 #include <sys/exec_elf.h>
   45 #include <sys/exec_olf.h>
   46 #include <sys/file.h>
   47 #include <sys/syscall.h>
   48 #include <sys/signalvar.h>
   49 #include <sys/stat.h>
   50 
   51 #include <sys/mman.h>
   52 #include <uvm/uvm_extern.h>
   53 
   54 #include <machine/cpu.h>
   55 #include <machine/reg.h>
   56 #include <machine/exec.h>
   57 
   58 #ifdef COMPAT_LINUX
   59 #include <compat/linux/linux_exec.h>
   60 #endif
   61 
   62 #ifdef COMPAT_SVR4
   63 #include <compat/svr4/svr4_exec.h>
   64 #endif
   65 
   66 #ifdef COMPAT_FREEBSD
   67 #include <compat/freebsd/freebsd_exec.h>
   68 #endif
   69 
   70 struct ELFNAME(probe_entry) {
   71         int (*func)(struct proc *, struct exec_package *, char *,
   72             u_long *, u_int8_t *);
   73         int os_mask;
   74 } ELFNAME(probes)[] = {
   75         /* XXX - bogus, shouldn't be size independent.. */
   76 #ifdef COMPAT_FREEBSD
   77         { freebsd_elf_probe, 1 << OOS_FREEBSD },
   78 #endif
   79 #ifdef COMPAT_SVR4
   80         { svr4_elf_probe,
   81             1 << OOS_SVR4 | 1 << OOS_ESIX | 1 << OOS_SOLARIS | 1 << OOS_SCO |
   82             1 << OOS_DELL | 1 << OOS_NCR },
   83 #endif
   84 #ifdef COMPAT_LINUX
   85         { linux_elf_probe, 1 << OOS_LINUX },
   86 #endif
   87         { 0, 1 << OOS_OPENBSD }
   88 };
   89 
   90 int ELFNAME(load_file)(struct proc *, char *, struct exec_package *,
   91         struct elf_args *, Elf_Addr *);
   92 int ELFNAME(check_header)(Elf_Ehdr *, int);
   93 int ELFNAME(olf_check_header)(Elf_Ehdr *, int, u_int8_t *);
   94 int ELFNAME(read_from)(struct proc *, struct vnode *, u_long, caddr_t, int);
   95 void ELFNAME(load_psection)(struct exec_vmcmd_set *, struct vnode *,
   96         Elf_Phdr *, Elf_Addr *, Elf_Addr *, int *, int);
   97 
   98 extern char sigcode[], esigcode[];
   99 #ifdef SYSCALL_DEBUG
  100 extern char *syscallnames[];
  101 #endif
  102 
  103 /* round up and down to page boundaries. */
  104 #define ELF_ROUND(a, b)         (((a) + (b) - 1) & ~((b) - 1))
  105 #define ELF_TRUNC(a, b)         ((a) & ~((b) - 1))
  106 
  107 /*
  108  * We limit the number of program headers to 32, this should
  109  * be a reasonable limit for ELF, the most we have seen so far is 12
  110  */
  111 #define ELF_MAX_VALID_PHDR 32
  112 
  113 /*
  114  * This is the basic elf emul. elf_probe_funcs may change to other emuls.
  115  */
  116 struct emul ELFNAMEEND(emul) = {
  117         "native",
  118         NULL,
  119         sendsig,
  120         SYS_syscall,
  121         SYS_MAXSYSCALL,
  122         sysent,
  123 #ifdef SYSCALL_DEBUG
  124         syscallnames,
  125 #else
  126         NULL,
  127 #endif
  128         sizeof (AuxInfo) * ELF_AUX_ENTRIES,
  129         ELFNAME(copyargs),
  130         setregs,
  131         ELFNAME2(exec,fixup),
  132         sigcode,
  133         esigcode,
  134         EMUL_ENABLED | EMUL_NATIVE,
  135 };
  136 
  137 /*
  138  * Copy arguments onto the stack in the normal way, but add some
  139  * space for extra information in case of dynamic binding.
  140  */
  141 void *
  142 ELFNAME(copyargs)(struct exec_package *pack, struct ps_strings *arginfo,
  143                 void *stack, void *argp)
  144 {
  145         stack = copyargs(pack, arginfo, stack, argp);
  146         if (!stack)
  147                 return (NULL);
  148 
  149         /*
  150          * Push space for extra arguments on the stack needed by
  151          * dynamically linked binaries.
  152          */
  153         if (pack->ep_interp != NULL) {
  154                 pack->ep_emul_argp = stack;
  155                 stack = (char *)stack + ELF_AUX_ENTRIES * sizeof (AuxInfo);
  156         }
  157         return (stack);
  158 }
  159 
  160 /*
  161  * Check header for validity; return 0 for ok, ENOEXEC if error
  162  */
  163 int
  164 ELFNAME(check_header)(Elf_Ehdr *ehdr, int type)
  165 {
  166         /*
  167          * We need to check magic, class size, endianess, and version before
  168          * we look at the rest of the Elf_Ehdr structure. These few elements
  169          * are represented in a machine independant fashion.
  170          */
  171         if (!IS_ELF(*ehdr) ||
  172             ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
  173             ehdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
  174             ehdr->e_ident[EI_VERSION] != ELF_TARG_VER)
  175                 return (ENOEXEC);
  176 
  177         /* Now check the machine dependant header */
  178         if (ehdr->e_machine != ELF_TARG_MACH ||
  179             ehdr->e_version != ELF_TARG_VER)
  180                 return (ENOEXEC);
  181 
  182         /* Check the type */
  183         if (ehdr->e_type != type)
  184                 return (ENOEXEC);
  185 
  186         /* Don't allow an insane amount of sections. */
  187         if (ehdr->e_phnum > ELF_MAX_VALID_PHDR)
  188                 return (ENOEXEC);
  189 
  190         return (0);
  191 }
  192 
  193 #ifndef SMALL_KERNEL
  194 /*
  195  * Check header for validity; return 0 for ok, ENOEXEC if error.
  196  * Remember OS tag for callers sake.
  197  */
  198 int
  199 ELFNAME(olf_check_header)(Elf_Ehdr *ehdr, int type, u_int8_t *os)
  200 {
  201         int i;
  202 
  203         /*
  204          * We need to check magic, class size, endianess, version, and OS
  205          * before we look at the rest of the Elf_Ehdr structure. These few
  206          * elements are represented in a machine independant fashion.
  207          */
  208         if (!IS_OLF(*ehdr) ||
  209             ehdr->e_ident[OI_CLASS] != ELF_TARG_CLASS ||
  210             ehdr->e_ident[OI_DATA] != ELF_TARG_DATA ||
  211             ehdr->e_ident[OI_VERSION] != ELF_TARG_VER)
  212                 return (ENOEXEC);
  213 
  214         for (i = 0;
  215             i < sizeof(ELFNAME(probes)) / sizeof(ELFNAME(probes)[0]);
  216             i++) {
  217                 if ((1 << ehdr->e_ident[OI_OS]) & ELFNAME(probes)[i].os_mask)
  218                         goto os_ok;
  219         }
  220         return (ENOEXEC);
  221 
  222 os_ok:
  223         /* Now check the machine dependant header */
  224         if (ehdr->e_machine != ELF_TARG_MACH ||
  225             ehdr->e_version != ELF_TARG_VER)
  226                 return (ENOEXEC);
  227 
  228         /* Check the type */
  229         if (ehdr->e_type != type)
  230                 return (ENOEXEC);
  231 
  232         /* Don't allow an insane amount of sections. */
  233         if (ehdr->e_phnum > ELF_MAX_VALID_PHDR)
  234                 return (ENOEXEC);
  235 
  236         *os = ehdr->e_ident[OI_OS];
  237         return (0);
  238 }
  239 #endif  /* !SMALL_KERNEL */
  240 
  241 /*
  242  * Load a psection at the appropriate address
  243  */
  244 void
  245 ELFNAME(load_psection)(struct exec_vmcmd_set *vcset, struct vnode *vp,
  246         Elf_Phdr *ph, Elf_Addr *addr, Elf_Addr *size, int *prot, int flags)
  247 {
  248         u_long uaddr, msize, lsize, psize, rm, rf;
  249         long diff, offset, bdiff;
  250         Elf_Addr base;
  251 
  252         /*
  253          * If the user specified an address, then we load there.
  254          */
  255         if (*addr != ELFDEFNNAME(NO_ADDR)) {
  256                 if (ph->p_align > 1) {
  257                         *addr = ELF_TRUNC(*addr, ph->p_align);
  258                         diff = ph->p_vaddr - ELF_TRUNC(ph->p_vaddr, ph->p_align);
  259                         /* page align vaddr */
  260                         base = *addr + trunc_page(ph->p_vaddr) 
  261                             - ELF_TRUNC(ph->p_vaddr, ph->p_align);
  262 
  263                         bdiff = ph->p_vaddr - trunc_page(ph->p_vaddr);
  264 
  265                 } else
  266                         diff = 0;
  267         } else {
  268                 *addr = uaddr = ph->p_vaddr;
  269                 if (ph->p_align > 1)
  270                         *addr = ELF_TRUNC(uaddr, ph->p_align);
  271                 base = trunc_page(uaddr);
  272                 bdiff = uaddr - base;
  273                 diff = uaddr - *addr;
  274         }
  275 
  276         *prot |= (ph->p_flags & PF_R) ? VM_PROT_READ : 0;
  277         *prot |= (ph->p_flags & PF_W) ? VM_PROT_WRITE : 0;
  278         *prot |= (ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0;
  279 
  280         msize = ph->p_memsz + diff;
  281         offset = ph->p_offset - bdiff;
  282         lsize = ph->p_filesz + bdiff;
  283         psize = round_page(lsize);
  284 
  285         /*
  286          * Because the pagedvn pager can't handle zero fill of the last
  287          * data page if it's not page aligned we map the last page readvn.
  288          */
  289         if (ph->p_flags & PF_W) {
  290                 psize = trunc_page(lsize);
  291                 if (psize > 0)
  292                         NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, base, vp,
  293                             offset, *prot, flags);
  294                 if (psize != lsize) {
  295                         NEW_VMCMD2(vcset, vmcmd_map_readvn, lsize - psize,
  296                             base + psize, vp, offset + psize, *prot, flags);
  297                 }
  298         } else {
  299                 NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, base, vp, offset,
  300                     *prot, flags);
  301         }
  302 
  303         /*
  304          * Check if we need to extend the size of the segment
  305          */
  306         rm = round_page(*addr + ph->p_memsz + diff);
  307         rf = round_page(*addr + ph->p_filesz + diff);
  308 
  309         if (rm != rf) {
  310                 NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 0,
  311                     *prot, flags);
  312         }
  313         *size = msize;
  314 }
  315 
  316 /*
  317  * Read from vnode into buffer at offset.
  318  */
  319 int
  320 ELFNAME(read_from)(struct proc *p, struct vnode *vp, u_long off, caddr_t buf,
  321         int size)
  322 {
  323         int error;
  324         size_t resid;
  325 
  326         if ((error = vn_rdwr(UIO_READ, vp, buf, size, off, UIO_SYSSPACE,
  327             0, p->p_ucred, &resid, p)) != 0)
  328                 return error;
  329         /*
  330          * See if we got all of it
  331          */
  332         if (resid != 0)
  333                 return (ENOEXEC);
  334         return (0);
  335 }
  336 
  337 /*
  338  * Load a file (interpreter/library) pointed to by path [stolen from
  339  * coff_load_shlib()]. Made slightly generic so it might be used externally.
  340  */
  341 int
  342 ELFNAME(load_file)(struct proc *p, char *path, struct exec_package *epp,
  343         struct elf_args *ap, Elf_Addr *last)
  344 {
  345         int error, i;
  346         struct nameidata nd;
  347         Elf_Ehdr eh;
  348         Elf_Phdr *ph = NULL;
  349         u_long phsize;
  350         Elf_Addr addr;
  351         struct vnode *vp;
  352 #ifndef SMALL_KERNEL
  353         u_int8_t os;                    /* Just a dummy in this routine */
  354 #endif
  355         Elf_Phdr *base_ph = NULL;
  356         struct interp_ld_sec {
  357                 Elf_Addr vaddr;
  358                 u_long memsz;
  359         } loadmap[ELF_MAX_VALID_PHDR];
  360         int nload, idx = 0;
  361         Elf_Addr pos = *last;
  362         int file_align;
  363 
  364         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p);
  365         if ((error = namei(&nd)) != 0) {
  366                 return (error);
  367         }
  368         vp = nd.ni_vp;
  369         if (vp->v_type != VREG) {
  370                 error = EACCES;
  371                 goto bad;
  372         }
  373         if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0)
  374                 goto bad;
  375         if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
  376                 error = EACCES;
  377                 goto bad;
  378         }
  379         if ((error = VOP_ACCESS(vp, VREAD, p->p_ucred, p)) != 0)
  380                 goto bad1;
  381         if ((error = ELFNAME(read_from)(p, nd.ni_vp, 0,
  382                                     (caddr_t)&eh, sizeof(eh))) != 0)
  383                 goto bad1;
  384 
  385         if (ELFNAME(check_header)(&eh, ET_DYN)
  386 #ifndef SMALL_KERNEL
  387             && ELFNAME(olf_check_header)(&eh, ET_DYN, &os)
  388 #endif
  389             ) {
  390                 error = ENOEXEC;
  391                 goto bad1;
  392         }
  393 
  394         phsize = eh.e_phnum * sizeof(Elf_Phdr);
  395         ph = malloc(phsize, M_TEMP, M_WAITOK);
  396 
  397         if ((error = ELFNAME(read_from)(p, nd.ni_vp, eh.e_phoff, (caddr_t)ph,
  398             phsize)) != 0)
  399                 goto bad1;
  400 
  401         for (i = 0; i < eh.e_phnum; i++) {
  402                 if (ph[i].p_type == PT_LOAD) {
  403                         loadmap[idx].vaddr = trunc_page(ph[i].p_vaddr);
  404                         loadmap[idx].memsz = round_page (ph[i].p_vaddr +
  405                             ph[i].p_memsz - loadmap[idx].vaddr);
  406                         file_align = ph[i].p_align;
  407                         idx++;
  408                 }
  409         }
  410         nload = idx;
  411 
  412         /*
  413          * If no position to load the interpreter was set by a probe
  414          * function, pick the same address that a non-fixed mmap(0, ..)
  415          * would (i.e. something safely out of the way).
  416          */
  417         if (pos == ELFDEFNNAME(NO_ADDR)) {
  418                 pos = uvm_map_hint(p, VM_PROT_EXECUTE);
  419         }
  420 
  421         pos = ELF_ROUND(pos, file_align);
  422         *last = epp->ep_interp_pos = pos;
  423         for (i = 0; i < nload;/**/) {
  424                 vaddr_t addr;
  425                 struct  uvm_object *uobj;
  426                 off_t   uoff;
  427                 size_t  size;
  428 
  429 #ifdef this_needs_fixing
  430                 if (i == 0) {
  431                         uobj = &vp->v_uvm.u_obj;
  432                         /* need to fix uoff */
  433                 } else {
  434 #endif
  435                         uobj = NULL;
  436                         uoff = 0;
  437 #ifdef this_needs_fixing
  438                 }
  439 #endif
  440 
  441                 addr = trunc_page(pos + loadmap[i].vaddr);
  442                 size =  round_page(addr + loadmap[i].memsz) - addr;
  443 
  444                 /* CRAP - map_findspace does not avoid daddr+MAXDSIZ */
  445                 if ((addr + size > (vaddr_t)p->p_vmspace->vm_daddr) &&
  446                     (addr < (vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ))
  447                         addr = round_page((vaddr_t)p->p_vmspace->vm_daddr +
  448                             MAXDSIZ);
  449 
  450                 if (uvm_map_findspace(&p->p_vmspace->vm_map, addr, size,
  451                     &addr, uobj, uoff, 0, UVM_FLAG_FIXED) == NULL) {
  452                         if (uvm_map_findspace(&p->p_vmspace->vm_map, addr, size,
  453                             &addr, uobj, uoff, 0, 0) == NULL) {
  454                                 error = ENOMEM; /* XXX */
  455                                 goto bad1;
  456                         }
  457                 } 
  458                 if (addr != pos + loadmap[i].vaddr) {
  459                         /* base changed. */
  460                         pos = addr - trunc_page(loadmap[i].vaddr);
  461                         pos = ELF_ROUND(pos,file_align);
  462                         epp->ep_interp_pos = *last = pos;
  463                         i = 0;
  464                         continue;
  465                 }
  466 
  467                 i++;
  468         }
  469 
  470         /*
  471          * Load all the necessary sections
  472          */
  473         for (i = 0; i < eh.e_phnum; i++) {
  474                 Elf_Addr size = 0;
  475                 int prot = 0;
  476                 int flags;
  477 
  478                 switch (ph[i].p_type) {
  479                 case PT_LOAD:
  480                         if (base_ph == NULL) {
  481                                 flags = VMCMD_BASE;
  482                                 addr = *last;
  483                                 base_ph = &ph[i];
  484                         } else {
  485                                 flags = VMCMD_RELATIVE;
  486                                 addr = ph[i].p_vaddr - base_ph->p_vaddr;
  487                         }
  488                         ELFNAME(load_psection)(&epp->ep_vmcmds, nd.ni_vp,
  489                             &ph[i], &addr, &size, &prot, flags);
  490                         /* If entry is within this section it must be text */
  491                         if (eh.e_entry >= ph[i].p_vaddr &&
  492                             eh.e_entry < (ph[i].p_vaddr + size)) {
  493                                 epp->ep_entry = addr + eh.e_entry -
  494                                     ELF_TRUNC(ph[i].p_vaddr,ph[i].p_align);
  495                                 ap->arg_interp = addr;
  496                         }
  497                         addr += size;
  498                         break;
  499 
  500                 case PT_DYNAMIC:
  501                 case PT_PHDR:
  502                 case PT_NOTE:
  503                         break;
  504 
  505                 default:
  506                         break;
  507                 }
  508         }
  509 
  510         vn_marktext(nd.ni_vp);
  511 
  512 bad1:
  513         VOP_CLOSE(nd.ni_vp, FREAD, p->p_ucred, p);
  514 bad:
  515         if (ph != NULL)
  516                 free(ph, M_TEMP);
  517 
  518         *last = addr;
  519         vput(nd.ni_vp);
  520         return (error);
  521 }
  522 
  523 /*
  524  * Prepare an Elf binary's exec package
  525  *
  526  * First, set of the various offsets/lengths in the exec package.
  527  *
  528  * Then, mark the text image busy (so it can be demand paged) or error out if
  529  * this is not possible.  Finally, set up vmcmds for the text, data, bss, and
  530  * stack segments.
  531  */
  532 int
  533 ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp)
  534 {
  535         Elf_Ehdr *eh = epp->ep_hdr;
  536         Elf_Phdr *ph, *pp;
  537         Elf_Addr phdr = 0;
  538         int error, i;
  539         char *interp = NULL;
  540         u_long pos = 0, phsize;
  541         u_int8_t os = OOS_NULL;
  542 
  543         if (epp->ep_hdrvalid < sizeof(Elf_Ehdr))
  544                 return (ENOEXEC);
  545 
  546         if (ELFNAME(check_header)(eh, ET_EXEC)
  547 #ifndef SMALL_KERNEL
  548             && ELFNAME(olf_check_header)(eh, ET_EXEC, &os)
  549 #endif
  550             )
  551                 return (ENOEXEC);
  552 
  553         /*
  554          * check if vnode is in open for writing, because we want to demand-
  555          * page out of it.  if it is, don't do it, for various reasons.
  556          */
  557         if (epp->ep_vp->v_writecount != 0) {
  558 #ifdef DIAGNOSTIC
  559                 if (epp->ep_vp->v_flag & VTEXT)
  560                         panic("exec: a VTEXT vnode has writecount != 0");
  561 #endif
  562                 return (ETXTBSY);
  563         }
  564         /*
  565          * Allocate space to hold all the program headers, and read them
  566          * from the file
  567          */
  568         phsize = eh->e_phnum * sizeof(Elf_Phdr);
  569         ph = malloc(phsize, M_TEMP, M_WAITOK);
  570 
  571         if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, (caddr_t)ph,
  572             phsize)) != 0)
  573                 goto bad;
  574 
  575         epp->ep_tsize = ELFDEFNNAME(NO_ADDR);
  576         epp->ep_dsize = ELFDEFNNAME(NO_ADDR);
  577 
  578         for (i = 0; i < eh->e_phnum; i++) {
  579                 pp = &ph[i];
  580                 if (pp->p_type == PT_INTERP) {
  581                         if (pp->p_filesz >= MAXPATHLEN)
  582                                 goto bad;
  583                         interp = pool_get(&namei_pool, PR_WAITOK);
  584                         if ((error = ELFNAME(read_from)(p, epp->ep_vp,
  585                             pp->p_offset, interp, pp->p_filesz)) != 0) {
  586                                 goto bad;
  587                         }
  588                         break;
  589                 }
  590         }
  591 
  592         /*
  593          * OK, we want a slightly different twist of the
  594          * standard emulation package for "real" elf.
  595          */
  596         epp->ep_emul = &ELFNAMEEND(emul);
  597         pos = ELFDEFNNAME(NO_ADDR);
  598 
  599         /*
  600          * On the same architecture, we may be emulating different systems.
  601          * See which one will accept this executable.
  602          *
  603          * Probe functions would normally see if the interpreter (if any)
  604          * exists. Emulation packages may possibly replace the interpreter in
  605          * *interp with a changed path (/emul/xxx/<path>), and also
  606          * set the ep_emul field in the exec package structure.
  607          */
  608         error = ENOEXEC;
  609         p->p_os = OOS_OPENBSD;
  610 #ifdef NATIVE_EXEC_ELF
  611         if (ELFNAME(os_pt_note)(p, epp, epp->ep_hdr, "OpenBSD", 8, 4) == 0) {
  612                 goto native;
  613         }
  614 #endif
  615         for (i = 0;
  616             i < sizeof(ELFNAME(probes)) / sizeof(ELFNAME(probes)[0]) && error;
  617             i++) {
  618                 if (os == OOS_NULL || ((1 << os) & ELFNAME(probes)[i].os_mask))
  619                         error = ELFNAME(probes)[i].func ?
  620                             (*ELFNAME(probes)[i].func)(p, epp, interp, &pos, &os) :
  621                             0;
  622         }
  623         if (!error)
  624                 p->p_os = os;
  625 #ifndef NATIVE_EXEC_ELF
  626         else
  627                 goto bad;
  628 #else
  629 native:
  630 #endif /* NATIVE_EXEC_ELF */
  631         /*
  632          * Load all the necessary sections
  633          */
  634         for (i = 0; i < eh->e_phnum; i++) {
  635                 Elf_Addr addr = ELFDEFNNAME(NO_ADDR), size = 0;
  636                 int prot = 0;
  637 
  638                 pp = &ph[i];
  639 
  640                 switch (ph[i].p_type) {
  641                 case PT_LOAD:
  642                         /*
  643                          * Calculates size of text and data segments
  644                          * by starting at first and going to end of last.
  645                          * 'rwx' sections are treated as data.
  646                          * this is correct for BSS_PLT, but may not be
  647                          * for DATA_PLT, is fine for TEXT_PLT.
  648                          */
  649                         ELFNAME(load_psection)(&epp->ep_vmcmds, epp->ep_vp,
  650                             &ph[i], &addr, &size, &prot, 0);
  651                         /*
  652                          * Decide whether it's text or data by looking
  653                          * at the protection of the section
  654                          */
  655                         if (prot & VM_PROT_WRITE) {
  656                                 /* data section */
  657                                 if (epp->ep_dsize == ELFDEFNNAME(NO_ADDR)) {
  658                                         epp->ep_daddr = addr;
  659                                         epp->ep_dsize = size;
  660                                 } else {
  661                                         if (addr < epp->ep_daddr) {
  662                                                 epp->ep_dsize =
  663                                                     epp->ep_dsize +
  664                                                     epp->ep_daddr -
  665                                                     addr;
  666                                                 epp->ep_daddr = addr;
  667                                         } else
  668                                                 epp->ep_dsize = addr+size -
  669                                                     epp->ep_daddr;
  670                                 }
  671                         } else if (prot & VM_PROT_EXECUTE) {
  672                                 /* text section */
  673                                 if (epp->ep_tsize == ELFDEFNNAME(NO_ADDR)) {
  674                                         epp->ep_taddr = addr;
  675                                         epp->ep_tsize = size;
  676                                 } else {
  677                                         if (addr < epp->ep_taddr) {
  678                                                 epp->ep_tsize =
  679                                                     epp->ep_tsize +
  680                                                     epp->ep_taddr -
  681                                                     addr;
  682                                                 epp->ep_taddr = addr;
  683                                         } else
  684                                                 epp->ep_tsize = addr+size -
  685                                                     epp->ep_taddr;
  686                                 }
  687                         }
  688                         break;
  689 
  690                 case PT_SHLIB:
  691                         error = ENOEXEC;
  692                         goto bad;
  693 
  694                 case PT_INTERP:
  695                         /* Already did this one */
  696                 case PT_DYNAMIC:
  697                 case PT_NOTE:
  698                         break;
  699 
  700                 case PT_PHDR:
  701                         /* Note address of program headers (in text segment) */
  702                         phdr = pp->p_vaddr;
  703                         break;
  704 
  705                 default:
  706                         /*
  707                          * Not fatal, we don't need to understand everything
  708                          * :-)
  709                          */
  710                         break;
  711                 }
  712         }
  713 
  714         /*
  715          * Strangely some linux programs may have all load sections marked
  716          * writeable, in this case, textsize is not -1, but rather 0;
  717          */
  718         if (epp->ep_tsize == ELFDEFNNAME(NO_ADDR))
  719                 epp->ep_tsize = 0;
  720         /*
  721          * Another possibility is that it has all load sections marked
  722          * read-only.  Fake a zero-sized data segment right after the
  723          * text segment.
  724          */
  725         if (epp->ep_dsize == ELFDEFNNAME(NO_ADDR)) {
  726                 epp->ep_daddr = round_page(epp->ep_taddr + epp->ep_tsize);
  727                 epp->ep_dsize = 0;
  728         }
  729 
  730         epp->ep_interp = interp;
  731         epp->ep_entry = eh->e_entry;
  732 
  733         /*
  734          * Check if we found a dynamically linked binary and arrange to load
  735          * its interpreter when the exec file is released.
  736          */
  737         if (interp) {
  738                 struct elf_args *ap;
  739 
  740                 ap = malloc(sizeof(struct elf_args), M_TEMP, M_WAITOK);
  741 
  742                 ap->arg_phaddr = phdr;
  743                 ap->arg_phentsize = eh->e_phentsize;
  744                 ap->arg_phnum = eh->e_phnum;
  745                 ap->arg_entry = eh->e_entry;
  746                 ap->arg_os = os;
  747 
  748                 epp->ep_emul_arg = ap;
  749                 epp->ep_interp_pos = pos;
  750         }
  751 
  752 #if defined(COMPAT_SVR4) && defined(i386)
  753 #ifndef ELF_MAP_PAGE_ZERO
  754         /* Dell SVR4 maps page zero, yeuch! */
  755         if (p->p_os == OOS_DELL)
  756 #endif
  757                 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, PAGE_SIZE, 0,
  758                     epp->ep_vp, 0, VM_PROT_READ);
  759 #endif
  760 
  761         free(ph, M_TEMP);
  762         vn_marktext(epp->ep_vp);
  763         return (exec_setup_stack(p, epp));
  764 
  765 bad:
  766         if (interp)
  767                 pool_put(&namei_pool, interp);
  768         free(ph, M_TEMP);
  769         kill_vmcmds(&epp->ep_vmcmds);
  770         return (ENOEXEC);
  771 }
  772 
  773 /*
  774  * Phase II of load. It is now safe to load the interpreter. Info collected
  775  * when loading the program is available for setup of the interpreter.
  776  */
  777 int
  778 ELFNAME2(exec,fixup)(struct proc *p, struct exec_package *epp)
  779 {
  780         char    *interp;
  781         int     error;
  782         struct  elf_args *ap;
  783         AuxInfo ai[ELF_AUX_ENTRIES], *a;
  784         Elf_Addr        pos = epp->ep_interp_pos;
  785 
  786         if (epp->ep_interp == NULL) {
  787                 return (0);
  788         }
  789 
  790         interp = epp->ep_interp;
  791         ap = epp->ep_emul_arg;
  792 
  793         if ((error = ELFNAME(load_file)(p, interp, epp, ap, &pos)) != 0) {
  794                 free(ap, M_TEMP);
  795                 pool_put(&namei_pool, interp);
  796                 kill_vmcmds(&epp->ep_vmcmds);
  797                 return (error);
  798         }
  799         /*
  800          * We have to do this ourselves...
  801          */
  802         error = exec_process_vmcmds(p, epp);
  803 
  804         /*
  805          * Push extra arguments on the stack needed by dynamically
  806          * linked binaries
  807          */
  808         if (error == 0) {
  809                 a = ai;
  810 
  811                 a->au_id = AUX_phdr;
  812                 a->au_v = ap->arg_phaddr;
  813                 a++;
  814 
  815                 a->au_id = AUX_phent;
  816                 a->au_v = ap->arg_phentsize;
  817                 a++;
  818 
  819                 a->au_id = AUX_phnum;
  820                 a->au_v = ap->arg_phnum;
  821                 a++;
  822 
  823                 a->au_id = AUX_pagesz;
  824                 a->au_v = PAGE_SIZE;
  825                 a++;
  826 
  827                 a->au_id = AUX_base;
  828                 a->au_v = ap->arg_interp;
  829                 a++;
  830 
  831                 a->au_id = AUX_flags;
  832                 a->au_v = 0;
  833                 a++;
  834 
  835                 a->au_id = AUX_entry;
  836                 a->au_v = ap->arg_entry;
  837                 a++;
  838 
  839                 a->au_id = AUX_null;
  840                 a->au_v = 0;
  841                 a++;
  842 
  843                 error = copyout(ai, epp->ep_emul_argp, sizeof ai);
  844         }
  845         free(ap, M_TEMP);
  846         pool_put(&namei_pool, interp);
  847         return (error);
  848 }
  849 
  850 /*
  851  * Older ELF binaries use EI_ABIVERSION (formerly EI_BRAND) to brand
  852  * executables.  Newer ELF binaries use EI_OSABI instead.
  853  */
  854 char *
  855 ELFNAME(check_brand)(Elf_Ehdr *eh)
  856 {
  857         if (eh->e_ident[EI_ABIVERSION] == '\0')
  858                 return (NULL);
  859         return (&eh->e_ident[EI_ABIVERSION]);
  860 }
  861 
  862 int
  863 ELFNAME(os_pt_note)(struct proc *p, struct exec_package *epp, Elf_Ehdr *eh,
  864         char *os_name, size_t name_size, size_t desc_size)
  865 {
  866         Elf_Phdr *hph, *ph;
  867         Elf_Note *np = NULL;
  868         size_t phsize;
  869         int error;
  870 
  871         phsize = eh->e_phnum * sizeof(Elf_Phdr);
  872         hph = malloc(phsize, M_TEMP, M_WAITOK);
  873         if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff,
  874             (caddr_t)hph, phsize)) != 0)
  875                 goto out1;
  876 
  877         for (ph = hph;  ph < &hph[eh->e_phnum]; ph++) {
  878                 if (ph->p_type != PT_NOTE ||
  879                     ph->p_filesz > 1024 ||
  880                     ph->p_filesz < sizeof(Elf_Note) + name_size)
  881                         continue;
  882 
  883                 np = malloc(ph->p_filesz, M_TEMP, M_WAITOK);
  884                 if ((error = ELFNAME(read_from)(p, epp->ep_vp, ph->p_offset,
  885                     (caddr_t)np, ph->p_filesz)) != 0)
  886                         goto out2;
  887 
  888 #if 0
  889                 if (np->type != ELF_NOTE_TYPE_OSVERSION) {
  890                         free(np, M_TEMP);
  891                         np = NULL;
  892                         continue;
  893                 }
  894 #endif
  895 
  896                 /* Check the name and description sizes. */
  897                 if (np->namesz != name_size ||
  898                     np->descsz != desc_size)
  899                         goto out3;
  900 
  901                 if (bcmp((np + 1), os_name, name_size))
  902                         goto out3;
  903 
  904                 /* XXX: We could check for the specific emulation here */
  905                 /* All checks succeeded. */
  906                 error = 0;
  907                 goto out2;
  908         }
  909 
  910 out3:
  911         error = ENOEXEC;
  912 out2:
  913         if (np)
  914                 free(np, M_TEMP);
  915 out1:
  916         free(hph, M_TEMP);
  917         return error;
  918 }

/* [<][>][^][v][top][bottom][index][help] */