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/kern/exec_elf32.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 /*      $NetBSD: exec_elf32.c,v 1.136 2008/09/15 18:12:56 rmind Exp $   */
    2 
    3 /*-
    4  * Copyright (c) 1994, 2000, 2005 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Christos Zoulas.
    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  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Copyright (c) 1996 Christopher G. Demetriou
   34  * All rights reserved.
   35  *
   36  * Redistribution and use in source and binary forms, with or without
   37  * modification, are permitted provided that the following conditions
   38  * are met:
   39  * 1. Redistributions of source code must retain the above copyright
   40  *    notice, this list of conditions and the following disclaimer.
   41  * 2. Redistributions in binary form must reproduce the above copyright
   42  *    notice, this list of conditions and the following disclaimer in the
   43  *    documentation and/or other materials provided with the distribution.
   44  * 3. The name of the author may not be used to endorse or promote products
   45  *    derived from this software without specific prior written permission
   46  *
   47  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   48  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   49  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   50  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   51  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   52  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   53  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   54  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   55  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   56  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   57  */
   58 
   59 #include <sys/cdefs.h>
   60 __KERNEL_RCSID(1, "$NetBSD: exec_elf32.c,v 1.136 2008/09/15 18:12:56 rmind Exp $");
   61 
   62 /* If not included by exec_elf64.c, ELFSIZE won't be defined. */
   63 #ifndef ELFSIZE
   64 #define ELFSIZE         32
   65 #endif
   66 
   67 #ifdef _KERNEL_OPT
   68 #include "opt_pax.h"
   69 #endif /* _KERNEL_OPT */
   70 
   71 #include <sys/param.h>
   72 #include <sys/proc.h>
   73 #include <sys/malloc.h>
   74 #include <sys/kmem.h>
   75 #include <sys/namei.h>
   76 #include <sys/vnode.h>
   77 #include <sys/exec.h>
   78 #include <sys/exec_elf.h>
   79 #include <sys/syscall.h>
   80 #include <sys/signalvar.h>
   81 #include <sys/mount.h>
   82 #include <sys/stat.h>
   83 #include <sys/kauth.h>
   84 #include <sys/bitops.h>
   85 
   86 #include <sys/cpu.h>
   87 #include <machine/reg.h>
   88 
   89 #include <compat/common/compat_util.h>
   90 
   91 #include <sys/pax.h>
   92 
   93 extern const struct emul emul_netbsd;
   94 
   95 #define elf_check_header        ELFNAME(check_header)
   96 #define elf_copyargs            ELFNAME(copyargs)
   97 #define elf_load_file           ELFNAME(load_file)
   98 #define elf_load_psection       ELFNAME(load_psection)
   99 #define exec_elf_makecmds       ELFNAME2(exec,makecmds)
  100 #define netbsd_elf_signature    ELFNAME2(netbsd,signature)
  101 #define netbsd_elf_probe        ELFNAME2(netbsd,probe)
  102 
  103 int     elf_load_file(struct lwp *, struct exec_package *, char *,
  104             struct exec_vmcmd_set *, u_long *, struct elf_args *, Elf_Addr *);
  105 void    elf_load_psection(struct exec_vmcmd_set *, struct vnode *,
  106             const Elf_Phdr *, Elf_Addr *, u_long *, int *, int);
  107 
  108 int     netbsd_elf_signature(struct lwp *, struct exec_package *, Elf_Ehdr *);
  109 int     netbsd_elf_probe(struct lwp *, struct exec_package *, void *, char *,
  110             vaddr_t *);
  111 
  112 /* round up and down to page boundaries. */
  113 #define ELF_ROUND(a, b)         (((a) + (b) - 1) & ~((b) - 1))
  114 #define ELF_TRUNC(a, b)         ((a) & ~((b) - 1))
  115 
  116 #define MAXPHNUM        50
  117 
  118 #ifdef PAX_ASLR
  119 /*
  120  * We don't move this code in kern_pax.c because it is compiled twice.
  121  */
  122 static void
  123 pax_aslr_elf(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh,
  124     Elf_Phdr *ph)
  125 {
  126         size_t pax_align = 0, pax_offset, i;
  127         uint32_t r;
  128 
  129         if (!pax_aslr_active(l))
  130                 return;
  131 
  132         /*
  133          * find align XXX: not all sections might have the same
  134          * alignment
  135          */
  136         for (i = 0; i < eh->e_phnum; i++)
  137                 if (ph[i].p_type == PT_LOAD) {
  138                         pax_align = ph[i].p_align;
  139                         break;
  140                 }
  141 
  142         r = arc4random();
  143 
  144         if (pax_align == 0)
  145                 pax_align = PGSHIFT;
  146 #ifdef DEBUG_ASLR
  147         uprintf("r=0x%x a=0x%x p=0x%x Delta=0x%lx\n", r,
  148             ilog2(pax_align), PGSHIFT, PAX_ASLR_DELTA(r,
  149                 ilog2(pax_align), PAX_ASLR_DELTA_EXEC_LEN));
  150 #endif
  151         pax_offset = ELF_TRUNC(PAX_ASLR_DELTA(r,
  152             ilog2(pax_align), PAX_ASLR_DELTA_EXEC_LEN), pax_align);
  153 
  154         for (i = 0; i < eh->e_phnum; i++)
  155                 ph[i].p_vaddr += pax_offset;
  156         eh->e_entry += pax_offset;
  157 #ifdef DEBUG_ASLR
  158         uprintf("pax offset=0x%zx entry=0x%llx\n",
  159             pax_offset, (unsigned long long)eh->e_entry);
  160 #endif
  161 }
  162 #endif /* PAX_ASLR */
  163 
  164 /*
  165  * Copy arguments onto the stack in the normal way, but add some
  166  * extra information in case of dynamic binding.
  167  */
  168 int
  169 elf_copyargs(struct lwp *l, struct exec_package *pack,
  170     struct ps_strings *arginfo, char **stackp, void *argp)
  171 {
  172         size_t len, vlen;
  173         AuxInfo ai[ELF_AUX_ENTRIES], *a, *execname;
  174         struct elf_args *ap;
  175         int error;
  176 
  177         if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0)
  178                 return error;
  179 
  180         a = ai;
  181         execname = NULL;
  182 
  183         /*
  184          * Push extra arguments on the stack needed by dynamically
  185          * linked binaries
  186          */
  187         if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
  188                 struct vattr *vap = pack->ep_vap;
  189 
  190                 a->a_type = AT_PHDR;
  191                 a->a_v = ap->arg_phaddr;
  192                 a++;
  193 
  194                 a->a_type = AT_PHENT;
  195                 a->a_v = ap->arg_phentsize;
  196                 a++;
  197 
  198                 a->a_type = AT_PHNUM;
  199                 a->a_v = ap->arg_phnum;
  200                 a++;
  201 
  202                 a->a_type = AT_PAGESZ;
  203                 a->a_v = PAGE_SIZE;
  204                 a++;
  205 
  206                 a->a_type = AT_BASE;
  207                 a->a_v = ap->arg_interp;
  208                 a++;
  209 
  210                 a->a_type = AT_FLAGS;
  211                 a->a_v = 0;
  212                 a++;
  213 
  214                 a->a_type = AT_ENTRY;
  215                 a->a_v = ap->arg_entry;
  216                 a++;
  217 
  218                 a->a_type = AT_EUID;
  219                 if (vap->va_mode & S_ISUID)
  220                         a->a_v = vap->va_uid;
  221                 else
  222                         a->a_v = kauth_cred_geteuid(l->l_cred);
  223                 a++;
  224 
  225                 a->a_type = AT_RUID;
  226                 a->a_v = kauth_cred_getuid(l->l_cred);
  227                 a++;
  228 
  229                 a->a_type = AT_EGID;
  230                 if (vap->va_mode & S_ISGID)
  231                         a->a_v = vap->va_gid;
  232                 else
  233                         a->a_v = kauth_cred_getegid(l->l_cred);
  234                 a++;
  235 
  236                 a->a_type = AT_RGID;
  237                 a->a_v = kauth_cred_getgid(l->l_cred);
  238                 a++;
  239 
  240                 if (pack->ep_path) {
  241                         execname = a;
  242                         a->a_type = AT_SUN_EXECNAME;
  243                         a++;
  244                 }
  245 
  246                 free(ap, M_TEMP);
  247                 pack->ep_emul_arg = NULL;
  248         }
  249 
  250         a->a_type = AT_NULL;
  251         a->a_v = 0;
  252         a++;
  253 
  254         vlen = (a - ai) * sizeof(AuxInfo);
  255 
  256         if (execname) {
  257                 char *path = pack->ep_path;
  258                 execname->a_v = (uintptr_t)(*stackp + vlen);
  259                 len = strlen(path) + 1;
  260                 if ((error = copyout(path, (*stackp + vlen), len)) != 0)
  261                         return error;
  262                 len = ALIGN(len);
  263         } else
  264                 len = 0;
  265 
  266         if ((error = copyout(ai, *stackp, vlen)) != 0)
  267                 return error;
  268         *stackp += vlen + len;
  269 
  270         return 0;
  271 }
  272 
  273 /*
  274  * elf_check_header():
  275  *
  276  * Check header for validity; return 0 of ok ENOEXEC if error
  277  */
  278 int
  279 elf_check_header(Elf_Ehdr *eh, int type)
  280 {
  281 
  282         if (memcmp(eh->e_ident, ELFMAG, SELFMAG) != 0 ||
  283             eh->e_ident[EI_CLASS] != ELFCLASS)
  284                 return ENOEXEC;
  285 
  286         switch (eh->e_machine) {
  287 
  288         ELFDEFNNAME(MACHDEP_ID_CASES)
  289 
  290         default:
  291                 return ENOEXEC;
  292         }
  293 
  294         if (ELF_EHDR_FLAGS_OK(eh) == 0)
  295                 return ENOEXEC;
  296 
  297         if (eh->e_type != type)
  298                 return ENOEXEC;
  299 
  300         if (eh->e_shnum > 32768 || eh->e_phnum > 128)
  301                 return ENOEXEC;
  302 
  303         return 0;
  304 }
  305 
  306 /*
  307  * elf_load_psection():
  308  *
  309  * Load a psection at the appropriate address
  310  */
  311 void
  312 elf_load_psection(struct exec_vmcmd_set *vcset, struct vnode *vp,
  313     const Elf_Phdr *ph, Elf_Addr *addr, u_long *size, int *prot, int flags)
  314 {
  315         u_long msize, psize, rm, rf;
  316         long diff, offset;
  317 
  318         /*
  319          * If the user specified an address, then we load there.
  320          */
  321         if (*addr == ELFDEFNNAME(NO_ADDR))
  322                 *addr = ph->p_vaddr;
  323 
  324         if (ph->p_align > 1) {
  325                 /*
  326                  * Make sure we are virtually aligned as we are supposed to be.
  327                  */
  328                 diff = ph->p_vaddr - ELF_TRUNC(ph->p_vaddr, ph->p_align);
  329                 KASSERT(*addr - diff == ELF_TRUNC(*addr, ph->p_align));
  330                 /*
  331                  * But make sure to not map any pages before the start of the
  332                  * psection by limiting the difference to within a page.
  333                  */
  334                 diff &= PAGE_MASK;
  335         } else
  336                 diff = 0;
  337 
  338         *prot |= (ph->p_flags & PF_R) ? VM_PROT_READ : 0;
  339         *prot |= (ph->p_flags & PF_W) ? VM_PROT_WRITE : 0;
  340         *prot |= (ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0;
  341 
  342         /*
  343          * Adjust everything so it all starts on a page boundary.
  344          */
  345         *addr -= diff;
  346         offset = ph->p_offset - diff;
  347         *size = ph->p_filesz + diff;
  348         msize = ph->p_memsz + diff;
  349 
  350         if (ph->p_align >= PAGE_SIZE) {
  351                 if ((ph->p_flags & PF_W) != 0) {
  352                         /*
  353                          * Because the pagedvn pager can't handle zero fill
  354                          * of the last data page if it's not page aligned we
  355                          * map the last page readvn.
  356                          */
  357                         psize = trunc_page(*size);
  358                 } else {
  359                         psize = round_page(*size);
  360                 }
  361         } else {
  362                 psize = *size;
  363         }
  364 
  365         if (psize > 0) {
  366                 NEW_VMCMD2(vcset, ph->p_align < PAGE_SIZE ?
  367                     vmcmd_map_readvn : vmcmd_map_pagedvn, psize, *addr, vp,
  368                     offset, *prot, flags);
  369                 flags &= VMCMD_RELATIVE;
  370         }
  371         if (psize < *size) {
  372                 NEW_VMCMD2(vcset, vmcmd_map_readvn, *size - psize,
  373                     *addr + psize, vp, offset + psize, *prot, flags);
  374         }
  375 
  376         /*
  377          * Check if we need to extend the size of the segment (does
  378          * bss extend page the next page boundary)?
  379          */
  380         rm = round_page(*addr + msize);
  381         rf = round_page(*addr + *size);
  382 
  383         if (rm != rf) {
  384                 NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP,
  385                     0, *prot, flags & VMCMD_RELATIVE);
  386                 *size = msize;
  387         }
  388 }
  389 
  390 /*
  391  * elf_load_file():
  392  *
  393  * Load a file (interpreter/library) pointed to by path
  394  * [stolen from coff_load_shlib()]. Made slightly generic
  395  * so it might be used externally.
  396  */
  397 int
  398 elf_load_file(struct lwp *l, struct exec_package *epp, char *path,
  399     struct exec_vmcmd_set *vcset, u_long *entryoff, struct elf_args *ap,
  400     Elf_Addr *last)
  401 {
  402         int error, i;
  403         struct vnode *vp;
  404         struct vattr attr;
  405         Elf_Ehdr eh;
  406         Elf_Phdr *ph = NULL;
  407         const Elf_Phdr *ph0;
  408         const Elf_Phdr *base_ph;
  409         const Elf_Phdr *last_ph;
  410         u_long phsize;
  411         Elf_Addr addr = *last;
  412         struct proc *p;
  413 
  414         p = l->l_proc;
  415 
  416         /*
  417          * 1. open file
  418          * 2. read filehdr
  419          * 3. map text, data, and bss out of it using VM_*
  420          */
  421         vp = epp->ep_interp;
  422         if (vp == NULL) {
  423                 error = emul_find_interp(l, epp, path);
  424                 if (error != 0)
  425                         return error;
  426                 vp = epp->ep_interp;
  427         }
  428         /* We'll tidy this ourselves - otherwise we have locking issues */
  429         epp->ep_interp = NULL;
  430         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
  431 
  432         /*
  433          * Similarly, if it's not marked as executable, or it's not a regular
  434          * file, we don't allow it to be used.
  435          */
  436         if (vp->v_type != VREG) {
  437                 error = EACCES;
  438                 goto badunlock;
  439         }
  440         if ((error = VOP_ACCESS(vp, VEXEC, l->l_cred)) != 0)
  441                 goto badunlock;
  442 
  443         /* get attributes */
  444         if ((error = VOP_GETATTR(vp, &attr, l->l_cred)) != 0)
  445                 goto badunlock;
  446 
  447         /*
  448          * Check mount point.  Though we're not trying to exec this binary,
  449          * we will be executing code from it, so if the mount point
  450          * disallows execution or set-id-ness, we punt or kill the set-id.
  451          */
  452         if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
  453                 error = EACCES;
  454                 goto badunlock;
  455         }
  456         if (vp->v_mount->mnt_flag & MNT_NOSUID)
  457                 epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID);
  458 
  459 #ifdef notyet /* XXX cgd 960926 */
  460         XXX cgd 960926: (maybe) VOP_OPEN it (and VOP_CLOSE in copyargs?)
  461 #endif
  462 
  463         error = vn_marktext(vp);
  464         if (error)
  465                 goto badunlock;
  466 
  467         VOP_UNLOCK(vp, 0);
  468 
  469         if ((error = exec_read_from(l, vp, 0, &eh, sizeof(eh))) != 0)
  470                 goto bad;
  471 
  472         if ((error = elf_check_header(&eh, ET_DYN)) != 0)
  473                 goto bad;
  474 
  475         if (eh.e_phnum > MAXPHNUM || eh.e_phnum == 0) {
  476                 error = ENOEXEC;
  477                 goto bad;
  478         }
  479 
  480         phsize = eh.e_phnum * sizeof(Elf_Phdr);
  481         ph = kmem_alloc(phsize, KM_SLEEP);
  482 
  483         if ((error = exec_read_from(l, vp, eh.e_phoff, ph, phsize)) != 0)
  484                 goto bad;
  485 
  486 #ifdef ELF_INTERP_NON_RELOCATABLE
  487         /*
  488          * Evil hack:  Only MIPS should be non-relocatable, and the
  489          * psections should have a high address (typically 0x5ffe0000).
  490          * If it's now relocatable, it should be linked at 0 and the
  491          * psections should have zeros in the upper part of the address.
  492          * Otherwise, force the load at the linked address.
  493          */
  494         if (*last == ELF_LINK_ADDR && (ph->p_vaddr & 0xffff0000) == 0)
  495                 *last = ELFDEFNNAME(NO_ADDR);
  496 #endif
  497 
  498         /*
  499          * If no position to load the interpreter was set by a probe
  500          * function, pick the same address that a non-fixed mmap(0, ..)
  501          * would (i.e. something safely out of the way).
  502          */
  503         if (*last == ELFDEFNNAME(NO_ADDR)) {
  504                 u_long limit = 0;
  505                 /*
  506                  * Find the start and ending addresses of the psections to
  507                  * be loaded.  This will give us the size.
  508                  */
  509                 for (i = 0, ph0 = ph, base_ph = NULL; i < eh.e_phnum;
  510                      i++, ph0++) {
  511                         if (ph0->p_type == PT_LOAD) {
  512                                 u_long psize = ph0->p_vaddr + ph0->p_memsz;
  513                                 if (base_ph == NULL)
  514                                         base_ph = ph0;
  515                                 if (psize > limit)
  516                                         limit = psize;
  517                         }
  518                 }
  519 
  520                 if (base_ph == NULL) {
  521                         error = ENOEXEC;
  522                         goto bad;
  523                 }
  524 
  525                 /*
  526                  * Now compute the size and load address.
  527                  */
  528                 addr = (*epp->ep_esch->es_emul->e_vm_default_addr)(p,
  529                     epp->ep_daddr,
  530                     round_page(limit) - trunc_page(base_ph->p_vaddr));
  531         } else
  532                 addr = *last; /* may be ELF_LINK_ADDR */
  533 
  534         /*
  535          * Load all the necessary sections
  536          */
  537         for (i = 0, ph0 = ph, base_ph = NULL, last_ph = NULL;
  538              i < eh.e_phnum; i++, ph0++) {
  539                 switch (ph0->p_type) {
  540                 case PT_LOAD: {
  541                         u_long size;
  542                         int prot = 0;
  543                         int flags;
  544 
  545                         if (base_ph == NULL) {
  546                                 /*
  547                                  * First encountered psection is always the
  548                                  * base psection.  Make sure it's aligned
  549                                  * properly (align down for topdown and align
  550                                  * upwards for not topdown).
  551                                  */
  552                                 base_ph = ph0;
  553                                 flags = VMCMD_BASE;
  554                                 if (addr == ELF_LINK_ADDR)
  555                                         addr = ph0->p_vaddr;
  556                                 if (p->p_vmspace->vm_map.flags & VM_MAP_TOPDOWN)
  557                                         addr = ELF_TRUNC(addr, ph0->p_align);
  558                                 else
  559                                         addr = ELF_ROUND(addr, ph0->p_align);
  560                         } else {
  561                                 u_long limit = round_page(last_ph->p_vaddr
  562                                     + last_ph->p_memsz);
  563                                 u_long base = trunc_page(ph0->p_vaddr);
  564 
  565                                 /*
  566                                  * If there is a gap in between the psections,
  567                                  * map it as inaccessible so nothing else
  568                                  * mmap'ed will be placed there.
  569                                  */
  570                                 if (limit != base) {
  571                                         NEW_VMCMD2(vcset, vmcmd_map_zero,
  572                                             base - limit,
  573                                             limit - base_ph->p_vaddr, NULLVP,
  574                                             0, VM_PROT_NONE, VMCMD_RELATIVE);
  575                                 }
  576 
  577                                 addr = ph0->p_vaddr - base_ph->p_vaddr;
  578                                 flags = VMCMD_RELATIVE;
  579                         }
  580                         last_ph = ph0;
  581                         elf_load_psection(vcset, vp, &ph[i], &addr,
  582                             &size, &prot, flags);
  583                         /*
  584                          * If entry is within this psection then this
  585                          * must contain the .text section.  *entryoff is
  586                          * relative to the base psection.
  587                          */
  588                         if (eh.e_entry >= ph0->p_vaddr &&
  589                             eh.e_entry < (ph0->p_vaddr + size)) {
  590                                 *entryoff = eh.e_entry - base_ph->p_vaddr;
  591                         }
  592                         addr += size;
  593                         break;
  594                 }
  595 
  596                 case PT_DYNAMIC:
  597                 case PT_PHDR:
  598                         break;
  599 
  600                 case PT_NOTE:
  601                         break;
  602 
  603                 default:
  604                         break;
  605                 }
  606         }
  607 
  608         kmem_free(ph, phsize);
  609         /*
  610          * This value is ignored if TOPDOWN.
  611          */
  612         *last = addr;
  613         vrele(vp);
  614         return 0;
  615 
  616 badunlock:
  617         VOP_UNLOCK(vp, 0);
  618 
  619 bad:
  620         if (ph != NULL)
  621                 kmem_free(ph, phsize);
  622 #ifdef notyet /* XXX cgd 960926 */
  623         (maybe) VOP_CLOSE it
  624 #endif
  625         vrele(vp);
  626         return error;
  627 }
  628 
  629 /*
  630  * exec_elf_makecmds(): Prepare an Elf binary's exec package
  631  *
  632  * First, set of the various offsets/lengths in the exec package.
  633  *
  634  * Then, mark the text image busy (so it can be demand paged) or error
  635  * out if this is not possible.  Finally, set up vmcmds for the
  636  * text, data, bss, and stack segments.
  637  */
  638 int
  639 exec_elf_makecmds(struct lwp *l, struct exec_package *epp)
  640 {
  641         Elf_Ehdr *eh = epp->ep_hdr;
  642         Elf_Phdr *ph, *pp;
  643         Elf_Addr phdr = 0, pos = 0;
  644         int error, i, nload;
  645         char *interp = NULL;
  646         u_long phsize;
  647         struct proc *p;
  648         bool is_dyn;
  649 
  650         if (epp->ep_hdrvalid < sizeof(Elf_Ehdr))
  651                 return ENOEXEC;
  652 
  653         is_dyn = elf_check_header(eh, ET_DYN) == 0;
  654         /*
  655          * XXX allow for executing shared objects. It seems silly
  656          * but other ELF-based systems allow it as well.
  657          */
  658         if (elf_check_header(eh, ET_EXEC) != 0 && !is_dyn)
  659                 return ENOEXEC;
  660 
  661         if (eh->e_phnum > MAXPHNUM || eh->e_phnum == 0)
  662                 return ENOEXEC;
  663 
  664         error = vn_marktext(epp->ep_vp);
  665         if (error)
  666                 return error;
  667 
  668         /*
  669          * Allocate space to hold all the program headers, and read them
  670          * from the file
  671          */
  672         p = l->l_proc;
  673         phsize = eh->e_phnum * sizeof(Elf_Phdr);
  674         ph = kmem_alloc(phsize, KM_SLEEP);
  675 
  676         if ((error = exec_read_from(l, epp->ep_vp, eh->e_phoff, ph, phsize)) !=
  677             0)
  678                 goto bad;
  679 
  680         epp->ep_taddr = epp->ep_tsize = ELFDEFNNAME(NO_ADDR);
  681         epp->ep_daddr = epp->ep_dsize = ELFDEFNNAME(NO_ADDR);
  682 
  683         for (i = 0; i < eh->e_phnum; i++) {
  684                 pp = &ph[i];
  685                 if (pp->p_type == PT_INTERP) {
  686                         if (pp->p_filesz >= MAXPATHLEN) {
  687                                 error = ENOEXEC;
  688                                 goto bad;
  689                         }
  690                         interp = PNBUF_GET();
  691                         interp[0] = '\0';
  692                         if ((error = exec_read_from(l, epp->ep_vp,
  693                             pp->p_offset, interp, pp->p_filesz)) != 0)
  694                                 goto bad;
  695                         break;
  696                 }
  697         }
  698 
  699         /*
  700          * On the same architecture, we may be emulating different systems.
  701          * See which one will accept this executable.
  702          *
  703          * Probe functions would normally see if the interpreter (if any)
  704          * exists. Emulation packages may possibly replace the interpreter in
  705          * interp[] with a changed path (/emul/xxx/<path>).
  706          */
  707         pos = ELFDEFNNAME(NO_ADDR);
  708         if (epp->ep_esch->u.elf_probe_func) {
  709                 vaddr_t startp = (vaddr_t)pos;
  710 
  711                 error = (*epp->ep_esch->u.elf_probe_func)(l, epp, eh, interp,
  712                                                           &startp);
  713                 if (error)
  714                         goto bad;
  715                 pos = (Elf_Addr)startp;
  716         }
  717 
  718 #if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD) || defined(PAX_ASLR)
  719         p->p_pax = epp->ep_pax_flags;
  720 #endif /* PAX_MPROTECT || PAX_SEGVGUARD || PAX_ASLR */
  721 
  722 #ifdef PAX_ASLR
  723         if (is_dyn)
  724                 pax_aslr_elf(l, epp, eh, ph);
  725 #endif /* PAX_ASLR */
  726 
  727         /*
  728          * Load all the necessary sections
  729          */
  730         for (i = nload = 0; i < eh->e_phnum; i++) {
  731                 Elf_Addr  addr = ELFDEFNNAME(NO_ADDR);
  732                 u_long size = 0;
  733                 int prot = 0;
  734 
  735                 pp = &ph[i];
  736 
  737                 switch (ph[i].p_type) {
  738                 case PT_LOAD:
  739                         /*
  740                          * XXX
  741                          * Can handle only 2 sections: text and data
  742                          */
  743                         if (nload++ == 2) {
  744                                 error = ENOEXEC;
  745                                 goto bad;
  746                         }
  747                         elf_load_psection(&epp->ep_vmcmds, epp->ep_vp,
  748                             &ph[i], &addr, &size, &prot, VMCMD_FIXED);
  749 
  750                         /*
  751                          * Decide whether it's text or data by looking
  752                          * at the entry point.
  753                          */
  754                         if (eh->e_entry >= addr &&
  755                             eh->e_entry < (addr + size)) {
  756                                 epp->ep_taddr = addr;
  757                                 epp->ep_tsize = size;
  758                                 if (epp->ep_daddr == ELFDEFNNAME(NO_ADDR)) {
  759                                         epp->ep_daddr = addr;
  760                                         epp->ep_dsize = size;
  761                                 }
  762                         } else {
  763                                 epp->ep_daddr = addr;
  764                                 epp->ep_dsize = size;
  765                         }
  766                         break;
  767 
  768                 case PT_SHLIB:
  769                         /* SCO has these sections. */
  770                 case PT_INTERP:
  771                         /* Already did this one. */
  772                 case PT_DYNAMIC:
  773                         break;
  774                 case PT_NOTE:
  775                         break;
  776                 case PT_PHDR:
  777                         /* Note address of program headers (in text segment) */
  778                         phdr = pp->p_vaddr;
  779                         break;
  780 
  781                 default:
  782                         /*
  783                          * Not fatal; we don't need to understand everything.
  784                          */
  785                         break;
  786                 }
  787         }
  788 
  789         /*
  790          * Check if we found a dynamically linked binary and arrange to load
  791          * its interpreter
  792          */
  793         if (interp) {
  794                 struct elf_args *ap;
  795                 int j = epp->ep_vmcmds.evs_used;
  796                 u_long interp_offset;
  797 
  798                 MALLOC(ap, struct elf_args *, sizeof(struct elf_args),
  799                     M_TEMP, M_WAITOK);
  800                 if ((error = elf_load_file(l, epp, interp,
  801                     &epp->ep_vmcmds, &interp_offset, ap, &pos)) != 0) {
  802                         FREE(ap, M_TEMP);
  803                         goto bad;
  804                 }
  805                 ap->arg_interp = epp->ep_vmcmds.evs_cmds[j].ev_addr;
  806                 epp->ep_entry = ap->arg_interp + interp_offset;
  807                 ap->arg_phaddr = phdr;
  808 
  809                 ap->arg_phentsize = eh->e_phentsize;
  810                 ap->arg_phnum = eh->e_phnum;
  811                 ap->arg_entry = eh->e_entry;
  812 
  813                 epp->ep_emul_arg = ap;
  814 
  815                 PNBUF_PUT(interp);
  816         } else
  817                 epp->ep_entry = eh->e_entry;
  818 
  819 #ifdef ELF_MAP_PAGE_ZERO
  820         /* Dell SVR4 maps page zero, yeuch! */
  821         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, PAGE_SIZE, 0,
  822             epp->ep_vp, 0, VM_PROT_READ);
  823 #endif
  824         kmem_free(ph, phsize);
  825         return (*epp->ep_esch->es_setup_stack)(l, epp);
  826 
  827 bad:
  828         if (interp)
  829                 PNBUF_PUT(interp);
  830         kmem_free(ph, phsize);
  831         kill_vmcmds(&epp->ep_vmcmds);
  832         return error;
  833 }
  834 
  835 int
  836 netbsd_elf_signature(struct lwp *l, struct exec_package *epp,
  837     Elf_Ehdr *eh)
  838 {
  839         size_t i;
  840         Elf_Phdr *ph;
  841         size_t phsize;
  842         int error;
  843         int isnetbsd = 0;
  844         char *ndata;
  845 
  846         epp->ep_pax_flags = 0;
  847         if (eh->e_phnum > MAXPHNUM || eh->e_phnum == 0)
  848                 return ENOEXEC;
  849 
  850         phsize = eh->e_phnum * sizeof(Elf_Phdr);
  851         ph = kmem_alloc(phsize, KM_SLEEP);
  852         error = exec_read_from(l, epp->ep_vp, eh->e_phoff, ph, phsize);
  853         if (error)
  854                 goto out;
  855 
  856         for (i = 0; i < eh->e_phnum; i++) {
  857                 Elf_Phdr *ephp = &ph[i];
  858                 Elf_Nhdr *np;
  859 
  860                 if (ephp->p_type != PT_NOTE ||
  861                     ephp->p_filesz > 1024 ||
  862                     ephp->p_filesz < sizeof(Elf_Nhdr) + ELF_NOTE_NETBSD_NAMESZ)
  863                         continue;
  864 
  865                 np = kmem_alloc(ephp->p_filesz, KM_SLEEP);
  866                 error = exec_read_from(l, epp->ep_vp, ephp->p_offset, np,
  867                     ephp->p_filesz);
  868                 if (error)
  869                         goto next;
  870 
  871                 ndata = (char *)(np + 1);
  872                 switch (np->n_type) {
  873                 case ELF_NOTE_TYPE_NETBSD_TAG:
  874                         if (np->n_namesz != ELF_NOTE_NETBSD_NAMESZ ||
  875                             np->n_descsz != ELF_NOTE_NETBSD_DESCSZ ||
  876                             memcmp(ndata, ELF_NOTE_NETBSD_NAME,
  877                             ELF_NOTE_NETBSD_NAMESZ))
  878                                 goto next;
  879                         isnetbsd = 1;
  880                         break;
  881 
  882                 case ELF_NOTE_TYPE_PAX_TAG:
  883                         if (np->n_namesz != ELF_NOTE_PAX_NAMESZ ||
  884                             np->n_descsz != ELF_NOTE_PAX_DESCSZ ||
  885                             memcmp(ndata, ELF_NOTE_PAX_NAME,
  886                             ELF_NOTE_PAX_NAMESZ))
  887                                 goto next;
  888                         (void)memcpy(&epp->ep_pax_flags,
  889                             ndata + ELF_NOTE_PAX_NAMESZ,
  890                             sizeof(epp->ep_pax_flags));
  891                         break;
  892 
  893                 default:
  894                         break;
  895                 }
  896 
  897 next:
  898                 kmem_free(np, ephp->p_filesz);
  899                 continue;
  900         }
  901 
  902         error = isnetbsd ? 0 : ENOEXEC;
  903 out:
  904         kmem_free(ph, phsize);
  905         return error;
  906 }
  907 
  908 int
  909 netbsd_elf_probe(struct lwp *l, struct exec_package *epp, void *eh, char *itp,
  910     vaddr_t *pos)
  911 {
  912         int error;
  913 
  914         if ((error = netbsd_elf_signature(l, epp, eh)) != 0)
  915                 return error;
  916 #ifdef ELF_INTERP_NON_RELOCATABLE
  917         *pos = ELF_LINK_ADDR;
  918 #endif
  919         return 0;
  920 }

Cache object: 5ddf9068d175d1976360bf7d0ed841c3


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