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_elf.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_elf.c,v 1.104 2022/10/26 23:20:36 riastradh Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 1994, 2000, 2005, 2015, 2020 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 and Maxime Villard.
    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_elf.c,v 1.104 2022/10/26 23:20:36 riastradh Exp $");
   61 
   62 #ifdef _KERNEL_OPT
   63 #include "opt_pax.h"
   64 #endif /* _KERNEL_OPT */
   65 
   66 #include <sys/param.h>
   67 #include <sys/proc.h>
   68 #include <sys/kmem.h>
   69 #include <sys/namei.h>
   70 #include <sys/vnode.h>
   71 #include <sys/exec.h>
   72 #include <sys/exec_elf.h>
   73 #include <sys/syscall.h>
   74 #include <sys/signalvar.h>
   75 #include <sys/mount.h>
   76 #include <sys/stat.h>
   77 #include <sys/kauth.h>
   78 #include <sys/bitops.h>
   79 
   80 #include <sys/cpu.h>
   81 #include <machine/reg.h>
   82 
   83 #include <compat/common/compat_util.h>
   84 
   85 #include <sys/pax.h>
   86 #include <uvm/uvm_param.h>
   87 
   88 #define elf_check_header        ELFNAME(check_header)
   89 #define elf_copyargs            ELFNAME(copyargs)
   90 #define elf_populate_auxv       ELFNAME(populate_auxv)
   91 #define elf_load_interp         ELFNAME(load_interp)
   92 #define elf_load_psection       ELFNAME(load_psection)
   93 #define exec_elf_makecmds       ELFNAME2(exec,makecmds)
   94 #define netbsd_elf_signature    ELFNAME2(netbsd,signature)
   95 #define netbsd_elf_note         ELFNAME2(netbsd,note)
   96 #define netbsd_elf_probe        ELFNAME2(netbsd,probe)
   97 #define coredump                ELFNAMEEND(coredump)
   98 #define elf_free_emul_arg       ELFNAME(free_emul_arg)
   99 
  100 static int
  101 elf_load_interp(struct lwp *, struct exec_package *, char *,
  102     struct exec_vmcmd_set *, u_long *, Elf_Addr *);
  103 static int
  104 elf_load_psection(struct exec_vmcmd_set *, struct vnode *, const Elf_Phdr *,
  105     Elf_Addr *, u_long *, int);
  106 
  107 int     netbsd_elf_signature(struct lwp *, struct exec_package *, Elf_Ehdr *);
  108 int     netbsd_elf_note(struct exec_package *, const Elf_Nhdr *, const char *,
  109             const char *);
  110 int     netbsd_elf_probe(struct lwp *, struct exec_package *, void *, char *,
  111             vaddr_t *);
  112 
  113 static void     elf_free_emul_arg(void *);
  114 
  115 #ifdef DEBUG_ELF
  116 #define DPRINTF(a, ...) printf("%s: " a "\n", __func__, ##__VA_ARGS__)
  117 #else
  118 #define DPRINTF(a, ...)
  119 #endif
  120 
  121 /* round up and down to page boundaries. */
  122 #define ELF_ROUND(a, b)         (((a) + (b) - 1) & ~((b) - 1))
  123 #define ELF_TRUNC(a, b)         ((a) & ~((b) - 1))
  124 
  125 static int
  126 elf_placedynexec(struct exec_package *epp, Elf_Ehdr *eh, Elf_Phdr *ph)
  127 {
  128         Elf_Addr align, offset;
  129         int i;
  130 
  131         for (align = 1, i = 0; i < eh->e_phnum; i++)
  132                 if (ph[i].p_type == PT_LOAD && ph[i].p_align > align)
  133                         align = ph[i].p_align;
  134 
  135         offset = (Elf_Addr)pax_aslr_exec_offset(epp, align);
  136         if (offset < epp->ep_vm_minaddr)
  137                 offset = roundup(epp->ep_vm_minaddr, align);
  138         if ((offset & (align - 1)) != 0) {
  139                 DPRINTF("bad offset=%#jx align=%#jx",
  140                     (uintmax_t)offset, (uintmax_t)align);
  141                 return EINVAL;
  142         }
  143 
  144         for (i = 0; i < eh->e_phnum; i++)
  145                 ph[i].p_vaddr += offset;
  146         epp->ep_entryoffset = offset;
  147         eh->e_entry += offset;
  148         return 0;
  149 }
  150 
  151 
  152 int
  153 elf_populate_auxv(struct lwp *l, struct exec_package *pack, char **stackp)
  154 {
  155         size_t len, vlen;
  156         AuxInfo ai[ELF_AUX_ENTRIES], *a, *execname;
  157         struct elf_args *ap;
  158         char *path = l->l_proc->p_path;
  159         int error;
  160 
  161         execname = NULL;
  162         a = ai;
  163 
  164         memset(ai, 0, sizeof(ai));
  165 
  166         /*
  167          * Push extra arguments on the stack needed by dynamically
  168          * linked binaries
  169          */
  170         if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
  171                 struct vattr *vap = pack->ep_vap;
  172 
  173                 a->a_type = AT_PHDR;
  174                 a->a_v = ap->arg_phaddr;
  175                 a++;
  176 
  177                 a->a_type = AT_PHENT;
  178                 a->a_v = ap->arg_phentsize;
  179                 a++;
  180 
  181                 a->a_type = AT_PHNUM;
  182                 a->a_v = ap->arg_phnum;
  183                 a++;
  184 
  185                 a->a_type = AT_PAGESZ;
  186                 a->a_v = PAGE_SIZE;
  187                 a++;
  188 
  189                 a->a_type = AT_BASE;
  190                 a->a_v = ap->arg_interp;
  191                 a++;
  192 
  193                 a->a_type = AT_FLAGS;
  194                 a->a_v = 0;
  195                 a++;
  196 
  197                 a->a_type = AT_ENTRY;
  198                 a->a_v = ap->arg_entry;
  199                 a++;
  200 
  201                 a->a_type = AT_EUID;
  202                 if (vap->va_mode & S_ISUID)
  203                         a->a_v = vap->va_uid;
  204                 else
  205                         a->a_v = kauth_cred_geteuid(l->l_cred);
  206                 a++;
  207 
  208                 a->a_type = AT_RUID;
  209                 a->a_v = kauth_cred_getuid(l->l_cred);
  210                 a++;
  211 
  212                 a->a_type = AT_EGID;
  213                 if (vap->va_mode & S_ISGID)
  214                         a->a_v = vap->va_gid;
  215                 else
  216                         a->a_v = kauth_cred_getegid(l->l_cred);
  217                 a++;
  218 
  219                 a->a_type = AT_RGID;
  220                 a->a_v = kauth_cred_getgid(l->l_cred);
  221                 a++;
  222 
  223                 a->a_type = AT_STACKBASE;
  224                 a->a_v = l->l_proc->p_stackbase;
  225                 a++;
  226 
  227                 /* "/" means fexecve(2) could not resolve the pathname */
  228                 if (path[0] == '/' && path[1] != '\0') {
  229                         execname = a;
  230                         a->a_type = AT_SUN_EXECNAME;
  231                         a++;
  232                 }
  233 
  234                 exec_free_emul_arg(pack);
  235         }
  236 
  237         a->a_type = AT_NULL;
  238         a->a_v = 0;
  239         a++;
  240 
  241         vlen = (a - ai) * sizeof(ai[0]);
  242 
  243         KASSERT(vlen <= sizeof(ai));
  244 
  245         if (execname) {
  246                 execname->a_v = (uintptr_t)(*stackp + vlen);
  247                 len = strlen(path) + 1;
  248                 if ((error = copyout(path, (*stackp + vlen), len)) != 0)
  249                         return error;
  250                 len = ALIGN(len);
  251         } else {
  252                 len = 0;
  253         }
  254 
  255         if ((error = copyout(ai, *stackp, vlen)) != 0)
  256                 return error;
  257         *stackp += vlen + len;
  258 
  259         return 0;
  260 }
  261 
  262 /*
  263  * Copy arguments onto the stack in the normal way, but add some
  264  * extra information in case of dynamic binding.
  265  */
  266 int
  267 elf_copyargs(struct lwp *l, struct exec_package *pack,
  268     struct ps_strings *arginfo, char **stackp, void *argp)
  269 {
  270         int error;
  271 
  272         if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0)
  273                 return error;
  274 
  275         return elf_populate_auxv(l, pack, stackp);
  276 }
  277 
  278 /*
  279  * elf_check_header():
  280  *
  281  * Check header for validity; return 0 if ok, ENOEXEC if error
  282  */
  283 int
  284 elf_check_header(Elf_Ehdr *eh)
  285 {
  286 
  287         if (memcmp(eh->e_ident, ELFMAG, SELFMAG) != 0 ||
  288             eh->e_ident[EI_CLASS] != ELFCLASS) {
  289                 DPRINTF("bad magic e_ident[EI_MAG0,EI_MAG3] %#x%x%x%x, "
  290                     "e_ident[EI_CLASS] %#x", eh->e_ident[EI_MAG0],
  291                     eh->e_ident[EI_MAG1], eh->e_ident[EI_MAG2],
  292                     eh->e_ident[EI_MAG3], eh->e_ident[EI_CLASS]);
  293                 return ENOEXEC;
  294         }
  295 
  296         switch (eh->e_machine) {
  297 
  298         ELFDEFNNAME(MACHDEP_ID_CASES)
  299 
  300         default:
  301                 DPRINTF("bad machine %#x", eh->e_machine);
  302                 return ENOEXEC;
  303         }
  304 
  305         if (ELF_EHDR_FLAGS_OK(eh) == 0) {
  306                 DPRINTF("bad flags %#x", eh->e_flags);
  307                 return ENOEXEC;
  308         }
  309 
  310         if (eh->e_shnum > ELF_MAXSHNUM || eh->e_phnum > ELF_MAXPHNUM) {
  311                 DPRINTF("bad shnum/phnum %#x/%#x", eh->e_shnum, eh->e_phnum);
  312                 return ENOEXEC;
  313         }
  314 
  315         return 0;
  316 }
  317 
  318 /*
  319  * elf_load_psection():
  320  *
  321  * Load a psection at the appropriate address
  322  */
  323 static int
  324 elf_load_psection(struct exec_vmcmd_set *vcset, struct vnode *vp,
  325     const Elf_Phdr *ph, Elf_Addr *addr, u_long *size, int flags)
  326 {
  327         u_long msize, psize, rm, rf;
  328         long diff, offset;
  329         int vmprot = 0;
  330 
  331         KASSERT(VOP_ISLOCKED(vp) != LK_NONE);
  332 
  333         /*
  334          * If the user specified an address, then we load there.
  335          */
  336         if (*addr == ELFDEFNNAME(NO_ADDR))
  337                 *addr = ph->p_vaddr;
  338 
  339         if (ph->p_align > 1) {
  340                 /*
  341                  * Make sure we are virtually aligned as we are supposed to be.
  342                  */
  343                 diff = ph->p_vaddr - ELF_TRUNC(ph->p_vaddr, ph->p_align);
  344                 if (*addr - diff != ELF_TRUNC(*addr, ph->p_align)) {
  345                         DPRINTF("bad alignment %#jx != %#jx\n",
  346                             (uintptr_t)(*addr - diff),
  347                             (uintptr_t)ELF_TRUNC(*addr, ph->p_align));
  348                         return EINVAL;
  349                 }
  350                 /*
  351                  * But make sure to not map any pages before the start of the
  352                  * psection by limiting the difference to within a page.
  353                  */
  354                 diff &= PAGE_MASK;
  355         } else
  356                 diff = 0;
  357 
  358         vmprot |= (ph->p_flags & PF_R) ? VM_PROT_READ : 0;
  359         vmprot |= (ph->p_flags & PF_W) ? VM_PROT_WRITE : 0;
  360         vmprot |= (ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0;
  361 
  362         /*
  363          * Adjust everything so it all starts on a page boundary.
  364          */
  365         *addr -= diff;
  366         offset = ph->p_offset - diff;
  367         *size = ph->p_filesz + diff;
  368         msize = ph->p_memsz + diff;
  369 
  370         if (ph->p_align >= PAGE_SIZE) {
  371                 if ((ph->p_flags & PF_W) != 0) {
  372                         /*
  373                          * Because the pagedvn pager can't handle zero fill
  374                          * of the last data page if it's not page aligned we
  375                          * map the last page readvn.
  376                          */
  377                         psize = trunc_page(*size);
  378                 } else {
  379                         psize = round_page(*size);
  380                 }
  381         } else {
  382                 psize = *size;
  383         }
  384 
  385         if (psize > 0) {
  386                 NEW_VMCMD2(vcset, ph->p_align < PAGE_SIZE ?
  387                     vmcmd_map_readvn : vmcmd_map_pagedvn, psize, *addr, vp,
  388                     offset, vmprot, flags);
  389                 flags &= VMCMD_RELATIVE;
  390         }
  391         if (psize < *size) {
  392                 NEW_VMCMD2(vcset, vmcmd_map_readvn, *size - psize,
  393                     *addr + psize, vp, offset + psize, vmprot, flags);
  394         }
  395 
  396         /*
  397          * Check if we need to extend the size of the segment (does
  398          * bss extend page the next page boundary)?
  399          */
  400         rm = round_page(*addr + msize);
  401         rf = round_page(*addr + *size);
  402 
  403         if (rm != rf) {
  404                 NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP,
  405                     0, vmprot, flags & VMCMD_RELATIVE);
  406                 *size = msize;
  407         }
  408         return 0;
  409 }
  410 
  411 /*
  412  * elf_load_interp():
  413  *
  414  * Load an interpreter pointed to by path.
  415  */
  416 static int
  417 elf_load_interp(struct lwp *l, struct exec_package *epp, char *path,
  418     struct exec_vmcmd_set *vcset, u_long *entryoff, Elf_Addr *last)
  419 {
  420         int error, i;
  421         struct vnode *vp;
  422         Elf_Ehdr eh;
  423         Elf_Phdr *ph = NULL;
  424         const Elf_Phdr *base_ph;
  425         const Elf_Phdr *last_ph;
  426         u_long phsize;
  427         Elf_Addr addr = *last;
  428         struct proc *p;
  429         bool use_topdown;
  430 
  431         p = l->l_proc;
  432 
  433         KASSERT(p->p_vmspace);
  434         KASSERT(p->p_vmspace != proc0.p_vmspace);
  435 
  436 #ifdef __USE_TOPDOWN_VM
  437         use_topdown = epp->ep_flags & EXEC_TOPDOWN_VM;
  438 #else
  439         use_topdown = false;
  440 #endif
  441 
  442         /*
  443          * 1. open file
  444          * 2. read filehdr
  445          * 3. map text, data, and bss out of it using VM_*
  446          */
  447         vp = epp->ep_interp;
  448         if (vp == NULL) {
  449                 error = emul_find_interp(l, epp, path);
  450                 if (error != 0)
  451                         return error;
  452                 vp = epp->ep_interp;
  453         }
  454         /* We'll tidy this ourselves - otherwise we have locking issues */
  455         epp->ep_interp = NULL;
  456         vn_lock(vp, LK_SHARED | LK_RETRY);
  457 
  458         /*
  459          * Similarly, if it's not marked as executable, or it's not a regular
  460          * file, we don't allow it to be used.
  461          */
  462         if (vp->v_type != VREG) {
  463                 error = EACCES;
  464                 goto bad;
  465         }
  466         if ((error = VOP_ACCESS(vp, VEXEC, l->l_cred)) != 0)
  467                 goto bad;
  468 
  469         /*
  470          * Check mount point.  Though we're not trying to exec this binary,
  471          * we will be executing code from it, so if the mount point
  472          * disallows execution or set-id-ness, we punt or kill the set-id.
  473          */
  474         if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
  475                 error = EACCES;
  476                 goto bad;
  477         }
  478         if (vp->v_mount->mnt_flag & MNT_NOSUID)
  479                 epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID);
  480 
  481         error = vn_marktext(vp);
  482         if (error)
  483                 goto bad;
  484 
  485         error = exec_read(l, vp, 0, &eh, sizeof(eh), IO_NODELOCKED);
  486         if (error != 0)
  487                 goto bad;
  488 
  489         if ((error = elf_check_header(&eh)) != 0)
  490                 goto bad;
  491         if (eh.e_type != ET_DYN || eh.e_phnum == 0) {
  492                 DPRINTF("bad interpreter type %#x", eh.e_type);
  493                 error = ENOEXEC;
  494                 goto bad;
  495         }
  496 
  497         phsize = eh.e_phnum * sizeof(Elf_Phdr);
  498         ph = kmem_alloc(phsize, KM_SLEEP);
  499 
  500         error = exec_read(l, vp, eh.e_phoff, ph, phsize, IO_NODELOCKED);
  501         if (error != 0)
  502                 goto bad;
  503 
  504 #ifdef ELF_INTERP_NON_RELOCATABLE
  505         /*
  506          * Evil hack:  Only MIPS should be non-relocatable, and the
  507          * psections should have a high address (typically 0x5ffe0000).
  508          * If it's now relocatable, it should be linked at 0 and the
  509          * psections should have zeros in the upper part of the address.
  510          * Otherwise, force the load at the linked address.
  511          */
  512         if (*last == ELF_LINK_ADDR && (ph->p_vaddr & 0xffff0000) == 0)
  513                 *last = ELFDEFNNAME(NO_ADDR);
  514 #endif
  515 
  516         /*
  517          * If no position to load the interpreter was set by a probe
  518          * function, pick the same address that a non-fixed mmap(0, ..)
  519          * would (i.e. something safely out of the way).
  520          */
  521         if (*last == ELFDEFNNAME(NO_ADDR)) {
  522                 u_long limit = 0;
  523                 /*
  524                  * Find the start and ending addresses of the psections to
  525                  * be loaded.  This will give us the size.
  526                  */
  527                 for (i = 0, base_ph = NULL; i < eh.e_phnum; i++) {
  528                         if (ph[i].p_type == PT_LOAD) {
  529                                 u_long psize = ph[i].p_vaddr + ph[i].p_memsz;
  530                                 if (base_ph == NULL)
  531                                         base_ph = &ph[i];
  532                                 if (psize > limit)
  533                                         limit = psize;
  534                         }
  535                 }
  536 
  537                 if (base_ph == NULL) {
  538                         DPRINTF("no interpreter loadable sections");
  539                         error = ENOEXEC;
  540                         goto bad;
  541                 }
  542 
  543                 /*
  544                  * Now compute the size and load address.
  545                  */
  546                 addr = (*epp->ep_esch->es_emul->e_vm_default_addr)(p,
  547                     epp->ep_daddr,
  548                     round_page(limit) - trunc_page(base_ph->p_vaddr),
  549                     use_topdown);
  550                 addr += (Elf_Addr)pax_aslr_rtld_offset(epp, base_ph->p_align,
  551                     use_topdown);
  552         } else {
  553                 addr = *last; /* may be ELF_LINK_ADDR */
  554         }
  555 
  556         /*
  557          * Load all the necessary sections
  558          */
  559         for (i = 0, base_ph = NULL, last_ph = NULL; i < eh.e_phnum; i++) {
  560                 switch (ph[i].p_type) {
  561                 case PT_LOAD: {
  562                         u_long size;
  563                         int flags;
  564 
  565                         if (base_ph == NULL) {
  566                                 /*
  567                                  * First encountered psection is always the
  568                                  * base psection.  Make sure it's aligned
  569                                  * properly (align down for topdown and align
  570                                  * upwards for not topdown).
  571                                  */
  572                                 base_ph = &ph[i];
  573                                 flags = VMCMD_BASE;
  574                                 if (addr == ELF_LINK_ADDR)
  575                                         addr = ph[i].p_vaddr;
  576                                 if (use_topdown)
  577                                         addr = ELF_TRUNC(addr, ph[i].p_align);
  578                                 else
  579                                         addr = ELF_ROUND(addr, ph[i].p_align);
  580                         } else {
  581                                 u_long limit = round_page(last_ph->p_vaddr
  582                                     + last_ph->p_memsz);
  583                                 u_long base = trunc_page(ph[i].p_vaddr);
  584 
  585                                 /*
  586                                  * If there is a gap in between the psections,
  587                                  * map it as inaccessible so nothing else
  588                                  * mmap'ed will be placed there.
  589                                  */
  590                                 if (limit != base) {
  591                                         NEW_VMCMD2(vcset, vmcmd_map_zero,
  592                                             base - limit,
  593                                             limit - base_ph->p_vaddr, NULLVP,
  594                                             0, VM_PROT_NONE, VMCMD_RELATIVE);
  595                                 }
  596 
  597                                 addr = ph[i].p_vaddr - base_ph->p_vaddr;
  598                                 flags = VMCMD_RELATIVE;
  599                         }
  600                         last_ph = &ph[i];
  601                         if ((error = elf_load_psection(vcset, vp, &ph[i], &addr,
  602                             &size, flags)) != 0)
  603                                 goto bad;
  604                         /*
  605                          * If entry is within this psection then this
  606                          * must contain the .text section.  *entryoff is
  607                          * relative to the base psection.
  608                          */
  609                         if (eh.e_entry >= ph[i].p_vaddr &&
  610                             eh.e_entry < (ph[i].p_vaddr + size)) {
  611                                 *entryoff = eh.e_entry - base_ph->p_vaddr;
  612                         }
  613                         addr += size;
  614                         break;
  615                 }
  616 
  617                 default:
  618                         break;
  619                 }
  620         }
  621 
  622         kmem_free(ph, phsize);
  623         /*
  624          * This value is ignored if TOPDOWN.
  625          */
  626         *last = addr;
  627         vput(vp);
  628         return 0;
  629 
  630 bad:
  631         if (ph != NULL)
  632                 kmem_free(ph, phsize);
  633         vput(vp);
  634         return error;
  635 }
  636 
  637 /*
  638  * exec_elf_makecmds(): Prepare an Elf binary's exec package
  639  *
  640  * First, set of the various offsets/lengths in the exec package.
  641  *
  642  * Then, mark the text image busy (so it can be demand paged) or error
  643  * out if this is not possible.  Finally, set up vmcmds for the
  644  * text, data, bss, and stack segments.
  645  */
  646 int
  647 exec_elf_makecmds(struct lwp *l, struct exec_package *epp)
  648 {
  649         Elf_Ehdr *eh = epp->ep_hdr;
  650         Elf_Phdr *ph, *pp;
  651         Elf_Addr phdr = 0, computed_phdr = 0, pos = 0, end_text = 0;
  652         int error, i;
  653         char *interp = NULL;
  654         u_long phsize;
  655         struct elf_args *ap;
  656         bool is_dyn = false;
  657 
  658         if (epp->ep_hdrvalid < sizeof(Elf_Ehdr)) {
  659                 DPRINTF("small header %#x", epp->ep_hdrvalid);
  660                 return ENOEXEC;
  661         }
  662         if ((error = elf_check_header(eh)) != 0)
  663                 return error;
  664 
  665         if (eh->e_type == ET_DYN)
  666                 /* PIE, and some libs have an entry point */
  667                 is_dyn = true;
  668         else if (eh->e_type != ET_EXEC) {
  669                 DPRINTF("bad type %#x", eh->e_type);
  670                 return ENOEXEC;
  671         }
  672 
  673         if (eh->e_phnum == 0) {
  674                 DPRINTF("no program headers");
  675                 return ENOEXEC;
  676         }
  677 
  678         /* XXX only LK_EXCLUSIVE to match all others - allow spinning */
  679         vn_lock(epp->ep_vp, LK_EXCLUSIVE | LK_RETRY);
  680         error = vn_marktext(epp->ep_vp);
  681         if (error) {
  682                 VOP_UNLOCK(epp->ep_vp);
  683                 return error;
  684         }
  685 
  686         /*
  687          * Allocate space to hold all the program headers, and read them
  688          * from the file
  689          */
  690         phsize = eh->e_phnum * sizeof(Elf_Phdr);
  691         ph = kmem_alloc(phsize, KM_SLEEP);
  692 
  693         error = exec_read(l, epp->ep_vp, eh->e_phoff, ph, phsize,
  694             IO_NODELOCKED);
  695         if (error != 0) {
  696                 VOP_UNLOCK(epp->ep_vp);
  697                 goto bad;
  698         }
  699 
  700         epp->ep_taddr = epp->ep_tsize = ELFDEFNNAME(NO_ADDR);
  701         epp->ep_daddr = epp->ep_dsize = ELFDEFNNAME(NO_ADDR);
  702 
  703         for (i = 0; i < eh->e_phnum; i++) {
  704                 pp = &ph[i];
  705                 if (pp->p_type == PT_INTERP) {
  706                         if (pp->p_filesz < 2 || pp->p_filesz > MAXPATHLEN) {
  707                                 DPRINTF("bad interpreter namelen %#jx",
  708                                     (uintmax_t)pp->p_filesz);
  709                                 error = ENOEXEC;
  710                                 VOP_UNLOCK(epp->ep_vp);
  711                                 goto bad;
  712                         }
  713                         interp = PNBUF_GET();
  714                         error = exec_read(l, epp->ep_vp, pp->p_offset, interp,
  715                             pp->p_filesz, IO_NODELOCKED);
  716                         if (error != 0) {
  717                                 VOP_UNLOCK(epp->ep_vp);
  718                                 goto bad;
  719                         }
  720                         /* Ensure interp is NUL-terminated and of the expected length */
  721                         if (strnlen(interp, pp->p_filesz) != pp->p_filesz - 1) {
  722                                 DPRINTF("bad interpreter name");
  723                                 error = ENOEXEC;
  724                                 VOP_UNLOCK(epp->ep_vp);
  725                                 goto bad;
  726                         }
  727                         break;
  728                 }
  729         }
  730 
  731         /*
  732          * On the same architecture, we may be emulating different systems.
  733          * See which one will accept this executable.
  734          *
  735          * Probe functions would normally see if the interpreter (if any)
  736          * exists. Emulation packages may possibly replace the interpreter in
  737          * interp with a changed path (/emul/xxx/<path>).
  738          */
  739         pos = ELFDEFNNAME(NO_ADDR);
  740         if (epp->ep_esch->u.elf_probe_func) {
  741                 vaddr_t startp = (vaddr_t)pos;
  742 
  743                 error = (*epp->ep_esch->u.elf_probe_func)(l, epp, eh, interp,
  744                                                           &startp);
  745                 if (error) {
  746                         VOP_UNLOCK(epp->ep_vp);
  747                         goto bad;
  748                 }
  749                 pos = (Elf_Addr)startp;
  750         }
  751 
  752         if (is_dyn && (error = elf_placedynexec(epp, eh, ph)) != 0) {
  753                 VOP_UNLOCK(epp->ep_vp);
  754                 goto bad;
  755         }
  756 
  757         /*
  758          * Load all the necessary sections
  759          */
  760         for (i = 0; i < eh->e_phnum; i++) {
  761                 Elf_Addr addr = ELFDEFNNAME(NO_ADDR);
  762                 u_long size = 0;
  763 
  764                 switch (ph[i].p_type) {
  765                 case PT_LOAD:
  766                         if ((error = elf_load_psection(&epp->ep_vmcmds,
  767                             epp->ep_vp, &ph[i], &addr, &size, VMCMD_FIXED))
  768                             != 0) {
  769                                 VOP_UNLOCK(epp->ep_vp);
  770                                 goto bad;
  771                         }
  772 
  773                         /*
  774                          * Consider this as text segment, if it is executable.
  775                          * If there is more than one text segment, pick the
  776                          * largest.
  777                          */
  778                         if (ph[i].p_flags & PF_X) {
  779                                 if (epp->ep_taddr == ELFDEFNNAME(NO_ADDR) ||
  780                                     size > epp->ep_tsize) {
  781                                         epp->ep_taddr = addr;
  782                                         epp->ep_tsize = size;
  783                                 }
  784                                 end_text = addr + size;
  785                         } else {
  786                                 epp->ep_daddr = addr;
  787                                 epp->ep_dsize = size;
  788                         }
  789                         if (ph[i].p_offset == 0) {
  790                                 computed_phdr = ph[i].p_vaddr + eh->e_phoff;
  791                         }
  792                         break;
  793 
  794                 case PT_SHLIB:
  795                         /* SCO has these sections. */
  796                 case PT_INTERP:
  797                         /* Already did this one. */
  798                 case PT_DYNAMIC:
  799                 case PT_NOTE:
  800                         break;
  801                 case PT_PHDR:
  802                         /* Note address of program headers (in text segment) */
  803                         phdr = ph[i].p_vaddr;
  804                         break;
  805 
  806                 default:
  807                         /*
  808                          * Not fatal; we don't need to understand everything.
  809                          */
  810                         break;
  811                 }
  812         }
  813 
  814         /* Now done with the vnode. */
  815         VOP_UNLOCK(epp->ep_vp);
  816 
  817         if (epp->ep_vmcmds.evs_used == 0) {
  818                 /* No VMCMD; there was no PT_LOAD section, or those
  819                  * sections were empty */
  820                 DPRINTF("no vmcommands");
  821                 error = ENOEXEC;
  822                 goto bad;
  823         }
  824 
  825         if (epp->ep_daddr == ELFDEFNNAME(NO_ADDR)) {
  826                 epp->ep_daddr = round_page(end_text);
  827                 epp->ep_dsize = 0;
  828         }
  829 
  830         /*
  831          * Check if we found a dynamically linked binary and arrange to load
  832          * its interpreter
  833          */
  834         if (interp) {
  835                 u_int nused = epp->ep_vmcmds.evs_used;
  836                 u_long interp_offset = 0;
  837 
  838                 if ((error = elf_load_interp(l, epp, interp,
  839                     &epp->ep_vmcmds, &interp_offset, &pos)) != 0) {
  840                         goto bad;
  841                 }
  842                 if (epp->ep_vmcmds.evs_used == nused) {
  843                         /* elf_load_interp() has not set up any new VMCMD */
  844                         DPRINTF("no vmcommands for interpreter");
  845                         error = ENOEXEC;
  846                         goto bad;
  847                 }
  848 
  849                 ap = kmem_alloc(sizeof(*ap), KM_SLEEP);
  850                 ap->arg_interp = epp->ep_vmcmds.evs_cmds[nused].ev_addr;
  851                 epp->ep_entryoffset = interp_offset;
  852                 epp->ep_entry = ap->arg_interp + interp_offset;
  853                 PNBUF_PUT(interp);
  854                 interp = NULL;
  855         } else {
  856                 epp->ep_entry = eh->e_entry;
  857                 if (epp->ep_flags & EXEC_FORCEAUX) {
  858                         ap = kmem_zalloc(sizeof(*ap), KM_SLEEP);
  859                         ap->arg_interp = (vaddr_t)NULL;
  860                 } else {
  861                         ap = NULL;
  862                 }
  863         }
  864 
  865         if (ap) {
  866                 ap->arg_phaddr = phdr ? phdr : computed_phdr;
  867                 ap->arg_phentsize = eh->e_phentsize;
  868                 ap->arg_phnum = eh->e_phnum;
  869                 ap->arg_entry = eh->e_entry;
  870                 epp->ep_emul_arg = ap;
  871                 epp->ep_emul_arg_free = elf_free_emul_arg;
  872         }
  873 
  874 #ifdef ELF_MAP_PAGE_ZERO
  875         /* Dell SVR4 maps page zero, yeuch! */
  876         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, PAGE_SIZE, 0,
  877             epp->ep_vp, 0, VM_PROT_READ);
  878 #endif
  879 
  880         error = (*epp->ep_esch->es_setup_stack)(l, epp);
  881         if (error)
  882                 goto bad;
  883 
  884         kmem_free(ph, phsize);
  885         return 0;
  886 
  887 bad:
  888         if (interp)
  889                 PNBUF_PUT(interp);
  890         exec_free_emul_arg(epp);
  891         kmem_free(ph, phsize);
  892         kill_vmcmds(&epp->ep_vmcmds);
  893         return error;
  894 }
  895 
  896 int
  897 netbsd_elf_signature(struct lwp *l, struct exec_package *epp,
  898     Elf_Ehdr *eh)
  899 {
  900         size_t i;
  901         Elf_Phdr *ph;
  902         size_t phsize;
  903         char *nbuf;
  904         int error;
  905         int isnetbsd = 0;
  906 
  907         epp->ep_pax_flags = 0;
  908 
  909         if (eh->e_phnum > ELF_MAXPHNUM || eh->e_phnum == 0) {
  910                 DPRINTF("no signature %#x", eh->e_phnum);
  911                 return ENOEXEC;
  912         }
  913 
  914         phsize = eh->e_phnum * sizeof(Elf_Phdr);
  915         ph = kmem_alloc(phsize, KM_SLEEP);
  916         error = exec_read(l, epp->ep_vp, eh->e_phoff, ph, phsize,
  917             IO_NODELOCKED);
  918         if (error)
  919                 goto out;
  920 
  921         nbuf = kmem_alloc(ELF_MAXNOTESIZE, KM_SLEEP);
  922         for (i = 0; i < eh->e_phnum; i++) {
  923                 const char *nptr;
  924                 size_t nlen;
  925 
  926                 if (ph[i].p_type != PT_NOTE ||
  927                     ph[i].p_filesz > ELF_MAXNOTESIZE)
  928                         continue;
  929 
  930                 nlen = ph[i].p_filesz;
  931                 error = exec_read(l, epp->ep_vp, ph[i].p_offset, nbuf, nlen,
  932                     IO_NODELOCKED);
  933                 if (error)
  934                         continue;
  935 
  936                 nptr = nbuf;
  937                 while (nlen > 0) {
  938                         const Elf_Nhdr *np;
  939                         const char *ndata, *ndesc;
  940 
  941                         /* note header */
  942                         np = (const Elf_Nhdr *)nptr;
  943                         if (nlen < sizeof(*np)) {
  944                                 break;
  945                         }
  946                         nptr += sizeof(*np);
  947                         nlen -= sizeof(*np);
  948 
  949                         /* note name */
  950                         ndata = nptr;
  951                         if (nlen < roundup(np->n_namesz, 4)) {
  952                                 break;
  953                         }
  954                         nptr += roundup(np->n_namesz, 4);
  955                         nlen -= roundup(np->n_namesz, 4);
  956 
  957                         /* note description */
  958                         ndesc = nptr;
  959                         if (nlen < roundup(np->n_descsz, 4)) {
  960                                 break;
  961                         }
  962                         nptr += roundup(np->n_descsz, 4);
  963                         nlen -= roundup(np->n_descsz, 4);
  964 
  965                         isnetbsd |= netbsd_elf_note(epp, np, ndata, ndesc);
  966                 }
  967         }
  968         kmem_free(nbuf, ELF_MAXNOTESIZE);
  969 
  970         error = isnetbsd ? 0 : ENOEXEC;
  971 #ifdef DEBUG_ELF
  972         if (error)
  973                 DPRINTF("not netbsd");
  974 #endif
  975 out:
  976         kmem_free(ph, phsize);
  977         return error;
  978 }
  979 
  980 int
  981 netbsd_elf_note(struct exec_package *epp,
  982                 const Elf_Nhdr *np, const char *ndata, const char *ndesc)
  983 {
  984         int isnetbsd = 0;
  985 
  986 #ifdef DIAGNOSTIC
  987         const char *badnote;
  988 #define BADNOTE(n) badnote = (n)
  989 #else
  990 #define BADNOTE(n)
  991 #endif
  992 
  993         switch (np->n_type) {
  994         case ELF_NOTE_TYPE_NETBSD_TAG:
  995                 /* It is us */
  996                 if (np->n_namesz == ELF_NOTE_NETBSD_NAMESZ &&
  997                     np->n_descsz == ELF_NOTE_NETBSD_DESCSZ &&
  998                     memcmp(ndata, ELF_NOTE_NETBSD_NAME,
  999                     ELF_NOTE_NETBSD_NAMESZ) == 0) {
 1000                         memcpy(&epp->ep_osversion, ndesc,
 1001                             ELF_NOTE_NETBSD_DESCSZ);
 1002                         isnetbsd = 1;
 1003                         break;
 1004                 }
 1005 
 1006                 /*
 1007                  * Ignore SuSE tags; SuSE's n_type is the same the
 1008                  * NetBSD one.
 1009                  */
 1010                 if (np->n_namesz == ELF_NOTE_SUSE_NAMESZ &&
 1011                     memcmp(ndata, ELF_NOTE_SUSE_NAME,
 1012                     ELF_NOTE_SUSE_NAMESZ) == 0)
 1013                         break;
 1014                 /*
 1015                  * Ignore old GCC
 1016                  */
 1017                 if (np->n_namesz == ELF_NOTE_OGCC_NAMESZ &&
 1018                     memcmp(ndata, ELF_NOTE_OGCC_NAME,
 1019                     ELF_NOTE_OGCC_NAMESZ) == 0)
 1020                         break;
 1021                 BADNOTE("NetBSD tag");
 1022                 goto bad;
 1023 
 1024         case ELF_NOTE_TYPE_PAX_TAG:
 1025                 if (np->n_namesz == ELF_NOTE_PAX_NAMESZ &&
 1026                     np->n_descsz == ELF_NOTE_PAX_DESCSZ &&
 1027                     memcmp(ndata, ELF_NOTE_PAX_NAME,
 1028                     ELF_NOTE_PAX_NAMESZ) == 0) {
 1029                         uint32_t flags;
 1030                         memcpy(&flags, ndesc, sizeof(flags));
 1031                         /* Convert the flags and insert them into
 1032                          * the exec package. */
 1033                         pax_setup_elf_flags(epp, flags);
 1034                         break;
 1035                 }
 1036                 BADNOTE("PaX tag");
 1037                 goto bad;
 1038 
 1039         case ELF_NOTE_TYPE_MARCH_TAG:
 1040                 /* Copy the machine arch into the package. */
 1041                 if (np->n_namesz == ELF_NOTE_MARCH_NAMESZ
 1042                     && memcmp(ndata, ELF_NOTE_MARCH_NAME,
 1043                             ELF_NOTE_MARCH_NAMESZ) == 0) {
 1044                         /* Do not truncate the buffer */
 1045                         if (np->n_descsz > sizeof(epp->ep_machine_arch)) {
 1046                                 BADNOTE("description size limit");
 1047                                 goto bad;
 1048                         }
 1049                         /*
 1050                          * Ensure ndesc is NUL-terminated and of the
 1051                          * expected length.
 1052                          */
 1053                         if (strnlen(ndesc, np->n_descsz) + 1 !=
 1054                             np->n_descsz) {
 1055                                 BADNOTE("description size");
 1056                                 goto bad;
 1057                         }
 1058                         strlcpy(epp->ep_machine_arch, ndesc,
 1059                             sizeof(epp->ep_machine_arch));
 1060                         break;
 1061                 }
 1062                 BADNOTE("march tag");
 1063                 goto bad;
 1064 
 1065         case ELF_NOTE_TYPE_MCMODEL_TAG:
 1066                 /* arch specific check for code model */
 1067 #ifdef ELF_MD_MCMODEL_CHECK
 1068                 if (np->n_namesz == ELF_NOTE_MCMODEL_NAMESZ
 1069                     && memcmp(ndata, ELF_NOTE_MCMODEL_NAME,
 1070                             ELF_NOTE_MCMODEL_NAMESZ) == 0) {
 1071                         ELF_MD_MCMODEL_CHECK(epp, ndesc, np->n_descsz);
 1072                         break;
 1073                 }
 1074                 BADNOTE("mcmodel tag");
 1075                 goto bad;
 1076 #endif
 1077                 break;
 1078 
 1079         case ELF_NOTE_TYPE_SUSE_VERSION_TAG:
 1080                 break;
 1081 
 1082         case ELF_NOTE_TYPE_GO_BUILDID_TAG:
 1083                 break;
 1084 
 1085         case ELF_NOTE_TYPE_FDO_PACKAGING_METADATA:
 1086                 break;
 1087 
 1088         case ELF_NOTE_TYPE_NETBSD_EMUL_TAG:
 1089                 /* Ancient NetBSD version tag */
 1090                 break;
 1091 
 1092         default:
 1093                 BADNOTE("unknown tag");
 1094 bad:
 1095 #ifdef DIAGNOSTIC
 1096                 /* Ignore GNU tags */
 1097                 if (np->n_namesz == ELF_NOTE_GNU_NAMESZ &&
 1098                     memcmp(ndata, ELF_NOTE_GNU_NAME,
 1099                     ELF_NOTE_GNU_NAMESZ) == 0)
 1100                     break;
 1101 
 1102                 int ns = (int)np->n_namesz;
 1103                 printf("%s: Unknown elf note type %d (%s): "
 1104                     "[namesz=%d, descsz=%d name=%-*.*s]\n",
 1105                     epp->ep_kname, np->n_type, badnote, np->n_namesz,
 1106                     np->n_descsz, ns, ns, ndata);
 1107 #endif
 1108                 break;
 1109         }
 1110 
 1111         return isnetbsd;
 1112 }
 1113 
 1114 int
 1115 netbsd_elf_probe(struct lwp *l, struct exec_package *epp, void *eh, char *itp,
 1116     vaddr_t *pos)
 1117 {
 1118         int error;
 1119 
 1120         if ((error = netbsd_elf_signature(l, epp, eh)) != 0)
 1121                 return error;
 1122 #ifdef ELF_MD_PROBE_FUNC
 1123         if ((error = ELF_MD_PROBE_FUNC(l, epp, eh, itp, pos)) != 0)
 1124                 return error;
 1125 #elif defined(ELF_INTERP_NON_RELOCATABLE)
 1126         *pos = ELF_LINK_ADDR;
 1127 #endif
 1128         epp->ep_flags |= EXEC_FORCEAUX;
 1129         return 0;
 1130 }
 1131 
 1132 void
 1133 elf_free_emul_arg(void *arg)
 1134 {
 1135         struct elf_args *ap = arg;
 1136         KASSERT(ap != NULL);
 1137         kmem_free(ap, sizeof(*ap));
 1138 }

Cache object: 00cc41b24f5f698d978f8050ed16810d


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