xref: /original-bsd/sys/kern/kern_exec.c (revision 963f8367)
1 /*-
2  * Copyright (c) 1982, 1986, 1991 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.proprietary.c%
6  *
7  *	@(#)kern_exec.c	7.43 (Berkeley) 05/09/91
8  */
9 
10 #include "param.h"
11 #include "systm.h"
12 #include "filedesc.h"
13 #include "kernel.h"
14 #include "proc.h"
15 #include "mount.h"
16 #include "malloc.h"
17 #include "namei.h"
18 #include "vnode.h"
19 #include "seg.h"
20 #include "file.h"
21 #include "acct.h"
22 #include "exec.h"
23 #include "ktrace.h"
24 #include "resourcevar.h"
25 
26 #include "machine/cpu.h"
27 #include "machine/reg.h"
28 
29 #include "mman.h"
30 #include "vm/vm.h"
31 #include "vm/vm_param.h"
32 #include "vm/vm_map.h"
33 #include "vm/vm_kern.h"
34 #include "vm/vm_pager.h"
35 
36 #include "signalvar.h"
37 #include "kinfo_proc.h"
38 
39 #ifdef HPUXCOMPAT
40 #include "user.h"			/* for pcb */
41 #include "hp300/hpux/hpux_exec.h"
42 #endif
43 
44 #ifdef COPY_SIGCODE
45 extern char sigcode[], esigcode[];
46 #define	szsigcode	(esigcode - sigcode)
47 #else
48 #define	szsigcode	0
49 #endif
50 
51 /*
52  * exec system call
53  */
54 /* ARGSUSED */
55 execve(p, uap, retval)
56 	register struct proc *p;
57 	register struct args {
58 		char	*fname;
59 		char	**argp;
60 		char	**envp;
61 	} *uap;
62 	int *retval;
63 {
64 	register struct ucred *cred = p->p_ucred;
65 	register struct nameidata *ndp;
66 	register struct filedesc *fdp = p->p_fd;
67 	int na, ne, ucp, ap, cc;
68 	register char *cp;
69 	register int nc;
70 	unsigned len;
71 	int indir, uid, gid;
72 	char *sharg;
73 	struct vnode *vp;
74 	int resid, error, paged = 0;
75 	vm_offset_t execargs;
76 	struct vattr vattr;
77 	char cfname[MAXCOMLEN + 1];
78 	char cfarg[MAXINTERP];
79 	union {
80 		char	ex_shell[MAXINTERP];	/* #! and interpreter name */
81 		struct	exec ex_exec;
82 #ifdef HPUXCOMPAT
83 		struct	hpux_exec ex_hexec;
84 #endif
85 	} exdata;
86 #ifdef HPUXCOMPAT
87 	struct hpux_exec hhead;
88 #endif
89 	struct nameidata nd;
90 
91 	ndp = &nd;
92   start:
93 	ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
94 	ndp->ni_segflg = UIO_USERSPACE;
95 	ndp->ni_dirp = uap->fname;
96 	if (error = namei(ndp, p))
97 		return (error);
98 	vp = ndp->ni_vp;
99 	indir = 0;
100 	uid = cred->cr_uid;
101 	gid = cred->cr_gid;
102 	if (error = VOP_GETATTR(vp, &vattr, cred, p))
103 		goto bad;
104 	if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
105 		error = EACCES;
106 		goto bad;
107 	}
108 	if ((vp->v_mount->mnt_flag & MNT_NOSUID) == 0) {
109 		if (vattr.va_mode & VSUID)
110 			uid = vattr.va_uid;
111 		if (vattr.va_mode & VSGID)
112 			gid = vattr.va_gid;
113 	}
114 
115   again:
116 	if (error = VOP_ACCESS(vp, VEXEC, cred, p))
117 		goto bad;
118 	if ((p->p_flag & STRC) && (error = VOP_ACCESS(vp, VREAD, cred, p)))
119 		goto bad;
120 	if (vp->v_type != VREG ||
121 	    (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) {
122 		error = EACCES;
123 		goto bad;
124 	}
125 
126 	/*
127 	 * Read in first few bytes of file for segment sizes, magic number:
128 	 *	OMAGIC = plain executable
129 	 *	NMAGIC = RO text
130 	 *	ZMAGIC = demand paged RO text
131 	 * Also an ASCII line beginning with #! is
132 	 * the file name of a ``shell'' and arguments may be prepended
133 	 * to the argument list if given here.
134 	 *
135 	 * SHELL NAMES ARE LIMITED IN LENGTH.
136 	 *
137 	 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
138 	 * THE ASCII LINE.
139 	 */
140 	exdata.ex_shell[0] = '\0';	/* for zero length files */
141 	error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata),
142 	    (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), cred, &resid,
143 	    (struct proc *)0);
144 	if (error)
145 		goto bad;
146 #ifndef lint
147 	if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) &&
148 	    exdata.ex_shell[0] != '#') {
149 		error = ENOEXEC;
150 		goto bad;
151 	}
152 #endif
153 #if defined(hp300)
154 	switch ((int)exdata.ex_exec.a_mid) {
155 
156 	/*
157 	 * An ancient hp200 or hp300 binary, shouldn't happen anymore.
158 	 * Mark as invalid.
159 	 */
160 	case MID_ZERO:
161 		exdata.ex_exec.a_magic = 0;
162 		break;
163 
164 	/*
165 	 * HP200 series has a smaller page size so we cannot
166 	 * demand-load or even write protect text, so we just
167 	 * treat as OMAGIC.
168 	 */
169 	case MID_HP200:
170 		exdata.ex_exec.a_magic = OMAGIC;
171 		break;
172 
173 	case MID_HP300:
174 		break;
175 
176 #ifdef HPUXCOMPAT
177 	case MID_HPUX:
178 		/*
179 		 * Save a.out header.  This is eventually saved in the pcb,
180 		 * but we cannot do that yet in case the exec fails before
181 		 * the image is overlayed.
182 		 */
183 		bcopy((caddr_t)&exdata.ex_hexec,
184 		      (caddr_t)&hhead, sizeof hhead);
185 		/*
186 		 * If version number is 0x2bad this is a native BSD
187 		 * binary created via the HPUX SGS.  Should not be
188 		 * treated as an HPUX binary.
189 		 */
190 		if (exdata.ex_hexec.ha_version != BSDVNUM)
191 			paged |= SHPUX;				/* XXX */
192 		/*
193 		 * Shuffle important fields to their BSD locations.
194 		 * Note that the order in which this is done is important.
195 		 */
196 		exdata.ex_exec.a_text = exdata.ex_hexec.ha_text;
197 		exdata.ex_exec.a_data = exdata.ex_hexec.ha_data;
198 		exdata.ex_exec.a_bss = exdata.ex_hexec.ha_bss;
199 		exdata.ex_exec.a_entry = exdata.ex_hexec.ha_entry;
200 		/*
201 		 * For ZMAGIC files, make sizes consistant with those
202 		 * generated by BSD ld.
203 		 */
204 		if (exdata.ex_exec.a_magic == ZMAGIC) {
205 			exdata.ex_exec.a_text =
206 				ctob(btoc(exdata.ex_exec.a_text));
207 			nc = exdata.ex_exec.a_data + exdata.ex_exec.a_bss;
208 			exdata.ex_exec.a_data =
209 				ctob(btoc(exdata.ex_exec.a_data));
210 			nc -= (int)exdata.ex_exec.a_data;
211 			exdata.ex_exec.a_bss = (nc < 0) ? 0 : nc;
212 		}
213 		break;
214 #endif
215 	}
216 #endif
217 	switch ((int)exdata.ex_exec.a_magic) {
218 
219 	case OMAGIC:
220 		exdata.ex_exec.a_data += exdata.ex_exec.a_text;
221 		exdata.ex_exec.a_text = 0;
222 		break;
223 
224 	case ZMAGIC:
225 		paged++;
226 		/* FALLTHROUGH */
227 	case NMAGIC:
228 		if (exdata.ex_exec.a_text == 0) {
229 			error = ENOEXEC;
230 			goto bad;
231 		}
232 		break;
233 
234 	default:
235 		if (exdata.ex_shell[0] != '#' ||
236 		    exdata.ex_shell[1] != '!' ||
237 		    indir) {
238 			error = ENOEXEC;
239 			goto bad;
240 		}
241 		for (cp = &exdata.ex_shell[2];; ++cp) {
242 			if (cp >= &exdata.ex_shell[MAXINTERP]) {
243 				error = ENOEXEC;
244 				goto bad;
245 			}
246 			if (*cp == '\n') {
247 				*cp = '\0';
248 				break;
249 			}
250 			if (*cp == '\t')
251 				*cp = ' ';
252 		}
253 		cp = &exdata.ex_shell[2];
254 		while (*cp == ' ')
255 			cp++;
256 		ndp->ni_dirp = cp;
257 		while (*cp && *cp != ' ')
258 			cp++;
259 		cfarg[0] = '\0';
260 		if (*cp) {
261 			*cp++ = '\0';
262 			while (*cp == ' ')
263 				cp++;
264 			if (*cp)
265 				bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP);
266 		}
267 		indir = 1;
268 		vput(vp);
269 		ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
270 		ndp->ni_segflg = UIO_SYSSPACE;
271 		if (error = namei(ndp, p))
272 			return (error);
273 		vp = ndp->ni_vp;
274 		if (error = VOP_GETATTR(vp, &vattr, cred, p))
275 			goto bad;
276 		bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
277 		    MAXCOMLEN);
278 		cfname[MAXCOMLEN] = '\0';
279 		uid = cred->cr_uid;	/* shell scripts can't be setuid */
280 		gid = cred->cr_gid;
281 		goto again;
282 	}
283 
284 	/*
285 	 * Collect arguments on "file" in swap space.
286 	 */
287 	na = 0;
288 	ne = 0;
289 	nc = 0;
290 	cc = NCARGS;
291 	execargs = kmem_alloc_wait(exec_map, NCARGS);
292 	cp = (char *) execargs;
293 	/*
294 	 * Copy arguments into file in argdev area.
295 	 */
296 	if (uap->argp) for (;;) {
297 		ap = NULL;
298 		sharg = NULL;
299 		if (indir && na == 0) {
300 			sharg = cfname;
301 			ap = (int)sharg;
302 			uap->argp++;		/* ignore argv[0] */
303 		} else if (indir && (na == 1 && cfarg[0])) {
304 			sharg = cfarg;
305 			ap = (int)sharg;
306 		} else if (indir && (na == 1 || na == 2 && cfarg[0]))
307 			ap = (int)uap->fname;
308 		else if (uap->argp) {
309 			ap = fuword((caddr_t)uap->argp);
310 			uap->argp++;
311 		}
312 		if (ap == NULL && uap->envp) {
313 			uap->argp = NULL;
314 			if ((ap = fuword((caddr_t)uap->envp)) != NULL)
315 				uap->envp++, ne++;
316 		}
317 		if (ap == NULL)
318 			break;
319 		na++;
320 		if (ap == -1) {
321 			error = EFAULT;
322 			goto bad;
323 		}
324 		do {
325 			if (nc >= NCARGS-1) {
326 				error = E2BIG;
327 				break;
328 			}
329 			if (sharg) {
330 				error = copystr(sharg, cp, (unsigned)cc, &len);
331 				sharg += len;
332 			} else {
333 				error = copyinstr((caddr_t)ap, cp, (unsigned)cc,
334 				    &len);
335 				ap += len;
336 			}
337 			cp += len;
338 			nc += len;
339 			cc -= len;
340 		} while (error == ENAMETOOLONG);
341 		if (error)
342 			goto bad;
343 	}
344 	nc = (nc + NBPW-1) & ~(NBPW-1);
345 	error = getxfile(p, vp, &exdata.ex_exec, paged, nc + (na+4)*NBPW,
346 	    uid, gid);
347 	if (error)
348 		goto bad;
349 	vput(vp);
350 	vp = NULL;
351 
352 #ifdef HPUXCOMPAT
353 	/*
354 	 * We are now committed to the exec so we can save the exec
355 	 * header in the pcb where we can dump it if necessary in core()
356 	 */
357 	if (p->p_addr->u_pcb.pcb_flags & PCB_HPUXBIN)
358 		bcopy((caddr_t)&hhead,
359 		      (caddr_t)p->p_addr->u_pcb.pcb_exec, sizeof hhead);
360 #endif
361 
362 	/*
363 	 * Copy back arglist.
364 	 */
365 	ucp = USRSTACK - szsigcode - nc - NBPW;
366 	ap = ucp - na*NBPW - 3*NBPW;
367 	p->p_regs[SP] = ap;
368 	(void) suword((caddr_t)ap, na-ne);
369 	nc = 0;
370 	cp = (char *) execargs;
371 	cc = NCARGS;
372 	for (;;) {
373 		ap += NBPW;
374 		if (na == ne) {
375 			(void) suword((caddr_t)ap, 0);
376 			ap += NBPW;
377 		}
378 		if (--na < 0)
379 			break;
380 		(void) suword((caddr_t)ap, ucp);
381 		do {
382 			error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc,
383 			    &len);
384 			ucp += len;
385 			cp += len;
386 			nc += len;
387 			cc -= len;
388 		} while (error == ENAMETOOLONG);
389 		if (error == EFAULT)
390 			panic("exec: EFAULT");
391 	}
392 	(void) suword((caddr_t)ap, 0);
393 
394 	execsigs(p);
395 
396 	for (nc = fdp->fd_lastfile; nc >= 0; --nc) {
397 		if (fdp->fd_ofileflags[nc] & UF_EXCLOSE) {
398 			(void) closef(fdp->fd_ofiles[nc], p);
399 			fdp->fd_ofiles[nc] = NULL;
400 			fdp->fd_ofileflags[nc] = 0;
401 			if (nc < fdp->fd_freefile)
402 				fdp->fd_freefile = nc;
403 		}
404 		fdp->fd_ofileflags[nc] &= ~UF_MAPPED;
405 	}
406 	/*
407 	 * Adjust fd_lastfile to account for descriptors closed above.
408 	 * Don't decrement fd_lastfile past 0, as it's unsigned.
409 	 */
410 	while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
411 		fdp->fd_lastfile--;
412 	setregs(p, exdata.ex_exec.a_entry, retval);
413 #ifdef COPY_SIGCODE
414 	/*
415 	 * Install sigcode at top of user stack.
416 	 */
417 	copyout((caddr_t)sigcode, (caddr_t)(USRSTACK - szsigcode), szsigcode);
418 #endif
419 	/*
420 	 * Remember file name for accounting.
421 	 */
422 	p->p_acflag &= ~AFORK;
423 	if (indir)
424 		bcopy((caddr_t)cfname, (caddr_t)p->p_comm, MAXCOMLEN);
425 	else {
426 		if (ndp->ni_dent.d_namlen > MAXCOMLEN)
427 			ndp->ni_dent.d_namlen = MAXCOMLEN;
428 		bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)p->p_comm,
429 		    (unsigned)(ndp->ni_dent.d_namlen + 1));
430 	}
431 	cpu_exec(p);
432 bad:
433 	if (execargs)
434 		kmem_free_wakeup(exec_map, execargs, NCARGS);
435 	if (vp)
436 		vput(vp);
437 	return (error);
438 }
439 
440 /*
441  * Read in and set up memory for executed file.
442  */
443 getxfile(p, vp, ep, paged, nargc, uid, gid)
444 	register struct proc *p;
445 	register struct vnode *vp;
446 	register struct exec *ep;
447 	int paged, nargc, uid, gid;
448 {
449 	segsz_t ts, ds, ss;
450 	register struct ucred *cred = p->p_ucred;
451 	off_t toff;
452 	int error = 0;
453 	vm_offset_t addr;
454 	vm_size_t size;
455 	struct vmspace *vm = p->p_vmspace;
456 
457 #ifdef HPUXCOMPAT
458 	int hpux = (paged & SHPUX);
459 	paged &= ~SHPUX;
460 	if (ep->a_mid == MID_HPUX) {
461 		if (paged)
462 			toff = CLBYTES;
463 		else
464 			toff = sizeof (struct hpux_exec);
465 	} else
466 #endif
467 	if (paged)
468 		toff = CLBYTES;
469 	else
470 		toff = sizeof (struct exec);
471 	if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 &&
472 	    vp->v_usecount != 1) {
473 		register struct file *fp;
474 
475 		for (fp = file; fp < fileNFILE; fp++) {
476 			if (fp->f_type == DTYPE_VNODE &&
477 			    fp->f_count > 0 &&
478 			    (struct vnode *)fp->f_data == vp &&
479 			    (fp->f_flag & FWRITE)) {
480 				return (ETXTBSY);
481 			}
482 		}
483 	}
484 
485 	/*
486 	 * Compute text and data sizes and make sure not too large.
487 	 * NB - Check data and bss separately as they may overflow
488 	 * when summed together.
489 	 */
490 	ts = clrnd(btoc(ep->a_text));
491 	ds = clrnd(btoc(ep->a_data + ep->a_bss));
492 	ss = clrnd(SSIZE + btoc(nargc + szsigcode));
493 
494 	/*
495 	 * If we're sharing the address space, allocate a new space
496 	 * and release our reference to the old one.  Otherwise,
497 	 * empty out the existing vmspace.
498 	 */
499 	if (vm->vm_refcnt > 1) {
500 		p->p_vmspace = vmspace_alloc(VM_MIN_ADDRESS,
501 		    VM_MAXUSER_ADDRESS, 1);
502 		vmspace_free(vm);
503 		vm = p->p_vmspace;
504 	} else {
505 #ifdef SYSVSHM
506 		if (vm->vm_shm)
507 			shmexit(p);
508 #endif
509 		(void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS,
510 		    VM_MAXUSER_ADDRESS);
511 	}
512 	/*
513 	 * If parent is waiting for us to exec or exit,
514 	 * SPPWAIT will be set; clear it and wakeup parent.
515 	 */
516 	if (p->p_flag & SPPWAIT) {
517 		p->p_flag &= ~SPPWAIT;
518 		wakeup((caddr_t) p->p_pptr);
519 	}
520 #ifdef HPUXCOMPAT
521 	p->p_addr->u_pcb.pcb_flags &= ~(PCB_HPUXMMAP|PCB_HPUXBIN);
522 	/* remember that we were loaded from an HPUX format file */
523 	if (ep->a_mid == MID_HPUX)
524 		p->p_addr->u_pcb.pcb_flags |= PCB_HPUXBIN;
525 	if (hpux)
526 		p->p_flag |= SHPUX;
527 	else
528 		p->p_flag &= ~SHPUX;
529 #endif
530 	p->p_flag |= SEXEC;
531 	addr = VM_MIN_ADDRESS;
532 	if (vm_allocate(&vm->vm_map, &addr, round_page(ctob(ts + ds)), FALSE)) {
533 		uprintf("Cannot allocate text+data space\n");
534 		error = ENOMEM;			/* XXX */
535 		goto badmap;
536 	}
537 	size = round_page(MAXSSIZ);		/* XXX */
538 	addr = trunc_page(USRSTACK - size);
539 	if (vm_allocate(&vm->vm_map, &addr, size, FALSE)) {
540 		uprintf("Cannot allocate stack space\n");
541 		error = ENOMEM;			/* XXX */
542 		goto badmap;
543 	}
544 	size -= round_page(p->p_rlimit[RLIMIT_STACK].rlim_cur);
545 	if (vm_map_protect(&vm->vm_map, addr, addr+size, VM_PROT_NONE, FALSE)) {
546 		uprintf("Cannot protect stack space\n");
547 		error = ENOMEM;
548 		goto badmap;
549 	}
550 	vm->vm_maxsaddr = (caddr_t)addr;
551 	vm->vm_taddr = (caddr_t)VM_MIN_ADDRESS;
552 	vm->vm_daddr = (caddr_t)(VM_MIN_ADDRESS + ctob(ts));
553 
554 	if (paged == 0) {
555 		/*
556 		 * Read in data segment.
557 		 */
558 		(void) vn_rdwr(UIO_READ, vp, vm->vm_daddr, (int) ep->a_data,
559 			(off_t)(toff + ep->a_text), UIO_USERSPACE,
560 			(IO_UNIT|IO_NODELOCKED), cred, (int *)0, p);
561 		/*
562 		 * Read in text segment if necessary (0410),
563 		 * and read-protect it.
564 		 */
565 		if (ep->a_text > 0) {
566 			error = vn_rdwr(UIO_READ, vp, vm->vm_taddr,
567 				(int)ep->a_text, toff, UIO_USERSPACE,
568 				(IO_UNIT|IO_NODELOCKED), cred, (int *)0, p);
569 			(void) vm_map_protect(&vm->vm_map, VM_MIN_ADDRESS,
570 				VM_MIN_ADDRESS + trunc_page(ep->a_text),
571 				VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
572 		}
573 	} else {
574 		/*
575 		 * Allocate a region backed by the exec'ed vnode.
576 		 */
577 		addr = VM_MIN_ADDRESS;
578 		size = round_page(ep->a_text + ep->a_data);
579 		error = vm_mmap(&vm->vm_map, &addr, size, VM_PROT_ALL,
580 			MAP_FILE|MAP_COPY|MAP_FIXED,
581 			(caddr_t)vp, (vm_offset_t)toff);
582 		(void) vm_map_protect(&vm->vm_map, addr,
583 			addr + trunc_page(ep->a_text),
584 			VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
585 		vp->v_flag |= VTEXT;
586 	}
587 badmap:
588 	if (error) {
589 		printf("pid %d: VM allocation failure\n", p->p_pid);
590 		uprintf("sorry, pid %d was killed in exec: VM allocation\n",
591 			p->p_pid);
592 		psignal(p, SIGKILL);
593 		p->p_flag |= SKEEP;
594 		return(error);
595 	}
596 
597 	/*
598 	 * set SUID/SGID protections, if no tracing
599 	 */
600 	if ((p->p_flag&STRC)==0) {
601 		if (uid != cred->cr_uid || gid != cred->cr_gid) {
602 			p->p_ucred = cred = crcopy(cred);
603 			/*
604 			 * If process is being ktraced, turn off - unless
605 			 * root set it.
606 			 */
607 			if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) {
608 				vrele(p->p_tracep);
609 				p->p_tracep = NULL;
610 				p->p_traceflag = 0;
611 			}
612 		}
613 		cred->cr_uid = uid;
614 		cred->cr_gid = gid;
615 	} else
616 		psignal(p, SIGTRAP);
617 	p->p_cred->p_svuid = cred->cr_uid;
618 	p->p_cred->p_svgid = cred->cr_gid;
619 	vm->vm_tsize = ts;
620 	vm->vm_dsize = ds;
621 	vm->vm_ssize = ss;
622 	p->p_stats->p_prof.pr_scale = 0;
623 #if defined(tahoe)
624 	/* move this when tahoe cpu_exec is created */
625 	p->p_addr->u_pcb.pcb_savacc.faddr = (float *)NULL;
626 #endif
627 	return (0);
628 }
629