xref: /illumos-gate/usr/src/uts/common/exec/elf/elf.c (revision a7cee4e9766ebda975dd156d1f10a70f51c242f0)
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 (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27 /*	   All Rights Reserved	*/
28 /*
29  * Copyright 2019, Joyent, Inc.
30  * Copyright 2023 Oxide Computer Company
31  * Copyright 2026 Carsten Grzemba
32  */
33 
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/thread.h>
37 #include <sys/sysmacros.h>
38 #include <sys/signal.h>
39 #include <sys/cred.h>
40 #include <sys/user.h>
41 #include <sys/errno.h>
42 #include <sys/vnode.h>
43 #include <sys/mman.h>
44 #include <sys/kmem.h>
45 #include <sys/proc.h>
46 #include <sys/pathname.h>
47 #include <sys/policy.h>
48 #include <sys/cmn_err.h>
49 #include <sys/systm.h>
50 #include <sys/elf.h>
51 #include <sys/vmsystm.h>
52 #include <sys/debug.h>
53 #include <sys/auxv.h>
54 #include <sys/exec.h>
55 #include <sys/prsystm.h>
56 #include <vm/as.h>
57 #include <vm/rm.h>
58 #include <vm/seg.h>
59 #include <vm/seg_vn.h>
60 #include <sys/modctl.h>
61 #include <sys/systeminfo.h>
62 #include <sys/vmparam.h>
63 #include <sys/machelf.h>
64 #include <sys/shm_impl.h>
65 #include <sys/archsystm.h>
66 #include <sys/fasttrap.h>
67 #include <sys/brand.h>
68 #include "elf_impl.h"
69 #include <sys/sdt.h>
70 #include <sys/siginfo.h>
71 #include <sys/random.h>
72 
73 #include <core_shstrtab.h>
74 
75 #if defined(__x86)
76 #include <sys/comm_page_util.h>
77 #include <sys/fp.h>
78 #endif /* defined(__x86) */
79 
80 
81 extern int at_flags;
82 extern volatile size_t aslr_max_brk_skew;
83 
84 #define	ORIGIN_STR	"ORIGIN"
85 #define	ORIGIN_STR_SIZE	6
86 
87 static int getelfhead(vnode_t *, cred_t *, Ehdr *, uint_t *, uint_t *,
88     uint_t *);
89 static int getelfphdr(vnode_t *, cred_t *, const Ehdr *, uint_t, caddr_t *,
90     size_t *);
91 static int getelfshdr(vnode_t *, cred_t *, const Ehdr *, uint_t, uint_t,
92     caddr_t *, size_t *, caddr_t *, size_t *);
93 static size_t elfsize(const Ehdr *, uint_t, const caddr_t, uintptr_t *);
94 static int mapelfexec(vnode_t *, Ehdr *, uint_t, caddr_t, Phdr **, Phdr **,
95     Phdr **, Phdr **, Phdr *, caddr_t *, caddr_t *, intptr_t *, uintptr_t *,
96     size_t, size_t *, size_t *);
97 
98 
99 #ifdef _ELF32_COMPAT
100 /* Link against the non-compat instances when compiling the 32-bit version. */
101 extern size_t elf_datasz_max;
102 extern size_t elf_zeropg_sz;
103 extern void elf_ctx_resize_scratch(elf_core_ctx_t *, size_t);
104 extern uint_t elf_nphdr_max;
105 extern uint_t elf_nshdr_max;
106 extern size_t elf_shstrtab_max;
107 #else
108 size_t elf_datasz_max = 1 * 1024 * 1024;
109 size_t elf_zeropg_sz = 4 * 1024;
110 uint_t elf_nphdr_max = 1000;
111 uint_t elf_nshdr_max = 10000;
112 size_t elf_shstrtab_max = 100 * 1024;
113 #endif
114 
115 static int
116 dtrace_safe_phdr(Phdr *phdrp, struct uarg *args, uintptr_t base)
117 {
118 	ASSERT(phdrp->p_type == PT_SUNWDTRACE);
119 
120 	/*
121 	 * See the comment in fasttrap.h for information on how to safely
122 	 * update this program header.
123 	 */
124 	if (phdrp->p_memsz < PT_SUNWDTRACE_SIZE ||
125 	    (phdrp->p_flags & (PF_R | PF_W | PF_X)) != (PF_R | PF_W | PF_X))
126 		return (-1);
127 
128 	args->thrptr = phdrp->p_vaddr + base;
129 
130 	return (0);
131 }
132 
133 static int
134 handle_secflag_dt(proc_t *p, uint_t dt, uint_t val)
135 {
136 	uint_t flag;
137 
138 	switch (dt) {
139 	case DT_SUNW_ASLR:
140 		flag = PROC_SEC_ASLR;
141 		break;
142 	default:
143 		return (EINVAL);
144 	}
145 
146 	if (val == 0) {
147 		if (secflag_isset(p->p_secflags.psf_lower, flag))
148 			return (EPERM);
149 		if ((secpolicy_psecflags(CRED(), p, p) != 0) &&
150 		    secflag_isset(p->p_secflags.psf_inherit, flag))
151 			return (EPERM);
152 
153 		secflag_clear(&p->p_secflags.psf_effective, flag);
154 	} else {
155 		if (!secflag_isset(p->p_secflags.psf_upper, flag))
156 			return (EPERM);
157 
158 		if ((secpolicy_psecflags(CRED(), p, p) != 0) &&
159 		    !secflag_isset(p->p_secflags.psf_inherit, flag))
160 			return (EPERM);
161 
162 		secflag_set(&p->p_secflags.psf_effective, flag);
163 	}
164 
165 	return (0);
166 }
167 
168 #ifndef _ELF32_COMPAT
169 void
170 elf_ctx_resize_scratch(elf_core_ctx_t *ctx, size_t sz)
171 {
172 	size_t target = MIN(sz, elf_datasz_max);
173 
174 	if (target > ctx->ecc_bufsz) {
175 		if (ctx->ecc_buf != NULL) {
176 			kmem_free(ctx->ecc_buf, ctx->ecc_bufsz);
177 		}
178 		ctx->ecc_buf = kmem_alloc(target, KM_SLEEP);
179 		ctx->ecc_bufsz = target;
180 	}
181 }
182 #endif /* _ELF32_COMPAT */
183 
184 /*
185  * Map in the executable pointed to by vp. Returns 0 on success.
186  */
187 int
188 mapexec_brand(vnode_t *vp, uarg_t *args, Ehdr *ehdr, Addr *uphdr_vaddr,
189     intptr_t *voffset, caddr_t exec_file, int *interp, caddr_t *bssbase,
190     caddr_t *brkbase, size_t *brksize, uintptr_t *lddatap)
191 {
192 	size_t		len, phdrsize;
193 	struct vattr	vat;
194 	caddr_t		phdrbase = NULL;
195 	uint_t		nshdrs, shstrndx, nphdrs;
196 	int		error = 0;
197 	Phdr		*uphdr = NULL;
198 	Phdr		*junk = NULL;
199 	Phdr		*dynphdr = NULL;
200 	Phdr		*dtrphdr = NULL;
201 	uintptr_t	lddata, minaddr;
202 	size_t		execsz;
203 
204 	if (lddatap != NULL)
205 		*lddatap = 0;
206 
207 	if (error = execpermissions(vp, &vat, args)) {
208 		uprintf("%s: Cannot execute %s\n", exec_file, args->pathname);
209 		return (error);
210 	}
211 
212 	if ((error = getelfhead(vp, CRED(), ehdr, &nshdrs, &shstrndx,
213 	    &nphdrs)) != 0 ||
214 	    (error = getelfphdr(vp, CRED(), ehdr, nphdrs, &phdrbase,
215 	    &phdrsize)) != 0) {
216 		uprintf("%s: Cannot read %s\n", exec_file, args->pathname);
217 		return (error);
218 	}
219 
220 	if ((len = elfsize(ehdr, nphdrs, phdrbase, &lddata)) == 0) {
221 		uprintf("%s: Nothing to load in %s", exec_file, args->pathname);
222 		kmem_free(phdrbase, phdrsize);
223 		return (ENOEXEC);
224 	}
225 	if (lddatap != NULL)
226 		*lddatap = lddata;
227 
228 	if (error = mapelfexec(vp, ehdr, nphdrs, phdrbase, &uphdr, &dynphdr,
229 	    &junk, &dtrphdr, NULL, bssbase, brkbase, voffset, &minaddr,
230 	    len, &execsz, brksize)) {
231 		uprintf("%s: Cannot map %s\n", exec_file, args->pathname);
232 		if (uphdr != NULL && uphdr->p_flags == 0)
233 			kmem_free(uphdr, sizeof (Phdr));
234 		kmem_free(phdrbase, phdrsize);
235 		return (error);
236 	}
237 
238 	/*
239 	 * Inform our caller if the executable needs an interpreter.
240 	 */
241 	*interp = (dynphdr == NULL) ? 0 : 1;
242 
243 	/*
244 	 * If this is a statically linked executable, voffset should indicate
245 	 * the address of the executable itself (it normally holds the address
246 	 * of the interpreter).
247 	 */
248 	if (ehdr->e_type == ET_EXEC && *interp == 0)
249 		*voffset = minaddr;
250 
251 	if (uphdr != NULL) {
252 		*uphdr_vaddr = uphdr->p_vaddr;
253 
254 		if (uphdr->p_flags == 0)
255 			kmem_free(uphdr, sizeof (Phdr));
256 	} else {
257 		*uphdr_vaddr = (Addr)-1;
258 	}
259 
260 	kmem_free(phdrbase, phdrsize);
261 	return (error);
262 }
263 
264 int
265 elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
266     int level, size_t *execsz, int setid, caddr_t exec_file, cred_t *cred,
267     int brand_action)
268 {
269 	caddr_t		phdrbase = NULL;
270 	caddr_t		bssbase = 0;
271 	caddr_t		brkbase = 0;
272 	size_t		brksize = 0;
273 	size_t		dlnsize;
274 	aux_entry_t	*aux;
275 	int		error;
276 	ssize_t		resid;
277 	int		fd = -1;
278 	intptr_t	voffset;
279 	Phdr		*intphdr = NULL;
280 	Phdr		*dynamicphdr = NULL;
281 	Phdr		*stphdr = NULL;
282 	Phdr		*uphdr = NULL;
283 	Phdr		*junk = NULL;
284 	size_t		len;
285 	size_t		postfixsize = 0;
286 	size_t		i;
287 	Phdr		*phdrp;
288 	Phdr		*dataphdrp = NULL;
289 	Phdr		*dtrphdr;
290 	Phdr		*capphdr = NULL;
291 	Cap		*cap = NULL;
292 	size_t		capsize;
293 	int		hasu = 0;
294 	int		hasauxv = 0;
295 	int		hasintp = 0;
296 	int		branded = 0;
297 	boolean_t	dynuphdr = B_FALSE;
298 
299 	struct proc *p = ttoproc(curthread);
300 	struct user *up = PTOU(p);
301 	struct bigwad {
302 		Ehdr	ehdr;
303 		aux_entry_t	elfargs[__KERN_NAUXV_IMPL];
304 		char		dl_name[MAXPATHLEN];
305 		char		pathbuf[MAXPATHLEN];
306 		struct vattr	vattr;
307 		struct execenv	exenv;
308 	} *bigwad;	/* kmem_alloc this behemoth so we don't blow stack */
309 	Ehdr		*ehdrp;
310 	uint_t		nshdrs, shstrndx, nphdrs;
311 	size_t		phdrsize;
312 	char		*dlnp;
313 	char		*pathbufp;
314 	rlim64_t	limit;
315 	rlim64_t	roundlimit;
316 
317 	ASSERT(p->p_model == DATAMODEL_ILP32 || p->p_model == DATAMODEL_LP64);
318 
319 	bigwad = kmem_alloc(sizeof (struct bigwad), KM_SLEEP);
320 	ehdrp = &bigwad->ehdr;
321 	dlnp = bigwad->dl_name;
322 	pathbufp = bigwad->pathbuf;
323 
324 	/*
325 	 * Obtain ELF and program header information.
326 	 */
327 	if ((error = getelfhead(vp, CRED(), ehdrp, &nshdrs, &shstrndx,
328 	    &nphdrs)) != 0 ||
329 	    (error = getelfphdr(vp, CRED(), ehdrp, nphdrs, &phdrbase,
330 	    &phdrsize)) != 0)
331 		goto out;
332 
333 	/*
334 	 * Prevent executing an ELF file that has no entry point.
335 	 */
336 	if (ehdrp->e_entry == 0) {
337 		uprintf("%s: Bad entry point\n", exec_file);
338 		goto bad;
339 	}
340 
341 	/*
342 	 * Put data model that we're exec-ing to into the args passed to
343 	 * exec_args(), so it will know what it is copying to on new stack.
344 	 * Now that we know whether we are exec-ing a 32-bit or 64-bit
345 	 * executable, we can set execsz with the appropriate NCARGS.
346 	 */
347 #ifdef	_LP64
348 	if (ehdrp->e_ident[EI_CLASS] == ELFCLASS32) {
349 		args->to_model = DATAMODEL_ILP32;
350 		*execsz = btopr(SINCR) + btopr(SSIZE) + btopr(NCARGS32-1);
351 	} else {
352 		args->to_model = DATAMODEL_LP64;
353 		args->stk_prot &= ~PROT_EXEC;
354 #if defined(__x86)
355 		args->dat_prot &= ~PROT_EXEC;
356 #endif
357 		*execsz = btopr(SINCR) + btopr(SSIZE) + btopr(NCARGS64-1);
358 	}
359 #else	/* _LP64 */
360 	args->to_model = DATAMODEL_ILP32;
361 	*execsz = btopr(SINCR) + btopr(SSIZE) + btopr(NCARGS-1);
362 #endif	/* _LP64 */
363 
364 	/*
365 	 * We delay invoking the brand callback until we've figured out
366 	 * what kind of elf binary we're trying to run, 32-bit or 64-bit.
367 	 * We do this because now the brand library can just check
368 	 * args->to_model to see if the target is 32-bit or 64-bit without
369 	 * having do duplicate all the code above.
370 	 *
371 	 * The level checks associated with brand handling below are used to
372 	 * prevent a loop since the brand elfexec function typically comes back
373 	 * through this function. We must check <= here since the nested
374 	 * handling in the #! interpreter code will increment the level before
375 	 * calling gexec to run the final elfexec interpreter.
376 	 */
377 	if ((level <= INTP_MAXDEPTH) &&
378 	    (brand_action != EBA_NATIVE) && (PROC_IS_BRANDED(p))) {
379 		error = BROP(p)->b_elfexec(vp, uap, args,
380 		    idatap, level + 1, execsz, setid, exec_file, cred,
381 		    brand_action);
382 		goto out;
383 	}
384 
385 	/*
386 	 * Determine aux size now so that stack can be built
387 	 * in one shot (except actual copyout of aux image),
388 	 * determine any non-default stack protections,
389 	 * and still have this code be machine independent.
390 	 */
391 	const uint_t hsize = ehdrp->e_phentsize;
392 	phdrp = (Phdr *)phdrbase;
393 	for (i = nphdrs; i > 0; i--) {
394 		switch (phdrp->p_type) {
395 		case PT_INTERP:
396 			hasauxv = hasintp = 1;
397 			break;
398 		case PT_PHDR:
399 			hasu = 1;
400 			break;
401 		case PT_SUNWSTACK:
402 			args->stk_prot = PROT_USER;
403 			if (phdrp->p_flags & PF_R)
404 				args->stk_prot |= PROT_READ;
405 			if (phdrp->p_flags & PF_W)
406 				args->stk_prot |= PROT_WRITE;
407 			if (phdrp->p_flags & PF_X)
408 				args->stk_prot |= PROT_EXEC;
409 			break;
410 		case PT_LOAD:
411 			dataphdrp = phdrp;
412 			break;
413 		case PT_SUNWCAP:
414 			capphdr = phdrp;
415 			break;
416 		case PT_DYNAMIC:
417 			dynamicphdr = phdrp;
418 			break;
419 		}
420 		phdrp = (Phdr *)((caddr_t)phdrp + hsize);
421 	}
422 
423 	if (ehdrp->e_type != ET_EXEC) {
424 		dataphdrp = NULL;
425 		hasauxv = 1;
426 	}
427 
428 	/* Copy BSS permissions to args->dat_prot */
429 	if (dataphdrp != NULL) {
430 		args->dat_prot = PROT_USER;
431 		if (dataphdrp->p_flags & PF_R)
432 			args->dat_prot |= PROT_READ;
433 		if (dataphdrp->p_flags & PF_W)
434 			args->dat_prot |= PROT_WRITE;
435 		if (dataphdrp->p_flags & PF_X)
436 			args->dat_prot |= PROT_EXEC;
437 	}
438 
439 	/*
440 	 * If a auxvector will be required - reserve the space for
441 	 * it now.  This may be increased by exec_args if there are
442 	 * ISA-specific types (included in __KERN_NAUXV_IMPL).
443 	 */
444 	if (hasauxv) {
445 		/*
446 		 * If a AUX vector is being built - the base AUX
447 		 * entries are:
448 		 *
449 		 *	AT_BASE
450 		 *	AT_FLAGS
451 		 *	AT_PAGESZ
452 		 *	AT_SUN_AUXFLAGS
453 		 *	AT_SUN_HWCAP
454 		 *	AT_SUN_HWCAP2
455 		 *	AT_SUN_HWCAP3
456 		 *	AT_SUN_PLATFORM (added in stk_copyout)
457 		 *	AT_SUN_EXECNAME (added in stk_copyout)
458 		 *	AT_NULL
459 		 *
460 		 * total == 10
461 		 */
462 		if (hasintp && hasu) {
463 			/*
464 			 * Has PT_INTERP & PT_PHDR - the auxvectors that
465 			 * will be built are:
466 			 *
467 			 *	AT_PHDR
468 			 *	AT_PHENT
469 			 *	AT_PHNUM
470 			 *	AT_ENTRY
471 			 *	AT_LDDATA
472 			 *
473 			 * total = 5
474 			 */
475 			args->auxsize = (10 + 5) * sizeof (aux_entry_t);
476 		} else if (hasintp) {
477 			/*
478 			 * Has PT_INTERP but no PT_PHDR
479 			 *
480 			 *	AT_EXECFD
481 			 *	AT_LDDATA
482 			 *
483 			 * total = 2
484 			 */
485 			args->auxsize = (10 + 2) * sizeof (aux_entry_t);
486 		} else {
487 			args->auxsize = 10 * sizeof (aux_entry_t);
488 		}
489 	} else {
490 		args->auxsize = 0;
491 	}
492 
493 	/*
494 	 * If this binary is using an emulator, we need to add an
495 	 * AT_SUN_EMULATOR aux entry.
496 	 */
497 	if (args->emulator != NULL)
498 		args->auxsize += sizeof (aux_entry_t);
499 
500 	/*
501 	 * On supported kernels (x86_64) make room in the auxv for the
502 	 * AT_SUN_COMMPAGE entry.  This will go unpopulated on i86xpv systems
503 	 * which do not provide such functionality.
504 	 *
505 	 * Additionally cover the floating point information AT_SUN_FPSIZE and
506 	 * AT_SUN_FPTYPE.
507 	 */
508 #if defined(__amd64)
509 	args->auxsize += 3 * sizeof (aux_entry_t);
510 #endif /* defined(__amd64) */
511 
512 	if ((brand_action != EBA_NATIVE) && (PROC_IS_BRANDED(p))) {
513 		branded = 1;
514 		/*
515 		 * We will be adding 4 entries to the aux vectors.  One for
516 		 * the the brandname and 3 for the brand specific aux vectors.
517 		 */
518 		args->auxsize += 4 * sizeof (aux_entry_t);
519 	}
520 
521 	/* If the binary has an explicit ASLR flag, it must be honoured */
522 	if ((dynamicphdr != NULL) && (dynamicphdr->p_filesz > 0)) {
523 		const size_t dynfilesz = dynamicphdr->p_filesz;
524 		const size_t dynoffset = dynamicphdr->p_offset;
525 		Dyn *dyn, *dp;
526 
527 		if (dynoffset > MAXOFFSET_T ||
528 		    dynfilesz > MAXOFFSET_T ||
529 		    dynoffset + dynfilesz > MAXOFFSET_T) {
530 			uprintf("%s: cannot read full .dynamic section\n",
531 			    exec_file);
532 			error = EINVAL;
533 			goto out;
534 		}
535 
536 #define	DYN_STRIDE	100
537 		for (i = 0; i < dynfilesz; i += sizeof (*dyn) * DYN_STRIDE) {
538 			const size_t remdyns = (dynfilesz - i) / sizeof (*dyn);
539 			const size_t ndyns = MIN(DYN_STRIDE, remdyns);
540 			const size_t dynsize = ndyns * sizeof (*dyn);
541 
542 			dyn = kmem_alloc(dynsize, KM_SLEEP);
543 
544 			if ((error = vn_rdwr(UIO_READ, vp, (caddr_t)dyn,
545 			    (ssize_t)dynsize, (offset_t)(dynoffset + i),
546 			    UIO_SYSSPACE, 0, (rlim64_t)0,
547 			    CRED(), NULL)) != 0) {
548 				uprintf("%s: cannot read .dynamic section\n",
549 				    exec_file);
550 				goto out;
551 			}
552 
553 			for (dp = dyn; dp < (dyn + ndyns); dp++) {
554 				if (dp->d_tag == DT_SUNW_ASLR) {
555 					if ((error = handle_secflag_dt(p,
556 					    DT_SUNW_ASLR,
557 					    dp->d_un.d_val)) != 0) {
558 						uprintf("%s: error setting "
559 						    "security-flag from "
560 						    "DT_SUNW_ASLR: %d\n",
561 						    exec_file, error);
562 						goto out;
563 					}
564 				}
565 			}
566 
567 			kmem_free(dyn, dynsize);
568 		}
569 	}
570 
571 	/* Hardware/Software capabilities */
572 	if (capphdr != NULL &&
573 	    (capsize = capphdr->p_filesz) > 0 &&
574 	    capsize <= 16 * sizeof (*cap)) {
575 		const uint_t ncaps = capsize / sizeof (*cap);
576 		Cap *cp;
577 
578 		cap = kmem_alloc(capsize, KM_SLEEP);
579 		if ((error = vn_rdwr(UIO_READ, vp, (caddr_t)cap,
580 		    (ssize_t)capsize, (offset_t)capphdr->p_offset,
581 		    UIO_SYSSPACE, 0, (rlim64_t)0, CRED(), NULL)) != 0) {
582 			uprintf("%s: Cannot read capabilities section\n",
583 			    exec_file);
584 			goto out;
585 		}
586 		for (cp = cap; cp < cap + ncaps; cp++) {
587 			if (cp->c_tag == CA_SUNW_SF_1 &&
588 			    (cp->c_un.c_val & SF1_SUNW_ADDR32)) {
589 				if (args->to_model == DATAMODEL_LP64)
590 					args->addr32 = 1;
591 				break;
592 			}
593 		}
594 	}
595 
596 	aux = bigwad->elfargs;
597 	/*
598 	 * Move args to the user's stack.
599 	 * This can fill in the AT_SUN_PLATFORM and AT_SUN_EXECNAME aux entries.
600 	 */
601 	if ((error = exec_args(uap, args, idatap, (void **)&aux)) != 0) {
602 		if (error == -1) {
603 			error = ENOEXEC;
604 			goto bad;
605 		}
606 		goto out;
607 	}
608 	/* we're single threaded after this point */
609 
610 	/*
611 	 * If this is an ET_DYN executable (shared object),
612 	 * determine its memory size so that mapelfexec() can load it.
613 	 */
614 	if (ehdrp->e_type == ET_DYN)
615 		len = elfsize(ehdrp, nphdrs, phdrbase, NULL);
616 	else
617 		len = 0;
618 
619 	dtrphdr = NULL;
620 
621 	error = mapelfexec(vp, ehdrp, nphdrs, phdrbase, &uphdr, &intphdr,
622 	    &stphdr, &dtrphdr, dataphdrp, &bssbase, &brkbase, &voffset, NULL,
623 	    len, execsz, &brksize);
624 
625 	/*
626 	 * Our uphdr has been dynamically allocated if (and only if) its
627 	 * program header flags are clear.  To avoid leaks, this must be
628 	 * checked regardless of whether mapelfexec() emitted an error.
629 	 */
630 	dynuphdr = (uphdr != NULL && uphdr->p_flags == 0);
631 
632 	if (error != 0)
633 		goto bad;
634 
635 	if (uphdr != NULL && intphdr == NULL)
636 		goto bad;
637 
638 	if (dtrphdr != NULL && dtrace_safe_phdr(dtrphdr, args, voffset) != 0) {
639 		uprintf("%s: Bad DTrace phdr in %s\n", exec_file, exec_file);
640 		goto bad;
641 	}
642 
643 	if (intphdr != NULL) {
644 		size_t		len;
645 		uintptr_t	lddata;
646 		char		*p;
647 		struct vnode	*nvp;
648 
649 		dlnsize = intphdr->p_filesz;
650 
651 		/*
652 		 * Make sure none of the component pieces of dlnsize result in
653 		 * an oversized or zeroed result.
654 		 */
655 		if (intphdr->p_filesz > MAXPATHLEN || dlnsize > MAXPATHLEN ||
656 		    dlnsize == 0 || dlnsize < intphdr->p_filesz) {
657 			goto bad;
658 		}
659 
660 		/*
661 		 * Read in "interpreter" pathname.
662 		 */
663 		if ((error = vn_rdwr(UIO_READ, vp, dlnp,
664 		    (ssize_t)intphdr->p_filesz, (offset_t)intphdr->p_offset,
665 		    UIO_SYSSPACE, 0, (rlim64_t)0, CRED(), &resid)) != 0) {
666 			uprintf("%s: Cannot obtain interpreter pathname\n",
667 			    exec_file);
668 			goto bad;
669 		}
670 
671 		if (resid != 0 || dlnp[dlnsize - 1] != '\0')
672 			goto bad;
673 
674 		/*
675 		 * Search for '$ORIGIN' token in interpreter path.
676 		 * If found, expand it.
677 		 */
678 		for (p = dlnp; p = strchr(p, '$'); ) {
679 			uint_t	len, curlen;
680 			char	*_ptr;
681 
682 			if (strncmp(++p, ORIGIN_STR, ORIGIN_STR_SIZE))
683 				continue;
684 
685 			/*
686 			 * We don't support $ORIGIN on setid programs to close
687 			 * a potential attack vector.
688 			 */
689 			if ((setid & EXECSETID_SETID) != 0) {
690 				error = ENOEXEC;
691 				goto bad;
692 			}
693 
694 			curlen = 0;
695 			len = p - dlnp - 1;
696 			if (len) {
697 				bcopy(dlnp, pathbufp, len);
698 				curlen += len;
699 			}
700 			if (_ptr = strrchr(args->pathname, '/')) {
701 				len = _ptr - args->pathname;
702 				if ((curlen + len) > MAXPATHLEN)
703 					break;
704 
705 				bcopy(args->pathname, &pathbufp[curlen], len);
706 				curlen += len;
707 			} else {
708 				/*
709 				 * executable is a basename found in the
710 				 * current directory.  So - just substitue
711 				 * '.' for ORIGIN.
712 				 */
713 				pathbufp[curlen] = '.';
714 				curlen++;
715 			}
716 			p += ORIGIN_STR_SIZE;
717 			len = strlen(p);
718 
719 			if ((curlen + len) > MAXPATHLEN)
720 				break;
721 			bcopy(p, &pathbufp[curlen], len);
722 			curlen += len;
723 			pathbufp[curlen++] = '\0';
724 			bcopy(pathbufp, dlnp, curlen);
725 		}
726 
727 		/*
728 		 * /usr/lib/ld.so.1 is known to be a symlink to /lib/ld.so.1
729 		 * (and /usr/lib/64/ld.so.1 is a symlink to /lib/64/ld.so.1).
730 		 * Just in case /usr is not mounted, change it now.
731 		 */
732 		if (strcmp(dlnp, USR_LIB_RTLD) == 0)
733 			dlnp += 4;
734 		error = lookupname(dlnp, UIO_SYSSPACE, FOLLOW, NULLVPP, &nvp);
735 		if (error && dlnp != bigwad->dl_name) {
736 			/* new kernel, old user-level */
737 			error = lookupname(dlnp -= 4, UIO_SYSSPACE, FOLLOW,
738 			    NULLVPP, &nvp);
739 		}
740 		if (error) {
741 			uprintf("%s: Cannot find %s\n", exec_file, dlnp);
742 			goto bad;
743 		}
744 
745 		/*
746 		 * Setup the "aux" vector.
747 		 */
748 		if (uphdr) {
749 			if (ehdrp->e_type == ET_DYN) {
750 				/* don't use the first page */
751 				bigwad->exenv.ex_brkbase = (caddr_t)PAGESIZE;
752 				bigwad->exenv.ex_bssbase = (caddr_t)PAGESIZE;
753 			} else {
754 				bigwad->exenv.ex_bssbase = bssbase;
755 				bigwad->exenv.ex_brkbase = brkbase;
756 			}
757 			bigwad->exenv.ex_brksize = brksize;
758 			bigwad->exenv.ex_magic = elfmagic;
759 			bigwad->exenv.ex_vp = vp;
760 			setexecenv(&bigwad->exenv);
761 
762 			ADDAUX(aux, AT_PHDR, uphdr->p_vaddr + voffset)
763 			ADDAUX(aux, AT_PHENT, ehdrp->e_phentsize)
764 			ADDAUX(aux, AT_PHNUM, nphdrs)
765 			ADDAUX(aux, AT_ENTRY, ehdrp->e_entry + voffset)
766 		} else {
767 			if ((error = execopen(&vp, &fd)) != 0) {
768 				VN_RELE(nvp);
769 				goto bad;
770 			}
771 
772 			ADDAUX(aux, AT_EXECFD, fd)
773 		}
774 
775 		if ((error = execpermissions(nvp, &bigwad->vattr, args)) != 0) {
776 			VN_RELE(nvp);
777 			uprintf("%s: Cannot execute %s\n", exec_file, dlnp);
778 			goto bad;
779 		}
780 
781 		/*
782 		 * Now obtain the ELF header along with the entire program
783 		 * header contained in "nvp".
784 		 */
785 		kmem_free(phdrbase, phdrsize);
786 		phdrbase = NULL;
787 		if ((error = getelfhead(nvp, CRED(), ehdrp, &nshdrs,
788 		    &shstrndx, &nphdrs)) != 0 ||
789 		    (error = getelfphdr(nvp, CRED(), ehdrp, nphdrs, &phdrbase,
790 		    &phdrsize)) != 0) {
791 			VN_RELE(nvp);
792 			uprintf("%s: Cannot read %s\n", exec_file, dlnp);
793 			goto bad;
794 		}
795 
796 		/*
797 		 * Determine memory size of the "interpreter's" loadable
798 		 * sections.  This size is then used to obtain the virtual
799 		 * address of a hole, in the user's address space, large
800 		 * enough to map the "interpreter".
801 		 */
802 		if ((len = elfsize(ehdrp, nphdrs, phdrbase, &lddata)) == 0) {
803 			VN_RELE(nvp);
804 			uprintf("%s: Nothing to load in %s\n", exec_file, dlnp);
805 			goto bad;
806 		}
807 
808 		dtrphdr = NULL;
809 
810 		error = mapelfexec(nvp, ehdrp, nphdrs, phdrbase, NULL, &junk,
811 		    &junk, &dtrphdr, NULL, NULL, NULL, &voffset, NULL, len,
812 		    execsz, NULL);
813 
814 		if (error || junk != NULL) {
815 			VN_RELE(nvp);
816 			uprintf("%s: Cannot map %s\n", exec_file, dlnp);
817 			goto bad;
818 		}
819 
820 		/*
821 		 * We use the DTrace program header to initialize the
822 		 * architecture-specific user per-LWP location. The dtrace
823 		 * fasttrap provider requires ready access to per-LWP scratch
824 		 * space. We assume that there is only one such program header
825 		 * in the interpreter.
826 		 */
827 		if (dtrphdr != NULL &&
828 		    dtrace_safe_phdr(dtrphdr, args, voffset) != 0) {
829 			VN_RELE(nvp);
830 			uprintf("%s: Bad DTrace phdr in %s\n", exec_file, dlnp);
831 			goto bad;
832 		}
833 
834 		VN_RELE(nvp);
835 		ADDAUX(aux, AT_SUN_LDDATA, voffset + lddata)
836 	}
837 
838 	if (hasauxv) {
839 		int auxf = AF_SUN_HWCAPVERIFY;
840 #if defined(__amd64)
841 		size_t fpsize;
842 		int fptype;
843 #endif /* defined(__amd64) */
844 
845 		/*
846 		 * Note: AT_SUN_PLATFORM and AT_SUN_EXECNAME were filled in via
847 		 * exec_args()
848 		 */
849 		ADDAUX(aux, AT_BASE, voffset)
850 		ADDAUX(aux, AT_FLAGS, at_flags)
851 		ADDAUX(aux, AT_PAGESZ, PAGESIZE)
852 		/*
853 		 * Linker flags. (security)
854 		 * p_flag not yet set at this time.
855 		 * We rely on gexec() to provide us with the information.
856 		 * If the application is set-uid but this is not reflected
857 		 * in a mismatch between real/effective uids/gids, then
858 		 * don't treat this as a set-uid exec.  So we care about
859 		 * the EXECSETID_UGIDS flag but not the ...SETID flag.
860 		 */
861 		if ((setid &= ~EXECSETID_SETID) != 0)
862 			auxf |= AF_SUN_SETUGID;
863 
864 		/*
865 		 * If we're running a native process from within a branded
866 		 * zone under pfexec then we clear the AF_SUN_SETUGID flag so
867 		 * that the native ld.so.1 is able to link with the native
868 		 * libraries instead of using the brand libraries that are
869 		 * installed in the zone.  We only do this for processes
870 		 * which we trust because we see they are already running
871 		 * under pfexec (where uid != euid).  This prevents a
872 		 * malicious user within the zone from crafting a wrapper to
873 		 * run native suid commands with unsecure libraries interposed.
874 		 */
875 		if ((brand_action == EBA_NATIVE) && (PROC_IS_BRANDED(p) &&
876 		    (setid &= ~EXECSETID_SETID) != 0))
877 			auxf &= ~AF_SUN_SETUGID;
878 
879 		/*
880 		 * Record the user addr of the auxflags aux vector entry
881 		 * since brands may optionally want to manipulate this field.
882 		 */
883 		args->auxp_auxflags =
884 		    (char *)((char *)args->stackend +
885 		    ((char *)&aux->a_type -
886 		    (char *)bigwad->elfargs));
887 		ADDAUX(aux, AT_SUN_AUXFLAGS, auxf);
888 
889 		/*
890 		 * Hardware capability flag word (performance hints)
891 		 * Used for choosing faster library routines.
892 		 * (Potentially different between 32-bit and 64-bit ABIs)
893 		 */
894 		if (args->to_model == DATAMODEL_NATIVE) {
895 			ADDAUX(aux, AT_SUN_HWCAP, auxv_hwcap)
896 			ADDAUX(aux, AT_SUN_HWCAP2, auxv_hwcap_2)
897 			ADDAUX(aux, AT_SUN_HWCAP3, auxv_hwcap_3)
898 		} else {
899 			ADDAUX(aux, AT_SUN_HWCAP, auxv_hwcap32)
900 			ADDAUX(aux, AT_SUN_HWCAP2, auxv_hwcap32_2)
901 			ADDAUX(aux, AT_SUN_HWCAP3, auxv_hwcap32_3)
902 		}
903 
904 		if (branded) {
905 			/*
906 			 * Reserve space for the brand-private aux vectors,
907 			 * and record the user addr of that space.
908 			 */
909 			args->auxp_brand =
910 			    (char *)((char *)args->stackend +
911 			    ((char *)&aux->a_type -
912 			    (char *)bigwad->elfargs));
913 			ADDAUX(aux, AT_SUN_BRAND_AUX1, 0)
914 			ADDAUX(aux, AT_SUN_BRAND_AUX2, 0)
915 			ADDAUX(aux, AT_SUN_BRAND_AUX3, 0)
916 		}
917 
918 		/*
919 		 * Add the comm page auxv entry, mapping it in if needed. Also
920 		 * take care of the FPU entries.
921 		 */
922 #if defined(__amd64)
923 		if (args->commpage != (uintptr_t)NULL ||
924 		    (args->commpage = (uintptr_t)comm_page_mapin()) !=
925 		    (uintptr_t)NULL) {
926 			ADDAUX(aux, AT_SUN_COMMPAGE, args->commpage)
927 		} else {
928 			/*
929 			 * If the comm page cannot be mapped, pad out the auxv
930 			 * to satisfy later size checks.
931 			 */
932 			ADDAUX(aux, AT_NULL, 0)
933 		}
934 
935 		fptype = AT_386_FPINFO_NONE;
936 		fpu_auxv_info(&fptype, &fpsize);
937 		if (fptype != AT_386_FPINFO_NONE) {
938 			ADDAUX(aux, AT_SUN_FPTYPE, fptype)
939 			ADDAUX(aux, AT_SUN_FPSIZE, fpsize)
940 		} else {
941 			ADDAUX(aux, AT_NULL, 0)
942 			ADDAUX(aux, AT_NULL, 0)
943 		}
944 #endif /* defined(__amd64) */
945 
946 		ADDAUX(aux, AT_NULL, 0)
947 		postfixsize = (uintptr_t)aux - (uintptr_t)bigwad->elfargs;
948 
949 		/*
950 		 * We make assumptions above when we determine how many aux
951 		 * vector entries we will be adding. However, if we have an
952 		 * invalid elf file, it is possible that mapelfexec might
953 		 * behave differently (but not return an error), in which case
954 		 * the number of aux entries we actually add will be different.
955 		 * We detect that now and error out.
956 		 */
957 		if (postfixsize != args->auxsize) {
958 			DTRACE_PROBE2(elfexec_badaux, size_t, postfixsize,
959 			    size_t, args->auxsize);
960 			goto bad;
961 		}
962 		ASSERT(postfixsize <= __KERN_NAUXV_IMPL * sizeof (aux_entry_t));
963 	}
964 
965 	/*
966 	 * For the 64-bit kernel, the limit is big enough that rounding it up
967 	 * to a page can overflow the 64-bit limit, so we check for btopr()
968 	 * overflowing here by comparing it with the unrounded limit in pages.
969 	 * If it hasn't overflowed, compare the exec size with the rounded up
970 	 * limit in pages.  Otherwise, just compare with the unrounded limit.
971 	 */
972 	limit = btop(p->p_vmem_ctl);
973 	roundlimit = btopr(p->p_vmem_ctl);
974 	if ((roundlimit > limit && *execsz > roundlimit) ||
975 	    (roundlimit < limit && *execsz > limit)) {
976 		mutex_enter(&p->p_lock);
977 		(void) rctl_action(rctlproc_legacy[RLIMIT_VMEM], p->p_rctls, p,
978 		    RCA_SAFE);
979 		mutex_exit(&p->p_lock);
980 		error = ENOMEM;
981 		goto bad;
982 	}
983 
984 	bzero(up->u_auxv, sizeof (up->u_auxv));
985 	up->u_commpagep = args->commpage;
986 	if (postfixsize) {
987 		size_t num_auxv;
988 
989 		/*
990 		 * Copy the aux vector to the user stack.
991 		 */
992 		error = execpoststack(args, bigwad->elfargs, postfixsize);
993 		if (error)
994 			goto bad;
995 
996 		/*
997 		 * Copy auxv to the process's user structure for use by /proc.
998 		 * If this is a branded process, the brand's exec routine will
999 		 * copy it's private entries to the user structure later. It
1000 		 * relies on the fact that the blank entries are at the end.
1001 		 */
1002 		num_auxv = postfixsize / sizeof (aux_entry_t);
1003 		ASSERT(num_auxv <= sizeof (up->u_auxv) / sizeof (auxv_t));
1004 		aux = bigwad->elfargs;
1005 		for (i = 0; i < num_auxv; i++) {
1006 			up->u_auxv[i].a_type = aux[i].a_type;
1007 			up->u_auxv[i].a_un.a_val = (aux_val_t)aux[i].a_un.a_val;
1008 		}
1009 	}
1010 
1011 	/*
1012 	 * Pass back the starting address so we can set the program counter.
1013 	 */
1014 	args->entry = (uintptr_t)(ehdrp->e_entry + voffset);
1015 
1016 	if (!uphdr) {
1017 		if (ehdrp->e_type == ET_DYN) {
1018 			/*
1019 			 * If we are executing a shared library which doesn't
1020 			 * have a interpreter (probably ld.so.1) then
1021 			 * we don't set the brkbase now.  Instead we
1022 			 * delay it's setting until the first call
1023 			 * via grow.c::brk().  This permits ld.so.1 to
1024 			 * initialize brkbase to the tail of the executable it
1025 			 * loads (which is where it needs to be).
1026 			 */
1027 			bigwad->exenv.ex_brkbase = (caddr_t)0;
1028 			bigwad->exenv.ex_bssbase = (caddr_t)0;
1029 			bigwad->exenv.ex_brksize = 0;
1030 		} else {
1031 			bigwad->exenv.ex_brkbase = brkbase;
1032 			bigwad->exenv.ex_bssbase = bssbase;
1033 			bigwad->exenv.ex_brksize = brksize;
1034 		}
1035 		bigwad->exenv.ex_magic = elfmagic;
1036 		bigwad->exenv.ex_vp = vp;
1037 		setexecenv(&bigwad->exenv);
1038 	}
1039 
1040 	ASSERT(error == 0);
1041 	goto out;
1042 
1043 bad:
1044 	if (fd != -1)		/* did we open the a.out yet */
1045 		(void) execclose(fd);
1046 
1047 	psignal(p, SIGKILL);
1048 
1049 	if (error == 0)
1050 		error = ENOEXEC;
1051 out:
1052 	if (dynuphdr)
1053 		kmem_free(uphdr, sizeof (Phdr));
1054 	if (phdrbase != NULL)
1055 		kmem_free(phdrbase, phdrsize);
1056 	if (cap != NULL)
1057 		kmem_free(cap, capsize);
1058 	kmem_free(bigwad, sizeof (struct bigwad));
1059 	return (error);
1060 }
1061 
1062 /*
1063  * Compute the memory size requirement for the ELF file.
1064  */
1065 static size_t
1066 elfsize(const Ehdr *ehdrp, uint_t nphdrs, const caddr_t phdrbase,
1067     uintptr_t *lddata)
1068 {
1069 	const Phdr *phdrp = (Phdr *)phdrbase;
1070 	const uint_t hsize = ehdrp->e_phentsize;
1071 	boolean_t dfirst = B_TRUE;
1072 	uintptr_t loaddr = UINTPTR_MAX;
1073 	uintptr_t hiaddr = 0;
1074 	uint_t i;
1075 
1076 	for (i = nphdrs; i > 0; i--) {
1077 		if (phdrp->p_type == PT_LOAD) {
1078 			const uintptr_t lo = phdrp->p_vaddr;
1079 			const uintptr_t hi = lo + phdrp->p_memsz;
1080 
1081 			loaddr = MIN(lo, loaddr);
1082 			hiaddr = MAX(hi, hiaddr);
1083 
1084 			/*
1085 			 * save the address of the first data segment
1086 			 * of a object - used for the AT_SUNW_LDDATA
1087 			 * aux entry.
1088 			 */
1089 			if ((lddata != NULL) && dfirst &&
1090 			    (phdrp->p_flags & PF_W)) {
1091 				*lddata = lo;
1092 				dfirst = B_FALSE;
1093 			}
1094 		}
1095 		phdrp = (Phdr *)((caddr_t)phdrp + hsize);
1096 	}
1097 
1098 	if (hiaddr <= loaddr) {
1099 		/* No non-zero PT_LOAD segment found */
1100 		return (0);
1101 	}
1102 
1103 	return (roundup(hiaddr - (loaddr & PAGEMASK), PAGESIZE));
1104 }
1105 
1106 /*
1107  * Read in the ELF header and program header table.
1108  * SUSV3 requires:
1109  *	ENOEXEC	File format is not recognized
1110  *	EINVAL	Format recognized but execution not supported
1111  */
1112 static int
1113 getelfhead(vnode_t *vp, cred_t *credp, Ehdr *ehdr, uint_t *nshdrs,
1114     uint_t *shstrndx, uint_t *nphdrs)
1115 {
1116 	int error;
1117 	ssize_t resid;
1118 
1119 	/*
1120 	 * We got here by the first two bytes in ident,
1121 	 * now read the entire ELF header.
1122 	 */
1123 	if ((error = vn_rdwr(UIO_READ, vp, (caddr_t)ehdr,
1124 	    sizeof (Ehdr), (offset_t)0, UIO_SYSSPACE, 0,
1125 	    (rlim64_t)0, credp, &resid)) != 0)
1126 		return (error);
1127 
1128 	/*
1129 	 * Since a separate version is compiled for handling 32-bit and
1130 	 * 64-bit ELF executables on a 64-bit kernel, the 64-bit version
1131 	 * doesn't need to be able to deal with 32-bit ELF files.
1132 	 */
1133 	if (resid != 0 ||
1134 	    ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1135 	    ehdr->e_ident[EI_MAG3] != ELFMAG3)
1136 		return (ENOEXEC);
1137 
1138 	if ((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) ||
1139 #if defined(_ILP32) || defined(_ELF32_COMPAT)
1140 	    ehdr->e_ident[EI_CLASS] != ELFCLASS32 ||
1141 #else
1142 	    ehdr->e_ident[EI_CLASS] != ELFCLASS64 ||
1143 #endif
1144 	    !elfheadcheck(ehdr->e_ident[EI_DATA], ehdr->e_machine,
1145 	    ehdr->e_flags))
1146 		return (EINVAL);
1147 
1148 	*nshdrs = ehdr->e_shnum;
1149 	*shstrndx = ehdr->e_shstrndx;
1150 	*nphdrs = ehdr->e_phnum;
1151 
1152 	/*
1153 	 * If e_shnum, e_shstrndx, or e_phnum is its sentinel value, we need
1154 	 * to read in the section header at index zero to access the true
1155 	 * values for those fields.
1156 	 */
1157 	if ((*nshdrs == 0 && ehdr->e_shoff != 0) ||
1158 	    *shstrndx == SHN_XINDEX || *nphdrs == PN_XNUM) {
1159 		Shdr shdr;
1160 
1161 		if (ehdr->e_shoff == 0)
1162 			return (EINVAL);
1163 
1164 		if ((error = vn_rdwr(UIO_READ, vp, (caddr_t)&shdr,
1165 		    sizeof (shdr), (offset_t)ehdr->e_shoff, UIO_SYSSPACE, 0,
1166 		    (rlim64_t)0, credp, NULL)) != 0) {
1167 			return (error);
1168 		}
1169 
1170 		if (*nshdrs == 0)
1171 			*nshdrs = shdr.sh_size;
1172 		if (*shstrndx == SHN_XINDEX)
1173 			*shstrndx = shdr.sh_link;
1174 		if (*nphdrs == PN_XNUM && shdr.sh_info != 0)
1175 			*nphdrs = shdr.sh_info;
1176 	}
1177 
1178 	return (0);
1179 }
1180 
1181 /*
1182  * We use members through p_flags on 32-bit files and p_memsz on 64-bit files,
1183  * so e_phentsize must be at least large enough to include those members.
1184  */
1185 #if !defined(_LP64) || defined(_ELF32_COMPAT)
1186 #define	MINPHENTSZ	(offsetof(Phdr, p_flags) + \
1187 			sizeof (((Phdr *)NULL)->p_flags))
1188 #else
1189 #define	MINPHENTSZ	(offsetof(Phdr, p_memsz) + \
1190 			sizeof (((Phdr *)NULL)->p_memsz))
1191 #endif
1192 
1193 static int
1194 getelfphdr(vnode_t *vp, cred_t *credp, const Ehdr *ehdr, uint_t nphdrs,
1195     caddr_t *phbasep, size_t *phsizep)
1196 {
1197 	int err;
1198 
1199 	/*
1200 	 * Ensure that e_phentsize is large enough for required fields to be
1201 	 * accessible and will maintain 8-byte alignment.
1202 	 */
1203 	if (ehdr->e_phentsize < MINPHENTSZ || (ehdr->e_phentsize & 3))
1204 		return (EINVAL);
1205 
1206 	*phsizep = nphdrs * ehdr->e_phentsize;
1207 
1208 	if (*phsizep > sizeof (Phdr) * elf_nphdr_max) {
1209 		if ((*phbasep = kmem_alloc(*phsizep, KM_NOSLEEP)) == NULL)
1210 			return (ENOMEM);
1211 	} else {
1212 		*phbasep = kmem_alloc(*phsizep, KM_SLEEP);
1213 	}
1214 
1215 	if ((err = vn_rdwr(UIO_READ, vp, *phbasep, (ssize_t)*phsizep,
1216 	    (offset_t)ehdr->e_phoff, UIO_SYSSPACE, 0, (rlim64_t)0,
1217 	    credp, NULL)) != 0) {
1218 		kmem_free(*phbasep, *phsizep);
1219 		*phbasep = NULL;
1220 		return (err);
1221 	}
1222 
1223 	return (0);
1224 }
1225 
1226 #define	MINSHDRSZ	(offsetof(Shdr, sh_entsize) + \
1227 			sizeof (((Shdr *)NULL)->sh_entsize))
1228 
1229 static int
1230 getelfshdr(vnode_t *vp, cred_t *credp, const Ehdr *ehdr, uint_t nshdrs,
1231     uint_t shstrndx, caddr_t *shbasep, size_t *shsizep, char **shstrbasep,
1232     size_t *shstrsizep)
1233 {
1234 	int err;
1235 	Shdr *shdr;
1236 
1237 	/*
1238 	 * Since we're going to be using e_shentsize to iterate down the
1239 	 * array of section headers, it must be 8-byte aligned or else
1240 	 * a we might cause a misaligned access. We use all members through
1241 	 * sh_entsize (on both 32- and 64-bit ELF files) so e_shentsize
1242 	 * must be at least large enough to include that member. The index
1243 	 * of the string table section must also be valid.
1244 	 */
1245 	if (ehdr->e_shentsize < MINSHDRSZ || (ehdr->e_shentsize & 3) ||
1246 	    nshdrs == 0 || shstrndx >= nshdrs) {
1247 		return (EINVAL);
1248 	}
1249 
1250 	*shsizep = nshdrs * ehdr->e_shentsize;
1251 
1252 	if (*shsizep > sizeof (Shdr) * elf_nshdr_max) {
1253 		if ((*shbasep = kmem_alloc(*shsizep, KM_NOSLEEP)) == NULL)
1254 			return (ENOMEM);
1255 	} else {
1256 		*shbasep = kmem_alloc(*shsizep, KM_SLEEP);
1257 	}
1258 
1259 	if ((err = vn_rdwr(UIO_READ, vp, *shbasep, (ssize_t)*shsizep,
1260 	    (offset_t)ehdr->e_shoff, UIO_SYSSPACE, 0, (rlim64_t)0,
1261 	    credp, NULL)) != 0) {
1262 		kmem_free(*shbasep, *shsizep);
1263 		return (err);
1264 	}
1265 
1266 	/*
1267 	 * Grab the section string table.  Walking through the shdrs is
1268 	 * pointless if their names cannot be interrogated.
1269 	 */
1270 	shdr = (Shdr *)(*shbasep + shstrndx * ehdr->e_shentsize);
1271 	if ((*shstrsizep = shdr->sh_size) == 0) {
1272 		kmem_free(*shbasep, *shsizep);
1273 		return (EINVAL);
1274 	}
1275 
1276 	if (*shstrsizep > elf_shstrtab_max) {
1277 		if ((*shstrbasep = kmem_alloc(*shstrsizep,
1278 		    KM_NOSLEEP)) == NULL) {
1279 			kmem_free(*shbasep, *shsizep);
1280 			return (ENOMEM);
1281 		}
1282 	} else {
1283 		*shstrbasep = kmem_alloc(*shstrsizep, KM_SLEEP);
1284 	}
1285 
1286 	if ((err = vn_rdwr(UIO_READ, vp, *shstrbasep, (ssize_t)*shstrsizep,
1287 	    (offset_t)shdr->sh_offset, UIO_SYSSPACE, 0, (rlim64_t)0,
1288 	    credp, NULL)) != 0) {
1289 		kmem_free(*shbasep, *shsizep);
1290 		kmem_free(*shstrbasep, *shstrsizep);
1291 		return (err);
1292 	}
1293 
1294 	/*
1295 	 * Make sure the strtab is null-terminated to make sure we
1296 	 * don't run off the end of the table.
1297 	 */
1298 	(*shstrbasep)[*shstrsizep - 1] = '\0';
1299 
1300 	return (0);
1301 }
1302 
1303 int
1304 elfreadhdr(vnode_t *vp, cred_t *credp, Ehdr *ehdrp, uint_t *nphdrs,
1305     caddr_t *phbasep, size_t *phsizep)
1306 {
1307 	int error;
1308 	uint_t nshdrs, shstrndx;
1309 
1310 	if ((error = getelfhead(vp, credp, ehdrp, &nshdrs, &shstrndx,
1311 	    nphdrs)) != 0 ||
1312 	    (error = getelfphdr(vp, credp, ehdrp, *nphdrs, phbasep,
1313 	    phsizep)) != 0) {
1314 		return (error);
1315 	}
1316 	return (0);
1317 }
1318 
1319 static int
1320 mapelfexec(
1321 	vnode_t *vp,
1322 	Ehdr *ehdr,
1323 	uint_t nphdrs,
1324 	caddr_t phdrbase,
1325 	Phdr **uphdr,
1326 	Phdr **intphdr,
1327 	Phdr **stphdr,
1328 	Phdr **dtphdr,
1329 	Phdr *dataphdrp,
1330 	caddr_t *bssbase,
1331 	caddr_t *brkbase,
1332 	intptr_t *voffset,
1333 	uintptr_t *minaddrp,
1334 	size_t len,
1335 	size_t *execsz,
1336 	size_t *brksize)
1337 {
1338 	Phdr *phdr;
1339 	int error, page, prot;
1340 	caddr_t addr = NULL;
1341 	caddr_t minaddr = (caddr_t)UINTPTR_MAX;
1342 	uint_t i;
1343 	size_t zfodsz, memsz;
1344 	boolean_t ptload = B_FALSE;
1345 	off_t offset;
1346 	const uint_t hsize = ehdr->e_phentsize;
1347 	extern int use_brk_lpg;
1348 
1349 	if (ehdr->e_type == ET_DYN) {
1350 		secflagset_t flags = 0;
1351 		/*
1352 		 * Obtain the virtual address of a hole in the
1353 		 * address space to map the "interpreter".
1354 		 */
1355 		if (secflag_enabled(curproc, PROC_SEC_ASLR))
1356 			flags |= _MAP_RANDOMIZE;
1357 
1358 		map_addr(&addr, len, (offset_t)0, 1, flags);
1359 		if (addr == NULL)
1360 			return (ENOMEM);
1361 		*voffset = (intptr_t)addr;
1362 
1363 		/*
1364 		 * Calculate the minimum vaddr so it can be subtracted out.
1365 		 * According to the ELF specification, since PT_LOAD sections
1366 		 * must be sorted by increasing p_vaddr values, this is
1367 		 * guaranteed to be the first PT_LOAD section.
1368 		 */
1369 		phdr = (Phdr *)phdrbase;
1370 		for (i = nphdrs; i > 0; i--) {
1371 			if (phdr->p_type == PT_LOAD) {
1372 				*voffset -= (uintptr_t)phdr->p_vaddr;
1373 				break;
1374 			}
1375 			phdr = (Phdr *)((caddr_t)phdr + hsize);
1376 		}
1377 
1378 	} else {
1379 		*voffset = 0;
1380 	}
1381 
1382 	phdr = (Phdr *)phdrbase;
1383 	for (i = nphdrs; i > 0; i--) {
1384 		switch (phdr->p_type) {
1385 		case PT_LOAD:
1386 			ptload = B_TRUE;
1387 			prot = PROT_USER;
1388 			if (phdr->p_flags & PF_R)
1389 				prot |= PROT_READ;
1390 			if (phdr->p_flags & PF_W)
1391 				prot |= PROT_WRITE;
1392 			if (phdr->p_flags & PF_X)
1393 				prot |= PROT_EXEC;
1394 
1395 			addr = (caddr_t)((uintptr_t)phdr->p_vaddr + *voffset);
1396 
1397 			if (*intphdr != NULL && uphdr != NULL &&
1398 			    *uphdr == NULL) {
1399 				/*
1400 				 * The PT_PHDR program header is, strictly
1401 				 * speaking, optional.  If we find that this
1402 				 * is missing, we will determine the location
1403 				 * of the program headers based on the address
1404 				 * of the lowest PT_LOAD segment (namely, this
1405 				 * one):  we subtract the p_offset to get to
1406 				 * the ELF header and then add back the program
1407 				 * header offset to get to the program headers.
1408 				 * We then cons up a Phdr that corresponds to
1409 				 * the (missing) PT_PHDR, setting the flags
1410 				 * to 0 to denote that this is artificial and
1411 				 * should (must) be freed by the caller.
1412 				 */
1413 				Phdr *cons;
1414 
1415 				cons = kmem_zalloc(sizeof (Phdr), KM_SLEEP);
1416 
1417 				cons->p_flags = 0;
1418 				cons->p_type = PT_PHDR;
1419 				cons->p_vaddr = ((uintptr_t)addr -
1420 				    phdr->p_offset) + ehdr->e_phoff;
1421 
1422 				*uphdr = cons;
1423 			}
1424 
1425 			/*
1426 			 * The ELF spec dictates that p_filesz may not be
1427 			 * larger than p_memsz in PT_LOAD segments.
1428 			 */
1429 			if (phdr->p_filesz > phdr->p_memsz) {
1430 				error = EINVAL;
1431 				goto bad;
1432 			}
1433 
1434 			/*
1435 			 * Keep track of the segment with the lowest starting
1436 			 * address.
1437 			 */
1438 			if (addr < minaddr)
1439 				minaddr = addr;
1440 
1441 			zfodsz = (size_t)phdr->p_memsz - phdr->p_filesz;
1442 
1443 			offset = phdr->p_offset;
1444 			if (((uintptr_t)offset & PAGEOFFSET) ==
1445 			    ((uintptr_t)addr & PAGEOFFSET) &&
1446 			    (!(vp->v_flag & VNOMAP))) {
1447 				page = 1;
1448 			} else {
1449 				page = 0;
1450 			}
1451 
1452 			/*
1453 			 * Set the heap pagesize for OOB when the bss size
1454 			 * is known and use_brk_lpg is not 0.
1455 			 */
1456 			if (brksize != NULL && use_brk_lpg &&
1457 			    zfodsz != 0 && phdr == dataphdrp &&
1458 			    (prot & PROT_WRITE)) {
1459 				const size_t tlen = P2NPHASE((uintptr_t)addr +
1460 				    phdr->p_filesz, PAGESIZE);
1461 
1462 				if (zfodsz > tlen) {
1463 					const caddr_t taddr = addr +
1464 					    phdr->p_filesz + tlen;
1465 
1466 					/*
1467 					 * Since a hole in the AS large enough
1468 					 * for this object as calculated by
1469 					 * elfsize() is available, we do not
1470 					 * need to fear overflow for 'taddr'.
1471 					 */
1472 					curproc->p_brkpageszc =
1473 					    page_szc(map_pgsz(MAPPGSZ_HEAP,
1474 					    curproc, taddr, zfodsz - tlen, 0));
1475 				}
1476 			}
1477 
1478 			if (curproc->p_brkpageszc != 0 && phdr == dataphdrp &&
1479 			    (prot & PROT_WRITE)) {
1480 				uint_t	szc = curproc->p_brkpageszc;
1481 				size_t pgsz = page_get_pagesize(szc);
1482 				caddr_t ebss = addr + phdr->p_memsz;
1483 				/*
1484 				 * If we need extra space to keep the BSS an
1485 				 * integral number of pages in size, some of
1486 				 * that space may fall beyond p_brkbase, so we
1487 				 * need to set p_brksize to account for it
1488 				 * being (logically) part of the brk.
1489 				 */
1490 				size_t extra_zfodsz;
1491 
1492 				ASSERT(pgsz > PAGESIZE);
1493 
1494 				extra_zfodsz = P2NPHASE((uintptr_t)ebss, pgsz);
1495 
1496 				if (error = execmap(vp, addr, phdr->p_filesz,
1497 				    zfodsz + extra_zfodsz, phdr->p_offset,
1498 				    prot, page, szc))
1499 					goto bad;
1500 				if (brksize != NULL)
1501 					*brksize = extra_zfodsz;
1502 			} else {
1503 				if (error = execmap(vp, addr, phdr->p_filesz,
1504 				    zfodsz, phdr->p_offset, prot, page, 0))
1505 					goto bad;
1506 			}
1507 
1508 			if (bssbase != NULL && addr >= *bssbase &&
1509 			    phdr == dataphdrp) {
1510 				*bssbase = addr + phdr->p_filesz;
1511 			}
1512 			if (brkbase != NULL && addr >= *brkbase) {
1513 				*brkbase = addr + phdr->p_memsz;
1514 			}
1515 
1516 			memsz = btopr(phdr->p_memsz);
1517 			if ((*execsz + memsz) < *execsz) {
1518 				error = ENOMEM;
1519 				goto bad;
1520 			}
1521 			*execsz += memsz;
1522 			break;
1523 
1524 		case PT_INTERP:
1525 			if (ptload)
1526 				goto bad;
1527 			*intphdr = phdr;
1528 			break;
1529 
1530 		case PT_SHLIB:
1531 			*stphdr = phdr;
1532 			break;
1533 
1534 		case PT_PHDR:
1535 			if (ptload || phdr->p_flags == 0)
1536 				goto bad;
1537 
1538 			if (uphdr != NULL)
1539 				*uphdr = phdr;
1540 
1541 			break;
1542 
1543 		case PT_NULL:
1544 		case PT_DYNAMIC:
1545 		case PT_NOTE:
1546 			break;
1547 
1548 		case PT_SUNWDTRACE:
1549 			if (dtphdr != NULL)
1550 				*dtphdr = phdr;
1551 			break;
1552 
1553 		default:
1554 			break;
1555 		}
1556 		phdr = (Phdr *)((caddr_t)phdr + hsize);
1557 	}
1558 
1559 	if (minaddrp != NULL) {
1560 		ASSERT(minaddr != (caddr_t)UINTPTR_MAX);
1561 		*minaddrp = (uintptr_t)minaddr;
1562 	}
1563 
1564 	if (brkbase != NULL && secflag_enabled(curproc, PROC_SEC_ASLR)) {
1565 		size_t off;
1566 		uintptr_t base = (uintptr_t)*brkbase;
1567 		uintptr_t oend = base + *brksize;
1568 
1569 		ASSERT(ISP2(aslr_max_brk_skew));
1570 
1571 		(void) random_get_pseudo_bytes((uint8_t *)&off, sizeof (off));
1572 		base += P2PHASE(off, aslr_max_brk_skew);
1573 		base = P2ROUNDUP(base, PAGESIZE);
1574 		*brkbase = (caddr_t)base;
1575 		/*
1576 		 * Above, we set *brksize to account for the possibility we
1577 		 * had to grow the 'brk' in padding out the BSS to a page
1578 		 * boundary.
1579 		 *
1580 		 * We now need to adjust that based on where we now are
1581 		 * actually putting the brk.
1582 		 */
1583 		if (oend > base)
1584 			*brksize = oend - base;
1585 		else
1586 			*brksize = 0;
1587 	}
1588 
1589 	return (0);
1590 bad:
1591 	if (error == 0)
1592 		error = EINVAL;
1593 	return (error);
1594 }
1595 
1596 int
1597 elfnote(vnode_t *vp, offset_t *offsetp, int type, int descsz, void *desc,
1598     rlim64_t rlimit, cred_t *credp)
1599 {
1600 	Note note;
1601 	int error;
1602 
1603 	bzero(&note, sizeof (note));
1604 	bcopy("CORE", note.name, 4);
1605 	note.nhdr.n_type = type;
1606 	/*
1607 	 * The System V ABI states that n_namesz must be the length of the
1608 	 * string that follows the Nhdr structure including the terminating
1609 	 * null. The ABI also specifies that sufficient padding should be
1610 	 * included so that the description that follows the name string
1611 	 * begins on a 4- or 8-byte boundary for 32- and 64-bit binaries
1612 	 * respectively. However, since this change was not made correctly
1613 	 * at the time of the 64-bit port, both 32- and 64-bit binaries
1614 	 * descriptions are only guaranteed to begin on a 4-byte boundary.
1615 	 */
1616 	note.nhdr.n_namesz = 5;
1617 	note.nhdr.n_descsz = roundup(descsz, sizeof (Word));
1618 
1619 	if (error = core_write(vp, UIO_SYSSPACE, *offsetp, &note,
1620 	    sizeof (note), rlimit, credp))
1621 		return (error);
1622 
1623 	*offsetp += sizeof (note);
1624 
1625 	if (error = core_write(vp, UIO_SYSSPACE, *offsetp, desc,
1626 	    note.nhdr.n_descsz, rlimit, credp))
1627 		return (error);
1628 
1629 	*offsetp += note.nhdr.n_descsz;
1630 	return (0);
1631 }
1632 
1633 /*
1634  * Copy the section data from one vnode to the section of another vnode.
1635  */
1636 static void
1637 elf_copy_scn(elf_core_ctx_t *ctx, const Shdr *src, vnode_t *src_vp, Shdr *dst)
1638 {
1639 	size_t n = src->sh_size;
1640 	u_offset_t off = 0;
1641 	const u_offset_t soff = src->sh_offset;
1642 	const u_offset_t doff = ctx->ecc_doffset;
1643 	void *buf = ctx->ecc_buf;
1644 	vnode_t *dst_vp = ctx->ecc_vp;
1645 	cred_t *credp = ctx->ecc_credp;
1646 
1647 	/* Protect the copy loop below from overflow on the offsets */
1648 	if (n > OFF_MAX || (n + soff) > OFF_MAX || (n + doff) > OFF_MAX ||
1649 	    (n + soff) < n || (n + doff) < n) {
1650 		dst->sh_size = 0;
1651 		dst->sh_offset = 0;
1652 		return;
1653 	}
1654 
1655 	while (n != 0) {
1656 		const size_t len = MIN(ctx->ecc_bufsz, n);
1657 		ssize_t resid;
1658 
1659 		if (vn_rdwr(UIO_READ, src_vp, buf, (ssize_t)len,
1660 		    (offset_t)(soff + off),
1661 		    UIO_SYSSPACE, 0, (rlim64_t)0, credp, &resid) != 0 ||
1662 		    resid >= len || resid < 0 ||
1663 		    core_write(dst_vp, UIO_SYSSPACE, (offset_t)(doff + off),
1664 		    buf, len - resid, ctx->ecc_rlimit, credp) != 0) {
1665 			dst->sh_size = 0;
1666 			dst->sh_offset = 0;
1667 			return;
1668 		}
1669 
1670 		ASSERT(n >= len - resid);
1671 
1672 		n -= len - resid;
1673 		off += len - resid;
1674 	}
1675 
1676 	ctx->ecc_doffset += src->sh_size;
1677 }
1678 
1679 /*
1680  * Walk sections for a given ELF object, counting (or copying) those of
1681  * interest (CTF, symtab, strtab, .debug_*).
1682  */
1683 static int
1684 elf_process_obj_scns(elf_core_ctx_t *ctx, vnode_t *mvp, caddr_t saddr,
1685     Shdr *v, uint_t idx, const uint_t remain, shstrtab_t *shstrtab,
1686     uint_t *countp)
1687 {
1688 	Ehdr ehdr;
1689 	const core_content_t content = ctx->ecc_content;
1690 	cred_t *credp = ctx->ecc_credp;
1691 	Shdr *ctf = NULL, *symtab = NULL, *strtab = NULL;
1692 	uintptr_t off = 0;
1693 	uint_t nshdrs, shstrndx, nphdrs, count, extra;
1694 	u_offset_t *doffp = &ctx->ecc_doffset;
1695 	boolean_t ctf_link = B_FALSE;
1696 	caddr_t shbase;
1697 	size_t shsize, shstrsize;
1698 	char *shstrbase;
1699 	int error = 0;
1700 	const boolean_t justcounting = (v == NULL);
1701 
1702 	/*
1703 	 * remain must be less than UINT_MAX so we can check for count
1704 	 * exceeding it.
1705 	 */
1706 	ASSERT3U(remain, <, UINT_MAX);
1707 
1708 	*countp = count = 0;
1709 
1710 	if ((content &
1711 	    (CC_CONTENT_CTF | CC_CONTENT_SYMTAB | CC_CONTENT_DEBUG)) == 0) {
1712 		return (0);
1713 	}
1714 
1715 	if (getelfhead(mvp, credp, &ehdr, &nshdrs, &shstrndx, &nphdrs) != 0 ||
1716 	    getelfshdr(mvp, credp, &ehdr, nshdrs, shstrndx, &shbase, &shsize,
1717 	    &shstrbase, &shstrsize) != 0) {
1718 		return (0);
1719 	}
1720 
1721 	/* Starting at index 1 skips SHT_NULL which is expected at index 0 */
1722 	off = ehdr.e_shentsize;
1723 	for (uint_t i = 1; i < nshdrs; i++, off += ehdr.e_shentsize) {
1724 		Shdr *shdr, *symchk = NULL, *strchk;
1725 		const char *name;
1726 
1727 		shdr = (Shdr *)(shbase + off);
1728 		if (shdr->sh_name >= shstrsize || shdr->sh_type == SHT_NULL)
1729 			continue;
1730 
1731 		name = shstrbase + shdr->sh_name;
1732 
1733 		if (ctf == NULL && (content & CC_CONTENT_CTF) != 0 &&
1734 		    strcmp(name, shstrtab_data[STR_CTF]) == 0) {
1735 			ctf = shdr;
1736 			if (ctf->sh_link != 0 && ctf->sh_link < nshdrs) {
1737 				/* check linked symtab below */
1738 				symchk = (Shdr *)(shbase +
1739 				    shdr->sh_link * ehdr.e_shentsize);
1740 				ctf_link = B_TRUE;
1741 			} else {
1742 				continue;
1743 			}
1744 		} else if (symtab == NULL &&
1745 		    (content & CC_CONTENT_SYMTAB) != 0 &&
1746 		    strcmp(name, shstrtab_data[STR_SYMTAB]) == 0) {
1747 			symchk = shdr;
1748 		} else if ((content & CC_CONTENT_DEBUG) != 0 &&
1749 		    strncmp(name, ".debug_", strlen(".debug_")) == 0) {
1750 			/*
1751 			 * The design of the above check is intentional. In
1752 			 * particular, we want to capture any sections that
1753 			 * begin with '.debug_' for a few reasons:
1754 			 *
1755 			 * 1) Various revisions to the DWARF spec end up
1756 			 * changing the set of section headers that exist. This
1757 			 * ensures that we don't need to change the kernel to
1758 			 * get a new version.
1759 			 *
1760 			 * 2) Other software uses .debug_ sections for things
1761 			 * which aren't DWARF. This allows them to be captured
1762 			 * as well.
1763 			 */
1764 			count++;
1765 
1766 			if (count > remain) {
1767 				error = ENOMEM;
1768 				goto done;
1769 			}
1770 
1771 			if (justcounting)
1772 				continue;
1773 
1774 			elf_ctx_resize_scratch(ctx, shdr->sh_size);
1775 
1776 			if (!shstrtab_ndx(shstrtab, name, &v[idx].sh_name)) {
1777 				error = ENOMEM;
1778 				goto done;
1779 			}
1780 
1781 			v[idx].sh_addr = (Addr)(uintptr_t)saddr;
1782 			v[idx].sh_type = shdr->sh_type;
1783 			v[idx].sh_addralign = shdr->sh_addralign;
1784 			*doffp = roundup(*doffp, v[idx].sh_addralign);
1785 			v[idx].sh_offset = *doffp;
1786 			v[idx].sh_size = shdr->sh_size;
1787 			v[idx].sh_link = 0;
1788 			v[idx].sh_entsize = shdr->sh_entsize;
1789 			v[idx].sh_info = shdr->sh_info;
1790 
1791 			elf_copy_scn(ctx, shdr, mvp, &v[idx]);
1792 			idx++;
1793 
1794 			continue;
1795 		} else {
1796 			continue;
1797 		}
1798 
1799 		ASSERT(symchk != NULL);
1800 		if ((symchk->sh_type != SHT_DYNSYM &&
1801 		    symchk->sh_type != SHT_SYMTAB) ||
1802 		    symchk->sh_link == 0 || symchk->sh_link >= nshdrs) {
1803 			ctf_link = B_FALSE;
1804 			continue;
1805 		}
1806 		strchk = (Shdr *)(shbase + symchk->sh_link * ehdr.e_shentsize);
1807 		if (strchk->sh_type != SHT_STRTAB) {
1808 			ctf_link = B_FALSE;
1809 			continue;
1810 		}
1811 		symtab = symchk;
1812 		strtab = strchk;
1813 
1814 		if (symtab != NULL && ctf != NULL &&
1815 		    (content & CC_CONTENT_DEBUG) == 0) {
1816 			/* No other shdrs are of interest at this point */
1817 			break;
1818 		}
1819 	}
1820 
1821 	extra = 0;
1822 	if (ctf != NULL)
1823 		extra += 1;
1824 	if (symtab != NULL)
1825 		extra += 2;
1826 
1827 	if (remain < extra || count > remain - extra) {
1828 		error = ENOMEM;
1829 		goto done;
1830 	}
1831 
1832 	count += extra;
1833 
1834 	if (justcounting)
1835 		goto done;
1836 
1837 	/* output CTF section */
1838 	if (ctf != NULL) {
1839 		elf_ctx_resize_scratch(ctx, ctf->sh_size);
1840 
1841 		if (!shstrtab_ndx(shstrtab,
1842 		    shstrtab_data[STR_CTF], &v[idx].sh_name)) {
1843 			error = ENOMEM;
1844 			goto done;
1845 		}
1846 		v[idx].sh_addr = (Addr)(uintptr_t)saddr;
1847 		v[idx].sh_type = SHT_PROGBITS;
1848 		v[idx].sh_addralign = 4;
1849 		*doffp = roundup(*doffp, v[idx].sh_addralign);
1850 		v[idx].sh_offset = *doffp;
1851 		v[idx].sh_size = ctf->sh_size;
1852 
1853 		if (ctf_link) {
1854 			/*
1855 			 * The linked symtab (and strtab) will be output
1856 			 * immediately after this CTF section.  Its shdr index
1857 			 * directly follows this one.
1858 			 */
1859 			v[idx].sh_link = idx + 1;
1860 			ASSERT(symtab != NULL);
1861 		} else {
1862 			v[idx].sh_link = 0;
1863 		}
1864 		elf_copy_scn(ctx, ctf, mvp, &v[idx]);
1865 		idx++;
1866 	}
1867 
1868 	/* output SYMTAB/STRTAB sections */
1869 	if (symtab != NULL) {
1870 		shstrtype_t symtab_type, strtab_type;
1871 		uint_t symtab_name, strtab_name;
1872 
1873 		elf_ctx_resize_scratch(ctx,
1874 		    MAX(symtab->sh_size, strtab->sh_size));
1875 
1876 		if (symtab->sh_type == SHT_DYNSYM) {
1877 			symtab_type = STR_DYNSYM;
1878 			strtab_type = STR_DYNSTR;
1879 		} else {
1880 			symtab_type = STR_SYMTAB;
1881 			strtab_type = STR_STRTAB;
1882 		}
1883 
1884 		if (!shstrtab_ndx(shstrtab,
1885 		    shstrtab_data[symtab_type], &symtab_name)) {
1886 			error = ENOMEM;
1887 			goto done;
1888 		}
1889 		if (!shstrtab_ndx(shstrtab,
1890 		    shstrtab_data[strtab_type], &strtab_name)) {
1891 			error = ENOMEM;
1892 			goto done;
1893 		}
1894 
1895 		v[idx].sh_name = symtab_name;
1896 		v[idx].sh_type = symtab->sh_type;
1897 		v[idx].sh_addr = symtab->sh_addr;
1898 		if (ehdr.e_type == ET_DYN || v[idx].sh_addr == 0)
1899 			v[idx].sh_addr += (Addr)(uintptr_t)saddr;
1900 		v[idx].sh_addralign = symtab->sh_addralign;
1901 		*doffp = roundup(*doffp, v[idx].sh_addralign);
1902 		v[idx].sh_offset = *doffp;
1903 		v[idx].sh_size = symtab->sh_size;
1904 		v[idx].sh_link = idx + 1;
1905 		v[idx].sh_entsize = symtab->sh_entsize;
1906 		v[idx].sh_info = symtab->sh_info;
1907 
1908 		elf_copy_scn(ctx, symtab, mvp, &v[idx]);
1909 		idx++;
1910 
1911 		v[idx].sh_name = strtab_name;
1912 		v[idx].sh_type = SHT_STRTAB;
1913 		v[idx].sh_flags = SHF_STRINGS;
1914 		v[idx].sh_addr = strtab->sh_addr;
1915 		if (ehdr.e_type == ET_DYN || v[idx].sh_addr == 0)
1916 			v[idx].sh_addr += (Addr)(uintptr_t)saddr;
1917 		v[idx].sh_addralign = strtab->sh_addralign;
1918 		*doffp = roundup(*doffp, v[idx].sh_addralign);
1919 		v[idx].sh_offset = *doffp;
1920 		v[idx].sh_size = strtab->sh_size;
1921 
1922 		elf_copy_scn(ctx, strtab, mvp, &v[idx]);
1923 		idx++;
1924 	}
1925 
1926 done:
1927 	kmem_free(shstrbase, shstrsize);
1928 	kmem_free(shbase, shsize);
1929 
1930 	if (error == 0)
1931 		*countp = count;
1932 
1933 	return (error);
1934 }
1935 
1936 /*
1937  * Walk mappings in process address space, examining those which correspond to
1938  * loaded objects.  It is called twice from elfcore: Once to simply count
1939  * relevant sections, and again later to copy those sections once an adequate
1940  * buffer has been allocated for the shdr details.
1941  */
1942 static int
1943 elf_process_scns(elf_core_ctx_t *ctx, Shdr *v, const uint_t nv, uint_t *nshdrsp)
1944 {
1945 	vnode_t *lastvp = NULL;
1946 	struct seg *seg;
1947 	uint_t remain, idx;
1948 	shstrtab_t shstrtab;
1949 	struct as *as = ctx->ecc_p->p_as;
1950 	int error = 0;
1951 	const boolean_t justcounting = (v == NULL);
1952 
1953 	ASSERT(AS_WRITE_HELD(as));
1954 
1955 	if (justcounting) {
1956 		ASSERT(nv == 0);
1957 		/*
1958 		 * In the counting case, set remain to UINT_MAX so that we
1959 		 * allow up to that many sections. Note that remain is
1960 		 * decremented immediately below to account for the SHT_NULL
1961 		 * section at index zero and so we do not end up passing
1962 		 * UINT_MAX as the 'remain' value to elf_process_obj_scns().
1963 		 * Once we've finished counting, we further check that there
1964 		 * is at least one array slot available for shstrtab.
1965 		 */
1966 		remain = UINT_MAX;
1967 	} else {
1968 		ASSERT(nv != 0);
1969 		remain = nv;
1970 
1971 		if (!shstrtab_init(&shstrtab))
1972 			return (ENOMEM);
1973 	}
1974 
1975 	/* Per the ELF spec, shdr index 0 is reserved. */
1976 	idx = 1;
1977 	remain--;
1978 	for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
1979 		vnode_t *mvp;
1980 		void *tmp = NULL;
1981 		caddr_t saddr = seg->s_base, naddr, eaddr;
1982 		size_t segsize;
1983 		uint_t count, prot;
1984 
1985 		/*
1986 		 * Since we're just looking for text segments of load
1987 		 * objects, we only care about the protection bits; we don't
1988 		 * care about the actual size of the segment so we use the
1989 		 * reserved size. If the segment's size is zero, there's
1990 		 * something fishy going on so we ignore this segment.
1991 		 */
1992 		if (seg->s_ops != &segvn_ops ||
1993 		    SEGOP_GETVP(seg, seg->s_base, &mvp) != 0 ||
1994 		    mvp == lastvp || mvp == NULL || mvp->v_type != VREG ||
1995 		    (segsize = pr_getsegsize(seg, 1)) == 0) {
1996 			continue;
1997 		}
1998 
1999 		eaddr = saddr + segsize;
2000 		prot = pr_getprot(seg, 1, &tmp, &saddr, &naddr, eaddr);
2001 		pr_getprot_done(&tmp);
2002 
2003 		/*
2004 		 * Skip this segment unless the protection bits look like
2005 		 * what we'd expect for a text segment.
2006 		 */
2007 		if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
2008 			continue;
2009 
2010 		error = elf_process_obj_scns(ctx, mvp, saddr, v, idx, remain,
2011 		    &shstrtab, &count);
2012 		if (error != 0)
2013 			goto done;
2014 
2015 		VERIFY3U(count, <=, remain);
2016 		if (!justcounting) {
2017 			VERIFY3U(idx + count, <=, nv);
2018 		}
2019 
2020 		remain -= count;
2021 		idx += count;
2022 		lastvp = mvp;
2023 	}
2024 
2025 	if (justcounting) {
2026 		if (idx == 1) {
2027 			/* No sections found */
2028 			*nshdrsp = 0;
2029 		} else if (remain < 1) {
2030 			/* No space for the shrstrtab at the end */
2031 			*nshdrsp = 0;
2032 			return (ENOMEM);
2033 		} else {
2034 			/* Include room for the shrstrtab at the end */
2035 			*nshdrsp = idx + 1;
2036 		}
2037 		return (0);
2038 	}
2039 
2040 	if (remain != 1) {
2041 		cmn_err(CE_WARN, "elfcore: core dump failed for "
2042 		    "process %d; address space is changing",
2043 		    ctx->ecc_p->p_pid);
2044 		error = EIO;
2045 		goto done;
2046 	}
2047 
2048 	if (!shstrtab_ndx(&shstrtab, shstrtab_data[STR_SHSTRTAB],
2049 	    &v[idx].sh_name)) {
2050 		error = ENOMEM;
2051 		goto done;
2052 	}
2053 	v[idx].sh_size = shstrtab_size(&shstrtab);
2054 	v[idx].sh_addralign = 1;
2055 	v[idx].sh_offset = ctx->ecc_doffset;
2056 	v[idx].sh_flags = SHF_STRINGS;
2057 	v[idx].sh_type = SHT_STRTAB;
2058 
2059 	elf_ctx_resize_scratch(ctx, v[idx].sh_size);
2060 	VERIFY3U(ctx->ecc_bufsz, >=, v[idx].sh_size);
2061 	shstrtab_dump(&shstrtab, ctx->ecc_buf);
2062 
2063 	error = core_write(ctx->ecc_vp, UIO_SYSSPACE, ctx->ecc_doffset,
2064 	    ctx->ecc_buf, v[idx].sh_size, ctx->ecc_rlimit, ctx->ecc_credp);
2065 	if (error == 0)
2066 		ctx->ecc_doffset += v[idx].sh_size;
2067 
2068 done:
2069 	if (!justcounting)
2070 		shstrtab_fini(&shstrtab);
2071 
2072 	return (error);
2073 }
2074 
2075 
2076 #define	NOTES_SECTIONS 1
2077 
2078 int
2079 elfcore(vnode_t *vp, proc_t *p, cred_t *credp, rlim64_t rlimit, int sig,
2080     core_content_t content)
2081 {
2082 	u_offset_t poffset, soffset, doffset;
2083 	int error;
2084 	uint_t i, nphdrs, nshdrs;
2085 	struct seg *seg;
2086 	struct as *as = p->p_as;
2087 	void *bigwad, *zeropg = NULL;
2088 	size_t bigsize, phdrsz, shdrsz;
2089 	Ehdr *ehdr;
2090 	Phdr *phdr;
2091 	Shdr shdr0;
2092 	caddr_t brkbase, stkbase;
2093 	size_t brksize, stksize;
2094 	boolean_t overflowed = B_FALSE, retried = B_FALSE;
2095 	klwp_t *lwp = ttolwp(curthread);
2096 	elf_core_ctx_t ctx = {
2097 		.ecc_vp = vp,
2098 		.ecc_p = p,
2099 		.ecc_credp = credp,
2100 		.ecc_rlimit = rlimit,
2101 		.ecc_content = content,
2102 		.ecc_doffset = 0,
2103 		.ecc_buf = NULL,
2104 		.ecc_bufsz = 0
2105 	};
2106 
2107 top:
2108 	/*
2109 	 * Make sure we have everything we need (registers, etc.).
2110 	 * All other lwps have already stopped and are in an orderly state.
2111 	 */
2112 	ASSERT(p == ttoproc(curthread));
2113 	prstop(0, 0);
2114 
2115 	AS_LOCK_ENTER(as, RW_WRITER);
2116 
2117 	nphdrs = prnsegs(as, 0) + NOTES_SECTIONS;
2118 
2119 	/*
2120 	 * Count the number of section headers we're going to need.
2121 	 */
2122 	nshdrs = error = 0;
2123 	if (content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB | CC_CONTENT_DEBUG))
2124 		error = elf_process_scns(&ctx, NULL, 0, &nshdrs);
2125 	AS_LOCK_EXIT(as);
2126 
2127 	if (error != 0)
2128 		return (error);
2129 
2130 	/*
2131 	 * The core file contents may require zero section headers, but if
2132 	 * we overflow the 16 bits allotted to the program header count in
2133 	 * the ELF header, we'll need that program header at index zero.
2134 	 */
2135 	if (nshdrs == 0 && nphdrs >= PN_XNUM)
2136 		nshdrs = 1;
2137 
2138 	/*
2139 	 * Allocate a buffer which is sized adequately to hold the ehdr, phdrs
2140 	 * or shdrs needed to produce the core file.  It is used for the three
2141 	 * tasks sequentially, not simultaneously, so it does not need space
2142 	 * for all three data at once, only the largest one.
2143 	 */
2144 	VERIFY3U(nphdrs, >=, NOTES_SECTIONS);
2145 	phdrsz = nphdrs * sizeof (Phdr);
2146 	shdrsz = nshdrs * sizeof (Shdr);
2147 	bigsize = MAX(sizeof (Ehdr), MAX(phdrsz, shdrsz));
2148 	bigwad = kmem_alloc(bigsize, KM_SLEEP);
2149 
2150 	ehdr = (Ehdr *)bigwad;
2151 	bzero(ehdr, sizeof (*ehdr));
2152 
2153 	ehdr->e_ident[EI_MAG0] = ELFMAG0;
2154 	ehdr->e_ident[EI_MAG1] = ELFMAG1;
2155 	ehdr->e_ident[EI_MAG2] = ELFMAG2;
2156 	ehdr->e_ident[EI_MAG3] = ELFMAG3;
2157 	ehdr->e_ident[EI_CLASS] = ELFCLASS;
2158 	ehdr->e_type = ET_CORE;
2159 
2160 #if !defined(_LP64) || defined(_ELF32_COMPAT)
2161 
2162 #if defined(__sparc)
2163 	ehdr->e_ident[EI_DATA] = ELFDATA2MSB;
2164 	ehdr->e_machine = EM_SPARC;
2165 #elif defined(__i386_COMPAT)
2166 	ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
2167 	ehdr->e_machine = EM_386;
2168 #else
2169 #error "no recognized machine type is defined"
2170 #endif
2171 
2172 #else	/* !defined(_LP64) || defined(_ELF32_COMPAT) */
2173 
2174 #if defined(__sparc)
2175 	ehdr->e_ident[EI_DATA] = ELFDATA2MSB;
2176 	ehdr->e_machine = EM_SPARCV9;
2177 #elif defined(__amd64)
2178 	ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
2179 	ehdr->e_machine = EM_AMD64;
2180 #else
2181 #error "no recognized 64-bit machine type is defined"
2182 #endif
2183 
2184 #endif	/* !defined(_LP64) || defined(_ELF32_COMPAT) */
2185 
2186 	poffset = sizeof (Ehdr);
2187 	soffset = sizeof (Ehdr) + phdrsz;
2188 	doffset = sizeof (Ehdr) + phdrsz + shdrsz;
2189 	bzero(&shdr0, sizeof (shdr0));
2190 
2191 	/*
2192 	 * If the count of program headers or section headers or the index
2193 	 * of the section string table can't fit in the mere 16 bits
2194 	 * shortsightedly allotted to them in the ELF header, we use the
2195 	 * extended formats and put the real values in the section header
2196 	 * as index 0.
2197 	 */
2198 	if (nphdrs >= PN_XNUM) {
2199 		ehdr->e_phnum = PN_XNUM;
2200 		shdr0.sh_info = nphdrs;
2201 	} else {
2202 		ehdr->e_phnum = (unsigned short)nphdrs;
2203 	}
2204 
2205 	if (nshdrs > 0) {
2206 		if (nshdrs >= SHN_LORESERVE) {
2207 			ehdr->e_shnum = 0;
2208 			shdr0.sh_size = nshdrs;
2209 		} else {
2210 			ehdr->e_shnum = (unsigned short)nshdrs;
2211 		}
2212 
2213 		if (nshdrs - 1 >= SHN_LORESERVE) {
2214 			ehdr->e_shstrndx = SHN_XINDEX;
2215 			shdr0.sh_link = nshdrs - 1;
2216 		} else {
2217 			ehdr->e_shstrndx = (unsigned short)(nshdrs - 1);
2218 		}
2219 
2220 		ehdr->e_shoff = soffset;
2221 		ehdr->e_shentsize = sizeof (Shdr);
2222 	}
2223 
2224 	ehdr->e_ident[EI_VERSION] = EV_CURRENT;
2225 	ehdr->e_version = EV_CURRENT;
2226 	ehdr->e_ehsize = sizeof (Ehdr);
2227 	ehdr->e_phoff = poffset;
2228 	ehdr->e_phentsize = sizeof (Phdr);
2229 
2230 	if (error = core_write(vp, UIO_SYSSPACE, (offset_t)0, ehdr,
2231 	    sizeof (Ehdr), rlimit, credp)) {
2232 		goto done;
2233 	}
2234 
2235 	phdr = (Phdr *)bigwad;
2236 	bzero(phdr, phdrsz);
2237 
2238 	setup_note_header(&phdr[0], p);
2239 	phdr[0].p_offset = doffset = roundup(doffset, sizeof (Word));
2240 	doffset += phdr[0].p_filesz;
2241 
2242 	mutex_enter(&p->p_lock);
2243 
2244 	brkbase = p->p_brkbase;
2245 	brksize = p->p_brksize;
2246 
2247 	stkbase = p->p_usrstack - p->p_stksize;
2248 	stksize = p->p_stksize;
2249 
2250 	mutex_exit(&p->p_lock);
2251 
2252 	AS_LOCK_ENTER(as, RW_WRITER);
2253 
2254 	i = NOTES_SECTIONS;
2255 
2256 	for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
2257 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
2258 		caddr_t saddr, naddr;
2259 		void *tmp = NULL;
2260 		extern struct seg_ops segspt_shmops;
2261 
2262 		if ((seg->s_flags & S_HOLE) != 0) {
2263 			continue;
2264 		}
2265 
2266 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
2267 			uint_t prot;
2268 			size_t size;
2269 			int type;
2270 			vnode_t *mvp;
2271 
2272 			prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
2273 			prot &= PROT_READ | PROT_WRITE | PROT_EXEC;
2274 			if ((size = (size_t)(naddr - saddr)) == 0) {
2275 				ASSERT(tmp == NULL);
2276 				continue;
2277 			} else if (i == nphdrs) {
2278 				pr_getprot_done(&tmp);
2279 				overflowed = B_TRUE;
2280 				break;
2281 			}
2282 			phdr[i].p_type = PT_LOAD;
2283 			phdr[i].p_vaddr = (Addr)(uintptr_t)saddr;
2284 			phdr[i].p_memsz = size;
2285 			if (prot & PROT_READ)
2286 				phdr[i].p_flags |= PF_R;
2287 			if (prot & PROT_WRITE)
2288 				phdr[i].p_flags |= PF_W;
2289 			if (prot & PROT_EXEC)
2290 				phdr[i].p_flags |= PF_X;
2291 
2292 			/*
2293 			 * Figure out which mappings to include in the core.
2294 			 */
2295 			type = SEGOP_GETTYPE(seg, saddr);
2296 
2297 			if (saddr == stkbase && size == stksize) {
2298 				if (!(content & CC_CONTENT_STACK))
2299 					goto exclude;
2300 
2301 			} else if (saddr == brkbase && size == brksize) {
2302 				if (!(content & CC_CONTENT_HEAP))
2303 					goto exclude;
2304 
2305 			} else if (seg->s_ops == &segspt_shmops) {
2306 				if (type & MAP_NORESERVE) {
2307 					if (!(content & CC_CONTENT_DISM))
2308 						goto exclude;
2309 				} else {
2310 					if (!(content & CC_CONTENT_ISM))
2311 						goto exclude;
2312 				}
2313 
2314 			} else if (seg->s_ops != &segvn_ops) {
2315 				goto exclude;
2316 
2317 			} else if (type & MAP_SHARED) {
2318 				if (shmgetid(p, saddr) != SHMID_NONE) {
2319 					if (!(content & CC_CONTENT_SHM))
2320 						goto exclude;
2321 
2322 				} else if (SEGOP_GETVP(seg, seg->s_base,
2323 				    &mvp) != 0 || mvp == NULL ||
2324 				    mvp->v_type != VREG) {
2325 					if (!(content & CC_CONTENT_SHANON))
2326 						goto exclude;
2327 
2328 				} else {
2329 					if (!(content & CC_CONTENT_SHFILE))
2330 						goto exclude;
2331 				}
2332 
2333 			} else if (SEGOP_GETVP(seg, seg->s_base, &mvp) != 0 ||
2334 			    mvp == NULL || mvp->v_type != VREG) {
2335 				if (!(content & CC_CONTENT_ANON))
2336 					goto exclude;
2337 
2338 			} else if (prot == (PROT_READ | PROT_EXEC)) {
2339 				if (!(content & CC_CONTENT_TEXT))
2340 					goto exclude;
2341 
2342 			} else if (prot == PROT_READ) {
2343 				if (!(content & CC_CONTENT_RODATA))
2344 					goto exclude;
2345 
2346 			} else {
2347 				if (!(content & CC_CONTENT_DATA))
2348 					goto exclude;
2349 			}
2350 
2351 			doffset = roundup(doffset, sizeof (Word));
2352 			phdr[i].p_offset = doffset;
2353 			phdr[i].p_filesz = size;
2354 			doffset += size;
2355 exclude:
2356 			i++;
2357 		}
2358 		VERIFY(tmp == NULL);
2359 		if (overflowed)
2360 			break;
2361 	}
2362 	AS_LOCK_EXIT(as);
2363 
2364 	if (overflowed || i != nphdrs) {
2365 		if (!retried) {
2366 			retried = B_TRUE;
2367 			overflowed = B_FALSE;
2368 			kmem_free(bigwad, bigsize);
2369 			goto top;
2370 		}
2371 		cmn_err(CE_WARN, "elfcore: core dump failed for "
2372 		    "process %d; address space is changing", p->p_pid);
2373 		error = EIO;
2374 		goto done;
2375 	}
2376 
2377 	if ((error = core_write(vp, UIO_SYSSPACE, poffset,
2378 	    phdr, phdrsz, rlimit, credp)) != 0) {
2379 		goto done;
2380 	}
2381 
2382 	if ((error = write_elfnotes(p, sig, vp, phdr[0].p_offset, rlimit,
2383 	    credp, content)) != 0) {
2384 		goto done;
2385 	}
2386 
2387 	for (i = NOTES_SECTIONS; i < nphdrs; i++) {
2388 		prkillinfo_t killinfo;
2389 		sigqueue_t *sq;
2390 		int sig, j;
2391 
2392 		if (phdr[i].p_filesz == 0)
2393 			continue;
2394 
2395 		/*
2396 		 * If we hit a region that was mapped PROT_NONE then we cannot
2397 		 * continue dumping this normally as the kernel would be unable
2398 		 * to read from the page and that would result in us failing to
2399 		 * dump the page. As such, any region mapped PROT_NONE, we dump
2400 		 * as a zero-filled page such that this is still represented in
2401 		 * the map.
2402 		 *
2403 		 * If dumping out this segment fails, rather than failing
2404 		 * the core dump entirely, we reset the size of the mapping
2405 		 * to zero to indicate that the data is absent from the core
2406 		 * file and or in the PF_SUNW_FAILURE flag to differentiate
2407 		 * this from mappings that were excluded due to the core file
2408 		 * content settings.
2409 		 */
2410 		if ((phdr[i].p_flags & (PF_R | PF_W | PF_X)) == 0) {
2411 			size_t towrite = phdr[i].p_filesz;
2412 			size_t curoff = 0;
2413 
2414 			if (zeropg == NULL) {
2415 				zeropg = kmem_zalloc(elf_zeropg_sz, KM_SLEEP);
2416 			}
2417 
2418 			error = 0;
2419 			while (towrite != 0) {
2420 				size_t len = MIN(towrite, elf_zeropg_sz);
2421 
2422 				error = core_write(vp, UIO_SYSSPACE,
2423 				    phdr[i].p_offset + curoff, zeropg, len,
2424 				    rlimit, credp);
2425 				if (error != 0)
2426 					break;
2427 
2428 				towrite -= len;
2429 				curoff += len;
2430 			}
2431 		} else {
2432 			error = core_seg(p, vp, phdr[i].p_offset,
2433 			    (caddr_t)(uintptr_t)phdr[i].p_vaddr,
2434 			    phdr[i].p_filesz, rlimit, credp);
2435 		}
2436 		if (error == 0)
2437 			continue;
2438 
2439 		if ((sig = lwp->lwp_cursig) == 0) {
2440 			/*
2441 			 * We failed due to something other than a signal.
2442 			 * Since the space reserved for the segment is now
2443 			 * unused, we stash the errno in the first four
2444 			 * bytes. This undocumented interface will let us
2445 			 * understand the nature of the failure.
2446 			 */
2447 			(void) core_write(vp, UIO_SYSSPACE, phdr[i].p_offset,
2448 			    &error, sizeof (error), rlimit, credp);
2449 
2450 			phdr[i].p_filesz = 0;
2451 			phdr[i].p_flags |= PF_SUNW_FAILURE;
2452 			if ((error = core_write(vp, UIO_SYSSPACE,
2453 			    poffset + sizeof (Phdr) * i, &phdr[i],
2454 			    sizeof (Phdr), rlimit, credp)) != 0)
2455 				goto done;
2456 
2457 			continue;
2458 		}
2459 
2460 		/*
2461 		 * We took a signal.  We want to abort the dump entirely, but
2462 		 * we also want to indicate what failed and why.  We therefore
2463 		 * use the space reserved for the first failing segment to
2464 		 * write our error (which, for purposes of compatability with
2465 		 * older core dump readers, we set to EINTR) followed by any
2466 		 * siginfo associated with the signal.
2467 		 */
2468 		bzero(&killinfo, sizeof (killinfo));
2469 		killinfo.prk_error = EINTR;
2470 
2471 		sq = sig == SIGKILL ? curproc->p_killsqp : lwp->lwp_curinfo;
2472 
2473 		if (sq != NULL) {
2474 			bcopy(&sq->sq_info, &killinfo.prk_info,
2475 			    sizeof (sq->sq_info));
2476 		} else {
2477 			killinfo.prk_info.si_signo = lwp->lwp_cursig;
2478 			killinfo.prk_info.si_code = SI_NOINFO;
2479 		}
2480 
2481 #if (defined(_SYSCALL32_IMPL) || defined(_LP64))
2482 		/*
2483 		 * If this is a 32-bit process, we need to translate from the
2484 		 * native siginfo to the 32-bit variant.  (Core readers must
2485 		 * always have the same data model as their target or must
2486 		 * be aware of -- and compensate for -- data model differences.)
2487 		 */
2488 		if (curproc->p_model == DATAMODEL_ILP32) {
2489 			siginfo32_t si32;
2490 
2491 			siginfo_kto32((k_siginfo_t *)&killinfo.prk_info, &si32);
2492 			bcopy(&si32, &killinfo.prk_info, sizeof (si32));
2493 		}
2494 #endif
2495 
2496 		(void) core_write(vp, UIO_SYSSPACE, phdr[i].p_offset,
2497 		    &killinfo, sizeof (killinfo), rlimit, credp);
2498 
2499 		/*
2500 		 * For the segment on which we took the signal, indicate that
2501 		 * its data now refers to a siginfo.
2502 		 */
2503 		phdr[i].p_filesz = 0;
2504 		phdr[i].p_flags |= PF_SUNW_FAILURE | PF_SUNW_KILLED |
2505 		    PF_SUNW_SIGINFO;
2506 
2507 		/*
2508 		 * And for every other segment, indicate that its absence
2509 		 * is due to a signal.
2510 		 */
2511 		for (j = i + 1; j < nphdrs; j++) {
2512 			phdr[j].p_filesz = 0;
2513 			phdr[j].p_flags |= PF_SUNW_FAILURE | PF_SUNW_KILLED;
2514 		}
2515 
2516 		/*
2517 		 * Finally, write out our modified program headers.
2518 		 */
2519 		if ((error = core_write(vp, UIO_SYSSPACE,
2520 		    poffset + sizeof (Phdr) * i, &phdr[i],
2521 		    sizeof (Phdr) * (nphdrs - i), rlimit, credp)) != 0) {
2522 			goto done;
2523 		}
2524 
2525 		break;
2526 	}
2527 
2528 	if (nshdrs > 0) {
2529 		Shdr *shdr = (Shdr *)bigwad;
2530 
2531 		bzero(shdr, shdrsz);
2532 		if (nshdrs > 1) {
2533 			ctx.ecc_doffset = doffset;
2534 			AS_LOCK_ENTER(as, RW_WRITER);
2535 			error = elf_process_scns(&ctx, shdr, nshdrs, NULL);
2536 			AS_LOCK_EXIT(as);
2537 			if (error != 0)
2538 				goto done;
2539 		}
2540 		/* Copy any extended format data destined for the first shdr */
2541 		bcopy(&shdr0, shdr, sizeof (shdr0));
2542 
2543 		error = core_write(vp, UIO_SYSSPACE, soffset, shdr, shdrsz,
2544 		    rlimit, credp);
2545 	}
2546 
2547 done:
2548 	if (zeropg != NULL)
2549 		kmem_free(zeropg, elf_zeropg_sz);
2550 	if (ctx.ecc_bufsz != 0)
2551 		kmem_free(ctx.ecc_buf, ctx.ecc_bufsz);
2552 	kmem_free(bigwad, bigsize);
2553 	return (error);
2554 }
2555 
2556 #ifndef	_ELF32_COMPAT
2557 
2558 static struct execsw esw = {
2559 #ifdef	_LP64
2560 	elf64magicstr,
2561 #else	/* _LP64 */
2562 	elf32magicstr,
2563 #endif	/* _LP64 */
2564 	0,
2565 	5,
2566 	elfexec,
2567 	elfcore
2568 };
2569 
2570 static struct modlexec modlexec = {
2571 	&mod_execops, "exec module for elf", &esw
2572 };
2573 
2574 #ifdef	_LP64
2575 extern int elf32exec(vnode_t *vp, execa_t *uap, uarg_t *args,
2576 			intpdata_t *idatap, int level, size_t *execsz,
2577 			int setid, caddr_t exec_file, cred_t *cred,
2578 			int brand_action);
2579 extern int elf32core(vnode_t *vp, proc_t *p, cred_t *credp,
2580 			rlim64_t rlimit, int sig, core_content_t content);
2581 
2582 static struct execsw esw32 = {
2583 	elf32magicstr,
2584 	0,
2585 	5,
2586 	elf32exec,
2587 	elf32core
2588 };
2589 
2590 static struct modlexec modlexec32 = {
2591 	&mod_execops, "32-bit exec module for elf", &esw32
2592 };
2593 #endif	/* _LP64 */
2594 
2595 static struct modlinkage modlinkage = {
2596 	MODREV_1,
2597 	(void *)&modlexec,
2598 #ifdef	_LP64
2599 	(void *)&modlexec32,
2600 #endif	/* _LP64 */
2601 	NULL
2602 };
2603 
2604 int
2605 _init(void)
2606 {
2607 	return (mod_install(&modlinkage));
2608 }
2609 
2610 int
2611 _fini(void)
2612 {
2613 	return (mod_remove(&modlinkage));
2614 }
2615 
2616 int
2617 _info(struct modinfo *modinfop)
2618 {
2619 	return (mod_info(&modlinkage, modinfop));
2620 }
2621 
2622 #endif	/* !_ELF32_COMPAT */
2623