Home | History | Annotate | Download | only in elf
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     28 /*	  All Rights Reserved  	*/
     29 
     30 
     31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     32 
     33 #include <sys/types.h>
     34 #include <sys/param.h>
     35 #include <sys/thread.h>
     36 #include <sys/sysmacros.h>
     37 #include <sys/signal.h>
     38 #include <sys/cred.h>
     39 #include <sys/user.h>
     40 #include <sys/errno.h>
     41 #include <sys/vnode.h>
     42 #include <sys/mman.h>
     43 #include <sys/kmem.h>
     44 #include <sys/proc.h>
     45 #include <sys/pathname.h>
     46 #include <sys/cmn_err.h>
     47 #include <sys/systm.h>
     48 #include <sys/elf.h>
     49 #include <sys/vmsystm.h>
     50 #include <sys/debug.h>
     51 #include <sys/auxv.h>
     52 #include <sys/exec.h>
     53 #include <sys/prsystm.h>
     54 #include <vm/as.h>
     55 #include <vm/rm.h>
     56 #include <vm/seg.h>
     57 #include <vm/seg_vn.h>
     58 #include <sys/modctl.h>
     59 #include <sys/systeminfo.h>
     60 #include <sys/vmparam.h>
     61 #include <sys/machelf.h>
     62 #include <sys/shm_impl.h>
     63 #include <sys/archsystm.h>
     64 #include <sys/fasttrap.h>
     65 #include <sys/brand.h>
     66 #include "elf_impl.h"
     67 
     68 #include <sys/sdt.h>
     69 
     70 extern int at_flags;
     71 
     72 #define	ORIGIN_STR	"ORIGIN"
     73 #define	ORIGIN_STR_SIZE	6
     74 
     75 static int getelfhead(vnode_t *, cred_t *, Ehdr *, int *, int *, int *);
     76 static int getelfphdr(vnode_t *, cred_t *, const Ehdr *, int, caddr_t *,
     77     ssize_t *);
     78 static int getelfshdr(vnode_t *, cred_t *, const Ehdr *, int, int, caddr_t *,
     79     ssize_t *, caddr_t *, ssize_t *);
     80 static size_t elfsize(Ehdr *, int, caddr_t, uintptr_t *);
     81 static int mapelfexec(vnode_t *, Ehdr *, int, caddr_t,
     82     Phdr **, Phdr **, Phdr **, Phdr **, Phdr *,
     83     caddr_t *, caddr_t *, intptr_t *, intptr_t *, size_t, long *, size_t *);
     84 
     85 typedef enum {
     86 	STR_CTF,
     87 	STR_SYMTAB,
     88 	STR_DYNSYM,
     89 	STR_STRTAB,
     90 	STR_DYNSTR,
     91 	STR_SHSTRTAB,
     92 	STR_NUM
     93 } shstrtype_t;
     94 
     95 static const char *shstrtab_data[] = {
     96 	".SUNW_ctf",
     97 	".symtab",
     98 	".dynsym",
     99 	".strtab",
    100 	".dynstr",
    101 	".shstrtab"
    102 };
    103 
    104 typedef struct shstrtab {
    105 	int	sst_ndx[STR_NUM];
    106 	int	sst_cur;
    107 } shstrtab_t;
    108 
    109 static void
    110 shstrtab_init(shstrtab_t *s)
    111 {
    112 	bzero(&s->sst_ndx, sizeof (s->sst_ndx));
    113 	s->sst_cur = 1;
    114 }
    115 
    116 static int
    117 shstrtab_ndx(shstrtab_t *s, shstrtype_t type)
    118 {
    119 	int ret;
    120 
    121 	if ((ret = s->sst_ndx[type]) != 0)
    122 		return (ret);
    123 
    124 	ret = s->sst_ndx[type] = s->sst_cur;
    125 	s->sst_cur += strlen(shstrtab_data[type]) + 1;
    126 
    127 	return (ret);
    128 }
    129 
    130 static size_t
    131 shstrtab_size(const shstrtab_t *s)
    132 {
    133 	return (s->sst_cur);
    134 }
    135 
    136 static void
    137 shstrtab_dump(const shstrtab_t *s, char *buf)
    138 {
    139 	int i, ndx;
    140 
    141 	*buf = '\0';
    142 	for (i = 0; i < STR_NUM; i++) {
    143 		if ((ndx = s->sst_ndx[i]) != 0)
    144 			(void) strcpy(buf + ndx, shstrtab_data[i]);
    145 	}
    146 }
    147 
    148 static int
    149 dtrace_safe_phdr(Phdr *phdrp, struct uarg *args, uintptr_t base)
    150 {
    151 	ASSERT(phdrp->p_type == PT_SUNWDTRACE);
    152 
    153 	/*
    154 	 * See the comment in fasttrap.h for information on how to safely
    155 	 * update this program header.
    156 	 */
    157 	if (phdrp->p_memsz < PT_SUNWDTRACE_SIZE ||
    158 	    (phdrp->p_flags & (PF_R | PF_W | PF_X)) != (PF_R | PF_W | PF_X))
    159 		return (-1);
    160 
    161 	args->thrptr = phdrp->p_vaddr + base;
    162 
    163 	return (0);
    164 }
    165 
    166 /*
    167  * Map in the executable pointed to by vp. Returns 0 on success.
    168  */
    169 int
    170 mapexec_brand(vnode_t *vp, uarg_t *args, Ehdr *ehdr, Addr *uphdr_vaddr,
    171     intptr_t *voffset, caddr_t exec_file, int *interp, caddr_t *bssbase,
    172     caddr_t *brkbase, size_t *brksize, uintptr_t *lddatap)
    173 {
    174 	size_t		len;
    175 	struct vattr	vat;
    176 	caddr_t		phdrbase = NULL;
    177 	ssize_t		phdrsize;
    178 	int		nshdrs, shstrndx, nphdrs;
    179 	int		error = 0;
    180 	Phdr		*uphdr = NULL;
    181 	Phdr		*junk = NULL;
    182 	Phdr		*dynphdr = NULL;
    183 	Phdr		*dtrphdr = NULL;
    184 	uintptr_t	lddata;
    185 	long		execsz;
    186 	intptr_t	minaddr;
    187 
    188 	if (lddatap != NULL)
    189 		*lddatap = NULL;
    190 
    191 	if (error = execpermissions(vp, &vat, args)) {
    192 		uprintf("%s: Cannot execute %s\n", exec_file, args->pathname);
    193 		return (error);
    194 	}
    195 
    196 	if ((error = getelfhead(vp, CRED(), ehdr, &nshdrs, &shstrndx,
    197 	    &nphdrs)) != 0 ||
    198 	    (error = getelfphdr(vp, CRED(), ehdr, nphdrs, &phdrbase,
    199 	    &phdrsize)) != 0) {
    200 		uprintf("%s: Cannot read %s\n", exec_file, args->pathname);
    201 		return (error);
    202 	}
    203 
    204 	if ((len = elfsize(ehdr, nphdrs, phdrbase, &lddata)) == 0) {
    205 		uprintf("%s: Nothing to load in %s", exec_file, args->pathname);
    206 		kmem_free(phdrbase, phdrsize);
    207 		return (ENOEXEC);
    208 	}
    209 	if (lddatap != NULL)
    210 		*lddatap = lddata;
    211 
    212 	if (error = mapelfexec(vp, ehdr, nphdrs, phdrbase, &uphdr, &dynphdr,
    213 	    &junk, &dtrphdr, NULL, bssbase, brkbase, voffset, &minaddr,
    214 	    len, &execsz, brksize)) {
    215 		uprintf("%s: Cannot map %s\n", exec_file, args->pathname);
    216 		kmem_free(phdrbase, phdrsize);
    217 		return (error);
    218 	}
    219 
    220 	/*
    221 	 * Inform our caller if the executable needs an interpreter.
    222 	 */
    223 	*interp = (dynphdr == NULL) ? 0 : 1;
    224 
    225 	/*
    226 	 * If this is a statically linked executable, voffset should indicate
    227 	 * the address of the executable itself (it normally holds the address
    228 	 * of the interpreter).
    229 	 */
    230 	if (ehdr->e_type == ET_EXEC && *interp == 0)
    231 		*voffset = minaddr;
    232 
    233 	if (uphdr != NULL) {
    234 		*uphdr_vaddr = uphdr->p_vaddr;
    235 	} else {
    236 		*uphdr_vaddr = (Addr)-1;
    237 	}
    238 
    239 	kmem_free(phdrbase, phdrsize);
    240 	return (error);
    241 }
    242 
    243 /*ARGSUSED*/
    244 int
    245 elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
    246     int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred,
    247     int brand_action)
    248 {
    249 	caddr_t		phdrbase = NULL;
    250 	caddr_t 	bssbase = 0;
    251 	caddr_t 	brkbase = 0;
    252 	size_t		brksize = 0;
    253 	ssize_t		dlnsize;
    254 	aux_entry_t	*aux;
    255 	int		error;
    256 	ssize_t		resid;
    257 	int		fd = -1;
    258 	intptr_t	voffset;
    259 	Phdr		*dyphdr = NULL;
    260 	Phdr		*stphdr = NULL;
    261 	Phdr		*uphdr = NULL;
    262 	Phdr		*junk = NULL;
    263 	size_t		len;
    264 	ssize_t		phdrsize;
    265 	int		postfixsize = 0;
    266 	int		i, hsize;
    267 	Phdr		*phdrp;
    268 	Phdr		*dataphdrp = NULL;
    269 	Phdr		*dtrphdr;
    270 	int		hasu = 0;
    271 	int		hasauxv = 0;
    272 	int		hasdy = 0;
    273 	int		branded = 0;
    274 
    275 	struct proc *p = ttoproc(curthread);
    276 	struct user *up = PTOU(p);
    277 	struct bigwad {
    278 		Ehdr	ehdr;
    279 		aux_entry_t	elfargs[__KERN_NAUXV_IMPL];
    280 		char		dl_name[MAXPATHLEN];
    281 		char		pathbuf[MAXPATHLEN];
    282 		struct vattr	vattr;
    283 		struct execenv	exenv;
    284 	} *bigwad;	/* kmem_alloc this behemoth so we don't blow stack */
    285 	Ehdr		*ehdrp;
    286 	int		nshdrs, shstrndx, nphdrs;
    287 	char		*dlnp;
    288 	char		*pathbufp;
    289 	rlim64_t	limit;
    290 	rlim64_t	roundlimit;
    291 
    292 	ASSERT(p->p_model == DATAMODEL_ILP32 || p->p_model == DATAMODEL_LP64);
    293 
    294 	bigwad = kmem_alloc(sizeof (struct bigwad), KM_SLEEP);
    295 	ehdrp = &bigwad->ehdr;
    296 	dlnp = bigwad->dl_name;
    297 	pathbufp = bigwad->pathbuf;
    298 
    299 	/*
    300 	 * Obtain ELF and program header information.
    301 	 */
    302 	if ((error = getelfhead(vp, CRED(), ehdrp, &nshdrs, &shstrndx,
    303 	    &nphdrs)) != 0 ||
    304 	    (error = getelfphdr(vp, CRED(), ehdrp, nphdrs, &phdrbase,
    305 	    &phdrsize)) != 0)
    306 		goto out;
    307 
    308 	/*
    309 	 * Prevent executing an ELF file that has no entry point.
    310 	 */
    311 	if (ehdrp->e_entry == 0) {
    312 		uprintf("%s: Bad entry point\n", exec_file);
    313 		goto bad;
    314 	}
    315 
    316 	/*
    317 	 * Put data model that we're exec-ing to into the args passed to
    318 	 * exec_args(), so it will know what it is copying to on new stack.
    319 	 * Now that we know whether we are exec-ing a 32-bit or 64-bit
    320 	 * executable, we can set execsz with the appropriate NCARGS.
    321 	 */
    322 #ifdef	_LP64
    323 	if (ehdrp->e_ident[EI_CLASS] == ELFCLASS32) {
    324 		args->to_model = DATAMODEL_ILP32;
    325 		*execsz = btopr(SINCR) + btopr(SSIZE) + btopr(NCARGS32-1);
    326 	} else {
    327 		args->to_model = DATAMODEL_LP64;
    328 		args->stk_prot &= ~PROT_EXEC;
    329 #if defined(__i386) || defined(__amd64)
    330 		args->dat_prot &= ~PROT_EXEC;
    331 #endif
    332 		*execsz = btopr(SINCR) + btopr(SSIZE) + btopr(NCARGS64-1);
    333 	}
    334 #else	/* _LP64 */
    335 	args->to_model = DATAMODEL_ILP32;
    336 	*execsz = btopr(SINCR) + btopr(SSIZE) + btopr(NCARGS-1);
    337 #endif	/* _LP64 */
    338 
    339 	/*
    340 	 * We delay invoking the brand callback until we've figured out
    341 	 * what kind of elf binary we're trying to run, 32-bit or 64-bit.
    342 	 * We do this because now the brand library can just check
    343 	 * args->to_model to see if the target is 32-bit or 64-bit without
    344 	 * having do duplicate all the code above.
    345 	 */
    346 	if ((level < 2) &&
    347 	    (brand_action != EBA_NATIVE) && (PROC_IS_BRANDED(p))) {
    348 		error = BROP(p)->b_elfexec(vp, uap, args,
    349 		    idatap, level + 1, execsz, setid, exec_file, cred,
    350 		    brand_action);
    351 		goto out;
    352 	}
    353 
    354 	/*
    355 	 * Determine aux size now so that stack can be built
    356 	 * in one shot (except actual copyout of aux image),
    357 	 * determine any non-default stack protections,
    358 	 * and still have this code be machine independent.
    359 	 */
    360 	hsize = ehdrp->e_phentsize;
    361 	phdrp = (Phdr *)phdrbase;
    362 	for (i = nphdrs; i > 0; i--) {
    363 		switch (phdrp->p_type) {
    364 		case PT_INTERP:
    365 			hasauxv = hasdy = 1;
    366 			break;
    367 		case PT_PHDR:
    368 			hasu = 1;
    369 			break;
    370 		case PT_SUNWSTACK:
    371 			args->stk_prot = PROT_USER;
    372 			if (phdrp->p_flags & PF_R)
    373 				args->stk_prot |= PROT_READ;
    374 			if (phdrp->p_flags & PF_W)
    375 				args->stk_prot |= PROT_WRITE;
    376 			if (phdrp->p_flags & PF_X)
    377 				args->stk_prot |= PROT_EXEC;
    378 			break;
    379 		case PT_LOAD:
    380 			dataphdrp = phdrp;
    381 			break;
    382 		}
    383 		phdrp = (Phdr *)((caddr_t)phdrp + hsize);
    384 	}
    385 
    386 	if (ehdrp->e_type != ET_EXEC) {
    387 		dataphdrp = NULL;
    388 		hasauxv = 1;
    389 	}
    390 
    391 	/* Copy BSS permissions to args->dat_prot */
    392 	if (dataphdrp != NULL) {
    393 		args->dat_prot = PROT_USER;
    394 		if (dataphdrp->p_flags & PF_R)
    395 			args->dat_prot |= PROT_READ;
    396 		if (dataphdrp->p_flags & PF_W)
    397 			args->dat_prot |= PROT_WRITE;
    398 		if (dataphdrp->p_flags & PF_X)
    399 			args->dat_prot |= PROT_EXEC;
    400 	}
    401 
    402 	/*
    403 	 * If a auxvector will be required - reserve the space for
    404 	 * it now.  This may be increased by exec_args if there are
    405 	 * ISA-specific types (included in __KERN_NAUXV_IMPL).
    406 	 */
    407 	if (hasauxv) {
    408 		/*
    409 		 * If a AUX vector is being built - the base AUX
    410 		 * entries are:
    411 		 *
    412 		 *	AT_BASE
    413 		 *	AT_FLAGS
    414 		 *	AT_PAGESZ
    415 		 *	AT_SUN_LDSECURE
    416 		 *	AT_SUN_HWCAP
    417 		 *	AT_SUN_PLATFORM
    418 		 *	AT_SUN_EXECNAME
    419 		 *	AT_NULL
    420 		 *
    421 		 * total == 8
    422 		 */
    423 		if (hasdy && hasu) {
    424 			/*
    425 			 * Has PT_INTERP & PT_PHDR - the auxvectors that
    426 			 * will be built are:
    427 			 *
    428 			 *	AT_PHDR
    429 			 *	AT_PHENT
    430 			 *	AT_PHNUM
    431 			 *	AT_ENTRY
    432 			 *	AT_LDDATA
    433 			 *
    434 			 * total = 5
    435 			 */
    436 			args->auxsize = (8 + 5) * sizeof (aux_entry_t);
    437 		} else if (hasdy) {
    438 			/*
    439 			 * Has PT_INTERP but no PT_PHDR
    440 			 *
    441 			 *	AT_EXECFD
    442 			 *	AT_LDDATA
    443 			 *
    444 			 * total = 2
    445 			 */
    446 			args->auxsize = (8 + 2) * sizeof (aux_entry_t);
    447 		} else {
    448 			args->auxsize = 8 * sizeof (aux_entry_t);
    449 		}
    450 	} else
    451 		args->auxsize = 0;
    452 
    453 	/*
    454 	 * If this binary is using an emulator, we need to add an
    455 	 * AT_SUN_EMULATOR aux entry.
    456 	 */
    457 	if (args->emulator != NULL)
    458 		args->auxsize += sizeof (aux_entry_t);
    459 
    460 	if ((brand_action != EBA_NATIVE) && (PROC_IS_BRANDED(p))) {
    461 		branded = 1;
    462 		/*
    463 		 * We will be adding 4 entries to the aux vectors.  One for
    464 		 * the the brandname and 3 for the brand specific aux vectors.
    465 		 */
    466 		args->auxsize += 4 * sizeof (aux_entry_t);
    467 	}
    468 
    469 	aux = bigwad->elfargs;
    470 	/*
    471 	 * Move args to the user's stack.
    472 	 */
    473 	if ((error = exec_args(uap, args, idatap, (void **)&aux)) != 0) {
    474 		if (error == -1) {
    475 			error = ENOEXEC;
    476 			goto bad;
    477 		}
    478 		goto out;
    479 	}
    480 	/* we're single threaded after this point */
    481 
    482 	/*
    483 	 * If this is an ET_DYN executable (shared object),
    484 	 * determine its memory size so that mapelfexec() can load it.
    485 	 */
    486 	if (ehdrp->e_type == ET_DYN)
    487 		len = elfsize(ehdrp, nphdrs, phdrbase, NULL);
    488 	else
    489 		len = 0;
    490 
    491 	dtrphdr = NULL;
    492 
    493 	if ((error = mapelfexec(vp, ehdrp, nphdrs, phdrbase, &uphdr, &dyphdr,
    494 	    &stphdr, &dtrphdr, dataphdrp, &bssbase, &brkbase, &voffset, NULL,
    495 	    len, execsz, &brksize)) != 0)
    496 		goto bad;
    497 
    498 	if (uphdr != NULL && dyphdr == NULL)
    499 		goto bad;
    500 
    501 	if (dtrphdr != NULL && dtrace_safe_phdr(dtrphdr, args, voffset) != 0) {
    502 		uprintf("%s: Bad DTrace phdr in %s\n", exec_file, exec_file);
    503 		goto bad;
    504 	}
    505 
    506 	if (dyphdr != NULL) {
    507 		size_t		len;
    508 		uintptr_t	lddata;
    509 		char		*p;
    510 		struct vnode	*nvp;
    511 
    512 		dlnsize = dyphdr->p_filesz;
    513 
    514 		if (dlnsize > MAXPATHLEN || dlnsize <= 0)
    515 			goto bad;
    516 
    517 		/*
    518 		 * Read in "interpreter" pathname.
    519 		 */
    520 		if ((error = vn_rdwr(UIO_READ, vp, dlnp, dyphdr->p_filesz,
    521 		    (offset_t)dyphdr->p_offset, UIO_SYSSPACE, 0, (rlim64_t)0,
    522 		    CRED(), &resid)) != 0) {
    523 			uprintf("%s: Cannot obtain interpreter pathname\n",
    524 			    exec_file);
    525 			goto bad;
    526 		}
    527 
    528 		if (resid != 0 || dlnp[dlnsize - 1] != '\0')
    529 			goto bad;
    530 
    531 		/*
    532 		 * Search for '$ORIGIN' token in interpreter path.
    533 		 * If found, expand it.
    534 		 */
    535 		for (p = dlnp; p = strchr(p, '$'); ) {
    536 			uint_t	len, curlen;
    537 			char	*_ptr;
    538 
    539 			if (strncmp(++p, ORIGIN_STR, ORIGIN_STR_SIZE))
    540 				continue;
    541 
    542 			curlen = 0;
    543 			len = p - dlnp - 1;
    544 			if (len) {
    545 				bcopy(dlnp, pathbufp, len);
    546 				curlen += len;
    547 			}
    548 			if (_ptr = strrchr(args->pathname, '/')) {
    549 				len = _ptr - args->pathname;
    550 				if ((curlen + len) > MAXPATHLEN)
    551 					break;
    552 
    553 				bcopy(args->pathname, &pathbufp[curlen], len);
    554 				curlen += len;
    555 			} else {
    556 				/*
    557 				 * executable is a basename found in the
    558 				 * current directory.  So - just substitue
    559 				 * '.' for ORIGIN.
    560 				 */
    561 				pathbufp[curlen] = '.';
    562 				curlen++;
    563 			}
    564 			p += ORIGIN_STR_SIZE;
    565 			len = strlen(p);
    566 
    567 			if ((curlen + len) > MAXPATHLEN)
    568 				break;
    569 			bcopy(p, &pathbufp[curlen], len);
    570 			curlen += len;
    571 			pathbufp[curlen++] = '\0';
    572 			bcopy(pathbufp, dlnp, curlen);
    573 		}
    574 
    575 		/*
    576 		 * /usr/lib/ld.so.1 is known to be a symlink to /lib/ld.so.1
    577 		 * (and /usr/lib/64/ld.so.1 is a symlink to /lib/64/ld.so.1).
    578 		 * Just in case /usr is not mounted, change it now.
    579 		 */
    580 		if (strcmp(dlnp, USR_LIB_RTLD) == 0)
    581 			dlnp += 4;
    582 		error = lookupname(dlnp, UIO_SYSSPACE, FOLLOW, NULLVPP, &nvp);
    583 		if (error && dlnp != bigwad->dl_name) {
    584 			/* new kernel, old user-level */
    585 			error = lookupname(dlnp -= 4, UIO_SYSSPACE, FOLLOW,
    586 			    NULLVPP, &nvp);
    587 		}
    588 		if (error) {
    589 			uprintf("%s: Cannot find %s\n", exec_file, dlnp);
    590 			goto bad;
    591 		}
    592 
    593 		/*
    594 		 * Setup the "aux" vector.
    595 		 */
    596 		if (uphdr) {
    597 			if (ehdrp->e_type == ET_DYN) {
    598 				/* don't use the first page */
    599 				bigwad->exenv.ex_brkbase = (caddr_t)PAGESIZE;
    600 				bigwad->exenv.ex_bssbase = (caddr_t)PAGESIZE;
    601 			} else {
    602 				bigwad->exenv.ex_bssbase = bssbase;
    603 				bigwad->exenv.ex_brkbase = brkbase;
    604 			}
    605 			bigwad->exenv.ex_brksize = brksize;
    606 			bigwad->exenv.ex_magic = elfmagic;
    607 			bigwad->exenv.ex_vp = vp;
    608 			setexecenv(&bigwad->exenv);
    609 
    610 			ADDAUX(aux, AT_PHDR, uphdr->p_vaddr + voffset)
    611 			ADDAUX(aux, AT_PHENT, ehdrp->e_phentsize)
    612 			ADDAUX(aux, AT_PHNUM, nphdrs)
    613 			ADDAUX(aux, AT_ENTRY, ehdrp->e_entry + voffset)
    614 		} else {
    615 			if ((error = execopen(&vp, &fd)) != 0) {
    616 				VN_RELE(nvp);
    617 				goto bad;
    618 			}
    619 
    620 			ADDAUX(aux, AT_EXECFD, fd)
    621 		}
    622 
    623 		if ((error = execpermissions(nvp, &bigwad->vattr, args)) != 0) {
    624 			VN_RELE(nvp);
    625 			uprintf("%s: Cannot execute %s\n", exec_file, dlnp);
    626 			goto bad;
    627 		}
    628 
    629 		/*
    630 		 * Now obtain the ELF header along with the entire program
    631 		 * header contained in "nvp".
    632 		 */
    633 		kmem_free(phdrbase, phdrsize);
    634 		phdrbase = NULL;
    635 		if ((error = getelfhead(nvp, CRED(), ehdrp, &nshdrs,
    636 		    &shstrndx, &nphdrs)) != 0 ||
    637 		    (error = getelfphdr(nvp, CRED(), ehdrp, nphdrs, &phdrbase,
    638 		    &phdrsize)) != 0) {
    639 			VN_RELE(nvp);
    640 			uprintf("%s: Cannot read %s\n", exec_file, dlnp);
    641 			goto bad;
    642 		}
    643 
    644 		/*
    645 		 * Determine memory size of the "interpreter's" loadable
    646 		 * sections.  This size is then used to obtain the virtual
    647 		 * address of a hole, in the user's address space, large
    648 		 * enough to map the "interpreter".
    649 		 */
    650 		if ((len = elfsize(ehdrp, nphdrs, phdrbase, &lddata)) == 0) {
    651 			VN_RELE(nvp);
    652 			uprintf("%s: Nothing to load in %s\n", exec_file, dlnp);
    653 			goto bad;
    654 		}
    655 
    656 		dtrphdr = NULL;
    657 
    658 		error = mapelfexec(nvp, ehdrp, nphdrs, phdrbase, &junk, &junk,
    659 		    &junk, &dtrphdr, NULL, NULL, NULL, &voffset, NULL, len,
    660 		    execsz, NULL);
    661 		if (error || junk != NULL) {
    662 			VN_RELE(nvp);
    663 			uprintf("%s: Cannot map %s\n", exec_file, dlnp);
    664 			goto bad;
    665 		}
    666 
    667 		/*
    668 		 * We use the DTrace program header to initialize the
    669 		 * architecture-specific user per-LWP location. The dtrace
    670 		 * fasttrap provider requires ready access to per-LWP scratch
    671 		 * space. We assume that there is only one such program header
    672 		 * in the interpreter.
    673 		 */
    674 		if (dtrphdr != NULL &&
    675 		    dtrace_safe_phdr(dtrphdr, args, voffset) != 0) {
    676 			VN_RELE(nvp);
    677 			uprintf("%s: Bad DTrace phdr in %s\n", exec_file, dlnp);
    678 			goto bad;
    679 		}
    680 
    681 		VN_RELE(nvp);
    682 		ADDAUX(aux, AT_SUN_LDDATA, voffset + lddata)
    683 	}
    684 
    685 	if (hasauxv) {
    686 		int auxf = AF_SUN_HWCAPVERIFY;
    687 		/*
    688 		 * Note: AT_SUN_PLATFORM was filled in via exec_args()
    689 		 */
    690 		ADDAUX(aux, AT_BASE, voffset)
    691 		ADDAUX(aux, AT_FLAGS, at_flags)
    692 		ADDAUX(aux, AT_PAGESZ, PAGESIZE)
    693 		/*
    694 		 * Linker flags. (security)
    695 		 * p_flag not yet set at this time.
    696 		 * We rely on gexec() to provide us with the information.
    697 		 * If the application is set-uid but this is not reflected
    698 		 * in a mismatch between real/effective uids/gids, then
    699 		 * don't treat this as a set-uid exec.  So we care about
    700 		 * the EXECSETID_UGIDS flag but not the ...SETID flag.
    701 		 */
    702 		if ((setid &= ~EXECSETID_SETID) != 0)
    703 			auxf |= AF_SUN_SETUGID;
    704 		/*
    705 		 * Record the user addr of the auxflags aux vector entry
    706 		 * since brands may optionally want to manipulate this field.
    707 		 */
    708 		args->auxp_auxflags =
    709 		    (char *)((char *)args->stackend +
    710 		    ((char *)&aux->a_type -
    711 		    (char *)bigwad->elfargs));
    712 		ADDAUX(aux, AT_SUN_AUXFLAGS, auxf);
    713 		/*
    714 		 * Hardware capability flag word (performance hints)
    715 		 * Used for choosing faster library routines.
    716 		 * (Potentially different between 32-bit and 64-bit ABIs)
    717 		 */
    718 #if defined(_LP64)
    719 		if (args->to_model == DATAMODEL_NATIVE)
    720 			ADDAUX(aux, AT_SUN_HWCAP, auxv_hwcap)
    721 		else
    722 			ADDAUX(aux, AT_SUN_HWCAP, auxv_hwcap32)
    723 #else
    724 		ADDAUX(aux, AT_SUN_HWCAP, auxv_hwcap)
    725 #endif
    726 		if (branded) {
    727 			/*
    728 			 * Reserve space for the brand-private aux vectors,
    729 			 * and record the user addr of that space.
    730 			 */
    731 			args->auxp_brand =
    732 			    (char *)((char *)args->stackend +
    733 			    ((char *)&aux->a_type -
    734 			    (char *)bigwad->elfargs));
    735 			ADDAUX(aux, AT_SUN_BRAND_AUX1, 0)
    736 			ADDAUX(aux, AT_SUN_BRAND_AUX2, 0)
    737 			ADDAUX(aux, AT_SUN_BRAND_AUX3, 0)
    738 		}
    739 
    740 		ADDAUX(aux, AT_NULL, 0)
    741 		postfixsize = (char *)aux - (char *)bigwad->elfargs;
    742 		ASSERT(postfixsize == args->auxsize);
    743 		ASSERT(postfixsize <= __KERN_NAUXV_IMPL * sizeof (aux_entry_t));
    744 	}
    745 
    746 	/*
    747 	 * For the 64-bit kernel, the limit is big enough that rounding it up
    748 	 * to a page can overflow the 64-bit limit, so we check for btopr()
    749 	 * overflowing here by comparing it with the unrounded limit in pages.
    750 	 * If it hasn't overflowed, compare the exec size with the rounded up
    751 	 * limit in pages.  Otherwise, just compare with the unrounded limit.
    752 	 */
    753 	limit = btop(p->p_vmem_ctl);
    754 	roundlimit = btopr(p->p_vmem_ctl);
    755 	if ((roundlimit > limit && *execsz > roundlimit) ||
    756 	    (roundlimit < limit && *execsz > limit)) {
    757 		mutex_enter(&p->p_lock);
    758 		(void) rctl_action(rctlproc_legacy[RLIMIT_VMEM], p->p_rctls, p,
    759 		    RCA_SAFE);
    760 		mutex_exit(&p->p_lock);
    761 		error = ENOMEM;
    762 		goto bad;
    763 	}
    764 
    765 	bzero(up->u_auxv, sizeof (up->u_auxv));
    766 	if (postfixsize) {
    767 		int num_auxv;
    768 
    769 		/*
    770 		 * Copy the aux vector to the user stack.
    771 		 */
    772 		error = execpoststack(args, bigwad->elfargs, postfixsize);
    773 		if (error)
    774 			goto bad;
    775 
    776 		/*
    777 		 * Copy auxv to the process's user structure for use by /proc.
    778 		 * If this is a branded process, the brand's exec routine will
    779 		 * copy it's private entries to the user structure later. It
    780 		 * relies on the fact that the blank entries are at the end.
    781 		 */
    782 		num_auxv = postfixsize / sizeof (aux_entry_t);
    783 		ASSERT(num_auxv <= sizeof (up->u_auxv) / sizeof (auxv_t));
    784 		aux = bigwad->elfargs;
    785 		for (i = 0; i < num_auxv; i++) {
    786 			up->u_auxv[i].a_type = aux[i].a_type;
    787 			up->u_auxv[i].a_un.a_val = (aux_val_t)aux[i].a_un.a_val;
    788 		}
    789 	}
    790 
    791 	/*
    792 	 * Pass back the starting address so we can set the program counter.
    793 	 */
    794 	args->entry = (uintptr_t)(ehdrp->e_entry + voffset);
    795 
    796 	if (!uphdr) {
    797 		if (ehdrp->e_type == ET_DYN) {
    798 			/*
    799 			 * If we are executing a shared library which doesn't
    800 			 * have a interpreter (probably ld.so.1) then
    801 			 * we don't set the brkbase now.  Instead we
    802 			 * delay it's setting until the first call
    803 			 * via grow.c::brk().  This permits ld.so.1 to
    804 			 * initialize brkbase to the tail of the executable it
    805 			 * loads (which is where it needs to be).
    806 			 */
    807 			bigwad->exenv.ex_brkbase = (caddr_t)0;
    808 			bigwad->exenv.ex_bssbase = (caddr_t)0;
    809 			bigwad->exenv.ex_brksize = 0;
    810 		} else {
    811 			bigwad->exenv.ex_brkbase = brkbase;
    812 			bigwad->exenv.ex_bssbase = bssbase;
    813 			bigwad->exenv.ex_brksize = brksize;
    814 		}
    815 		bigwad->exenv.ex_magic = elfmagic;
    816 		bigwad->exenv.ex_vp = vp;
    817 		setexecenv(&bigwad->exenv);
    818 	}
    819 
    820 	ASSERT(error == 0);
    821 	goto out;
    822 
    823 bad:
    824 	if (fd != -1)		/* did we open the a.out yet */
    825 		(void) execclose(fd);
    826 
    827 	psignal(p, SIGKILL);
    828 
    829 	if (error == 0)
    830 		error = ENOEXEC;
    831 out:
    832 	if (phdrbase != NULL)
    833 		kmem_free(phdrbase, phdrsize);
    834 	kmem_free(bigwad, sizeof (struct bigwad));
    835 	return (error);
    836 }
    837 
    838 /*
    839  * Compute the memory size requirement for the ELF file.
    840  */
    841 static size_t
    842 elfsize(Ehdr *ehdrp, int nphdrs, caddr_t phdrbase, uintptr_t *lddata)
    843 {
    844 	size_t	len;
    845 	Phdr	*phdrp = (Phdr *)phdrbase;
    846 	int	hsize = ehdrp->e_phentsize;
    847 	int	first = 1;
    848 	int	dfirst = 1;	/* first data segment */
    849 	uintptr_t loaddr = 0;
    850 	uintptr_t hiaddr = 0;
    851 	uintptr_t lo, hi;
    852 	int	i;
    853 
    854 	for (i = nphdrs; i > 0; i--) {
    855 		if (phdrp->p_type == PT_LOAD) {
    856 			lo = phdrp->p_vaddr;
    857 			hi = lo + phdrp->p_memsz;
    858 			if (first) {
    859 				loaddr = lo;
    860 				hiaddr = hi;
    861 				first = 0;
    862 			} else {
    863 				if (loaddr > lo)
    864 					loaddr = lo;
    865 				if (hiaddr < hi)
    866 					hiaddr = hi;
    867 			}
    868 
    869 			/*
    870 			 * save the address of the first data segment
    871 			 * of a object - used for the AT_SUNW_LDDATA
    872 			 * aux entry.
    873 			 */
    874 			if ((lddata != NULL) && dfirst &&
    875 			    (phdrp->p_flags & PF_W)) {
    876 				*lddata = lo;
    877 				dfirst = 0;
    878 			}
    879 		}
    880 		phdrp = (Phdr *)((caddr_t)phdrp + hsize);
    881 	}
    882 
    883 	len = hiaddr - (loaddr & PAGEMASK);
    884 	len = roundup(len, PAGESIZE);
    885 
    886 	return (len);
    887 }
    888 
    889 /*
    890  * Read in the ELF header and program header table.
    891  * SUSV3 requires:
    892  *	ENOEXEC	File format is not recognized
    893  *	EINVAL	Format recognized but execution not supported
    894  */
    895 static int
    896 getelfhead(vnode_t *vp, cred_t *credp, Ehdr *ehdr, int *nshdrs, int *shstrndx,
    897     int *nphdrs)
    898 {
    899 	int error;
    900 	ssize_t resid;
    901 
    902 	/*
    903 	 * We got here by the first two bytes in ident,
    904 	 * now read the entire ELF header.
    905 	 */
    906 	if ((error = vn_rdwr(UIO_READ, vp, (caddr_t)ehdr,
    907 	    sizeof (Ehdr), (offset_t)0, UIO_SYSSPACE, 0,
    908 	    (rlim64_t)0, credp, &resid)) != 0)
    909 		return (error);
    910 
    911 	/*
    912 	 * Since a separate version is compiled for handling 32-bit and
    913 	 * 64-bit ELF executables on a 64-bit kernel, the 64-bit version
    914 	 * doesn't need to be able to deal with 32-bit ELF files.
    915 	 */
    916 	if (resid != 0 ||
    917 	    ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
    918 	    ehdr->e_ident[EI_MAG3] != ELFMAG3)
    919 		return (ENOEXEC);
    920 
    921 	if ((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) ||
    922 #if defined(_ILP32) || defined(_ELF32_COMPAT)
    923 	    ehdr->e_ident[EI_CLASS] != ELFCLASS32 ||
    924 #else
    925 	    ehdr->e_ident[EI_CLASS] != ELFCLASS64 ||
    926 #endif
    927 	    !elfheadcheck(ehdr->e_ident[EI_DATA], ehdr->e_machine,
    928 	    ehdr->e_flags))
    929 		return (EINVAL);
    930 
    931 	*nshdrs = ehdr->e_shnum;
    932 	*shstrndx = ehdr->e_shstrndx;
    933 	*nphdrs = ehdr->e_phnum;
    934 
    935 	/*
    936 	 * If e_shnum, e_shstrndx, or e_phnum is its sentinel value, we need
    937 	 * to read in the section header at index zero to acces the true
    938 	 * values for those fields.
    939 	 */
    940 	if ((*nshdrs == 0 && ehdr->e_shoff != 0) ||
    941 	    *shstrndx == SHN_XINDEX || *nphdrs == PN_XNUM) {
    942 		Shdr shdr;
    943 
    944 		if (ehdr->e_shoff == 0)
    945 			return (EINVAL);
    946 
    947 		if ((error = vn_rdwr(UIO_READ, vp, (caddr_t)&shdr,
    948 		    sizeof (shdr), (offset_t)ehdr->e_shoff, UIO_SYSSPACE, 0,
    949 		    (rlim64_t)0, credp, &resid)) != 0)
    950 			return (error);
    951 
    952 		if (*nshdrs == 0)
    953 			*nshdrs = shdr.sh_size;
    954 		if (*shstrndx == SHN_XINDEX)
    955 			*shstrndx = shdr.sh_link;
    956 		if (*nphdrs == PN_XNUM && shdr.sh_info != 0)
    957 			*nphdrs = shdr.sh_info;
    958 	}
    959 
    960 	return (0);
    961 }
    962 
    963 #ifdef _ELF32_COMPAT
    964 extern size_t elf_nphdr_max;
    965 #else
    966 size_t elf_nphdr_max = 1000;
    967 #endif
    968 
    969 static int
    970 getelfphdr(vnode_t *vp, cred_t *credp, const Ehdr *ehdr, int nphdrs,
    971     caddr_t *phbasep, ssize_t *phsizep)
    972 {
    973 	ssize_t resid, minsize;
    974 	int err;
    975 
    976 	/*
    977 	 * Since we're going to be using e_phentsize to iterate down the
    978 	 * array of program headers, it must be 8-byte aligned or else
    979 	 * a we might cause a misaligned access. We use all members through
    980 	 * p_flags on 32-bit ELF files and p_memsz on 64-bit ELF files so
    981 	 * e_phentsize must be at least large enough to include those
    982 	 * members.
    983 	 */
    984 #if !defined(_LP64) || defined(_ELF32_COMPAT)
    985 	minsize = offsetof(Phdr, p_flags) + sizeof (((Phdr *)NULL)->p_flags);
    986 #else
    987 	minsize = offsetof(Phdr, p_memsz) + sizeof (((Phdr *)NULL)->p_memsz);
    988 #endif
    989 	if (ehdr->e_phentsize < minsize || (ehdr->e_phentsize & 3))
    990 		return (EINVAL);
    991 
    992 	*phsizep = nphdrs * ehdr->e_phentsize;
    993 
    994 	if (*phsizep > sizeof (Phdr) * elf_nphdr_max) {
    995 		if ((*phbasep = kmem_alloc(*phsizep, KM_NOSLEEP)) == NULL)
    996 			return (ENOMEM);
    997 	} else {
    998 		*phbasep = kmem_alloc(*phsizep, KM_SLEEP);
    999 	}
   1000 
   1001 	if ((err = vn_rdwr(UIO_READ, vp, *phbasep, *phsizep,
   1002 	    (offset_t)ehdr->e_phoff, UIO_SYSSPACE, 0, (rlim64_t)0,
   1003 	    credp, &resid)) != 0) {
   1004 		kmem_free(*phbasep, *phsizep);
   1005 		*phbasep = NULL;
   1006 		return (err);
   1007 	}
   1008 
   1009 	return (0);
   1010 }
   1011 
   1012 #ifdef _ELF32_COMPAT
   1013 extern size_t elf_nshdr_max;
   1014 extern size_t elf_shstrtab_max;
   1015 #else
   1016 size_t elf_nshdr_max = 10000;
   1017 size_t elf_shstrtab_max = 100 * 1024;
   1018 #endif
   1019 
   1020 
   1021 static int
   1022 getelfshdr(vnode_t *vp, cred_t *credp, const Ehdr *ehdr,
   1023     int nshdrs, int shstrndx, caddr_t *shbasep, ssize_t *shsizep,
   1024     char **shstrbasep, ssize_t *shstrsizep)
   1025 {
   1026 	ssize_t resid, minsize;
   1027 	int err;
   1028 	Shdr *shdr;
   1029 
   1030 	/*
   1031 	 * Since we're going to be using e_shentsize to iterate down the
   1032 	 * array of section headers, it must be 8-byte aligned or else
   1033 	 * a we might cause a misaligned access. We use all members through
   1034 	 * sh_entsize (on both 32- and 64-bit ELF files) so e_shentsize
   1035 	 * must be at least large enough to include that member. The index
   1036 	 * of the string table section must also be valid.
   1037 	 */
   1038 	minsize = offsetof(Shdr, sh_entsize) + sizeof (shdr->sh_entsize);
   1039 	if (ehdr->e_shentsize < minsize || (ehdr->e_shentsize & 3) ||
<