xref: /original-bsd/sys/kern/kern_exec.c (revision e718337e)
1 /*
2  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)kern_exec.c	7.32 (Berkeley) 10/19/90
8  */
9 
10 #include "param.h"
11 #include "systm.h"
12 #include "map.h"
13 #include "user.h"
14 #include "kernel.h"
15 #include "proc.h"
16 #include "mount.h"
17 #include "ucred.h"
18 #include "malloc.h"
19 #include "buf.h"
20 #include "vnode.h"
21 #include "seg.h"
22 #include "vm.h"
23 #include "text.h"
24 #include "file.h"
25 #include "uio.h"
26 #include "acct.h"
27 #include "exec.h"
28 #include "ktrace.h"
29 
30 #include "machine/reg.h"
31 #include "machine/pte.h"
32 #include "machine/psl.h"
33 #include "machine/mtpr.h"
34 
35 #ifdef HPUXCOMPAT
36 #include "../hpux/hpux_exec.h"
37 #endif
38 
39 /*
40  * exec system call, with and without environments.
41  */
42 execv(p, uap, retval)
43 	struct proc *p;
44 	struct args {
45 		char	*fname;
46 		char	**argp;
47 		char	**envp;
48 	} *uap;
49 	int *retval;
50 {
51 
52 	uap->envp = NULL;
53 	return (execve(p, uap, retval));
54 }
55 
56 /* ARGSUSED */
57 execve(p, uap, retval)
58 	register struct proc *p;
59 	register struct args {
60 		char	*fname;
61 		char	**argp;
62 		char	**envp;
63 	} *uap;
64 	int *retval;
65 {
66 	register nc;
67 	register char *cp;
68 	register struct buf *bp;
69 	struct buf *tbp;
70 	int na, ne, ucp, ap, cc;
71 	unsigned len;
72 	int indir, uid, gid;
73 	char *sharg;
74 	struct vnode *vp;
75 	swblk_t bno;
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 	register struct ucred *cred = u.u_cred;
90 	register struct nameidata *ndp = &u.u_nd;
91 	int resid, error, flags = 0;
92 
93   start:
94 	ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
95 	ndp->ni_segflg = UIO_USERSPACE;
96 	ndp->ni_dirp = uap->fname;
97 	if (error = namei(ndp))
98 		return (error);
99 	vp = ndp->ni_vp;
100 	bno = 0;
101 	bp = 0;
102 	indir = 0;
103 	uid = cred->cr_uid;
104 	gid = cred->cr_gid;
105 	if (error = VOP_GETATTR(vp, &vattr, cred))
106 		goto bad;
107 	if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
108 		error = EACCES;
109 		goto bad;
110 	}
111 	if ((vp->v_mount->mnt_flag & MNT_NOSUID) == 0) {
112 		if (vattr.va_mode & VSUID)
113 			uid = vattr.va_uid;
114 		if (vattr.va_mode & VSGID)
115 			gid = vattr.va_gid;
116 	}
117 
118   again:
119 	if (error = VOP_ACCESS(vp, VEXEC, cred))
120 		goto bad;
121 	if ((p->p_flag & STRC) && (error = VOP_ACCESS(vp, VREAD, cred)))
122 		goto bad;
123 	if (vp->v_type != VREG ||
124 	    (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) {
125 		error = EACCES;
126 		goto bad;
127 	}
128 
129 	/*
130 	 * Read in first few bytes of file for segment sizes, magic number:
131 	 *	OMAGIC = plain executable
132 	 *	NMAGIC = RO text
133 	 *	ZMAGIC = demand paged RO text
134 	 * Also an ASCII line beginning with #! is
135 	 * the file name of a ``shell'' and arguments may be prepended
136 	 * to the argument list if given here.
137 	 *
138 	 * SHELL NAMES ARE LIMITED IN LENGTH.
139 	 *
140 	 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
141 	 * THE ASCII LINE.
142 	 */
143 	exdata.ex_shell[0] = '\0';	/* for zero length files */
144 	error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata),
145 	    (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), cred, &resid);
146 	if (error)
147 		goto bad;
148 #ifndef lint
149 	if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) &&
150 	    exdata.ex_shell[0] != '#') {
151 		error = ENOEXEC;
152 		goto bad;
153 	}
154 #endif
155 #if defined(hp300)
156 	switch ((int)exdata.ex_exec.a_mid) {
157 
158 	/*
159 	 * An ancient hp200 or hp300 binary, shouldn't happen anymore.
160 	 * Mark as invalid.
161 	 */
162 	case MID_ZERO:
163 		exdata.ex_exec.a_magic = 0;
164 		break;
165 
166 	/*
167 	 * HP200 series has a smaller page size so we cannot
168 	 * demand-load or even write protect text, so we just
169 	 * treat as OMAGIC.
170 	 */
171 	case MID_HP200:
172 		exdata.ex_exec.a_magic = OMAGIC;
173 		break;
174 
175 	case MID_HP300:
176 		break;
177 
178 #ifdef HPUXCOMPAT
179 	case MID_HPUX:
180 		/*
181 		 * Save a.out header.  This is eventually saved in the pcb,
182 		 * but we cannot do that yet in case the exec fails before
183 		 * the image is overlayed.
184 		 */
185 		bcopy((caddr_t)&exdata.ex_hexec,
186 		      (caddr_t)&hhead, sizeof hhead);
187 		/*
188 		 * If version number is 0x2bad this is a native BSD
189 		 * binary created via the HPUX SGS.  Should not be
190 		 * treated as an HPUX binary.
191 		 */
192 		if (exdata.ex_hexec.ha_version != BSDVNUM)
193 			flags |= SHPUX;
194 		/*
195 		 * Shuffle important fields to their BSD locations.
196 		 * Note that the order in which this is done is important.
197 		 */
198 		exdata.ex_exec.a_text = exdata.ex_hexec.ha_text;
199 		exdata.ex_exec.a_data = exdata.ex_hexec.ha_data;
200 		exdata.ex_exec.a_bss = exdata.ex_hexec.ha_bss;
201 		exdata.ex_exec.a_entry = exdata.ex_hexec.ha_entry;
202 		/*
203 		 * For ZMAGIC files, make sizes consistant with those
204 		 * generated by BSD ld.
205 		 */
206 		if (exdata.ex_exec.a_magic == ZMAGIC) {
207 			exdata.ex_exec.a_text =
208 				ctob(btoc(exdata.ex_exec.a_text));
209 			nc = exdata.ex_exec.a_data + exdata.ex_exec.a_bss;
210 			exdata.ex_exec.a_data =
211 				ctob(btoc(exdata.ex_exec.a_data));
212 			nc -= (int)exdata.ex_exec.a_data;
213 			exdata.ex_exec.a_bss = (nc < 0) ? 0 : nc;
214 		}
215 		break;
216 #endif
217 	}
218 #endif
219 	switch ((int)exdata.ex_exec.a_magic) {
220 
221 	case OMAGIC:
222 		exdata.ex_exec.a_data += exdata.ex_exec.a_text;
223 		exdata.ex_exec.a_text = 0;
224 		break;
225 
226 	case ZMAGIC:
227 		flags |= SPAGV;
228 	case NMAGIC:
229 		if (exdata.ex_exec.a_text == 0) {
230 			error = ENOEXEC;
231 			goto bad;
232 		}
233 		break;
234 
235 	default:
236 		if (exdata.ex_shell[0] != '#' ||
237 		    exdata.ex_shell[1] != '!' ||
238 		    indir) {
239 			error = ENOEXEC;
240 			goto bad;
241 		}
242 		for (cp = &exdata.ex_shell[2];; ++cp) {
243 			if (cp >= &exdata.ex_shell[MAXINTERP]) {
244 				error = ENOEXEC;
245 				goto bad;
246 			}
247 			if (*cp == '\n') {
248 				*cp = '\0';
249 				break;
250 			}
251 			if (*cp == '\t')
252 				*cp = ' ';
253 		}
254 		cp = &exdata.ex_shell[2];
255 		while (*cp == ' ')
256 			cp++;
257 		ndp->ni_dirp = cp;
258 		while (*cp && *cp != ' ')
259 			cp++;
260 		cfarg[0] = '\0';
261 		if (*cp) {
262 			*cp++ = '\0';
263 			while (*cp == ' ')
264 				cp++;
265 			if (*cp)
266 				bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP);
267 		}
268 		indir = 1;
269 		vput(vp);
270 		ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
271 		ndp->ni_segflg = UIO_SYSSPACE;
272 		if (error = namei(ndp))
273 			return (error);
274 		vp = ndp->ni_vp;
275 		if (error = VOP_GETATTR(vp, &vattr, cred))
276 			goto bad;
277 		bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
278 		    MAXCOMLEN);
279 		cfname[MAXCOMLEN] = '\0';
280 		uid = cred->cr_uid;	/* shell scripts can't be setuid */
281 		gid = cred->cr_gid;
282 		goto again;
283 	}
284 	/*
285 	 * If the vnode has been modified since we last used it,
286 	 * then throw away all its pages and its text table entry.
287 	 */
288 	if (vp->v_text && vp->v_text->x_mtime != vattr.va_mtime.tv_sec) {
289 		/*
290 		 * Try once to release, if it is still busy
291 		 * take more drastic action.
292 		 */
293 		xrele(vp);
294 		if (vp->v_flag & VTEXT) {
295 			vput(vp);
296 			vgone(vp);
297 			goto start;
298 		}
299 	}
300 
301 	/*
302 	 * Collect arguments on "file" in swap space.
303 	 */
304 	na = 0;
305 	ne = 0;
306 	nc = 0;
307 	cc = 0;
308 	bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS))));
309 	if (bno == 0) {
310 		swkill(p, "exec: no swap space");
311 		goto bad;
312 	}
313 	if (bno % CLSIZE)
314 		panic("execa rmalloc");
315 #ifdef GENERIC
316 	if (rootdev == dumpdev)
317 		bno += 4096;
318 #endif
319 	/*
320 	 * Copy arguments into file in argdev area.
321 	 */
322 	if (uap->argp) for (;;) {
323 		ap = NULL;
324 		sharg = NULL;
325 		if (indir && na == 0) {
326 			sharg = cfname;
327 			ap = (int)sharg;
328 			uap->argp++;		/* ignore argv[0] */
329 		} else if (indir && (na == 1 && cfarg[0])) {
330 			sharg = cfarg;
331 			ap = (int)sharg;
332 		} else if (indir && (na == 1 || na == 2 && cfarg[0]))
333 			ap = (int)uap->fname;
334 		else if (uap->argp) {
335 			ap = fuword((caddr_t)uap->argp);
336 			uap->argp++;
337 		}
338 		if (ap == NULL && uap->envp) {
339 			uap->argp = NULL;
340 			if ((ap = fuword((caddr_t)uap->envp)) != NULL)
341 				uap->envp++, ne++;
342 		}
343 		if (ap == NULL)
344 			break;
345 		na++;
346 		if (ap == -1) {
347 			error = EFAULT;
348 			if (bp) {
349 				brelse(bp);
350 				bp = 0;
351 			}
352 			goto badarg;
353 		}
354 		do {
355 			if (cc <= 0) {
356 				/*
357 				 * We depend on NCARGS being a multiple of
358 				 * CLBYTES.  This way we need only check
359 				 * overflow before each buffer allocation.
360 				 */
361 				if (nc >= NCARGS-1) {
362 					error = E2BIG;
363 					break;
364 				}
365 				if (bp)
366 					bdwrite(bp);
367 				cc = CLBYTES;
368 				bp = getblk(argdev_vp, bno + ctod(nc/NBPG), cc);
369 				cp = bp->b_un.b_addr;
370 			}
371 			if (sharg) {
372 				error = copystr(sharg, cp, (unsigned)cc, &len);
373 				sharg += len;
374 			} else {
375 				error = copyinstr((caddr_t)ap, cp, (unsigned)cc,
376 				    &len);
377 				ap += len;
378 			}
379 			cp += len;
380 			nc += len;
381 			cc -= len;
382 		} while (error == ENAMETOOLONG);
383 		if (error) {
384 			if (bp)
385 				brelse(bp);
386 			bp = 0;
387 			goto badarg;
388 		}
389 	}
390 	if (bp)
391 		bdwrite(bp);
392 	bp = 0;
393 	nc = (nc + NBPW-1) & ~(NBPW-1);
394 	error = getxfile(p, vp, &exdata.ex_exec, flags, nc + (na+4)*NBPW,
395 	    uid, gid);
396 	if (error) {
397 badarg:
398 		for (cc = 0; cc < nc; cc += CLBYTES) {
399 			(void) baddr(argdev_vp, bno + ctod(cc/NBPG),
400 				CLBYTES, NOCRED, &tbp);
401 			bp = tbp;
402 			if (bp) {
403 				bp->b_flags |= B_INVAL;		/* throw away */
404 				brelse(bp);
405 				bp = 0;
406 			}
407 		}
408 		goto bad;
409 	}
410 	if (vp->v_text)
411 		vp->v_text->x_mtime = vattr.va_mtime.tv_sec;
412 	vput(vp);
413 	vp = NULL;
414 
415 #ifdef HPUXCOMPAT
416 	/*
417 	 * We are now committed to the exec so we can save the exec
418 	 * header in the pcb where we can dump it if necessary in core()
419 	 */
420 	if (u.u_pcb.pcb_flags & PCB_HPUXBIN)
421 		bcopy((caddr_t)&hhead,
422 		      (caddr_t)u.u_pcb.pcb_exec, sizeof hhead);
423 #endif
424 
425 	/*
426 	 * Copy back arglist.
427 	 */
428 	ucp = USRSTACK - nc - NBPW;
429 	ap = ucp - na*NBPW - 3*NBPW;
430 	u.u_ar0[SP] = ap;
431 	(void) suword((caddr_t)ap, na-ne);
432 	nc = 0;
433 	cc = 0;
434 	for (;;) {
435 		ap += NBPW;
436 		if (na == ne) {
437 			(void) suword((caddr_t)ap, 0);
438 			ap += NBPW;
439 		}
440 		if (--na < 0)
441 			break;
442 		(void) suword((caddr_t)ap, ucp);
443 		do {
444 			if (cc <= 0) {
445 				if (bp)
446 					brelse(bp);
447 				cc = CLBYTES;
448 				error = bread(argdev_vp,
449 				    (daddr_t)(bno + ctod(nc / NBPG)), cc,
450 				    NOCRED, &tbp);
451 				bp = tbp;
452 				bp->b_flags |= B_INVAL;		/* throw away */
453 				cp = bp->b_un.b_addr;
454 			}
455 			error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc,
456 			    &len);
457 			ucp += len;
458 			cp += len;
459 			nc += len;
460 			cc -= len;
461 		} while (error == ENAMETOOLONG);
462 		if (error == EFAULT)
463 			panic("exec: EFAULT");
464 	}
465 	(void) suword((caddr_t)ap, 0);
466 
467 	execsigs(p);
468 
469 	for (nc = u.u_lastfile; nc >= 0; --nc) {
470 		if (u.u_pofile[nc] & UF_EXCLOSE) {
471 			(void) closef(u.u_ofile[nc]);
472 			u.u_ofile[nc] = NULL;
473 			u.u_pofile[nc] = 0;
474 		}
475 		u.u_pofile[nc] &= ~UF_MAPPED;
476 	}
477 	while (u.u_lastfile >= 0 && u.u_ofile[u.u_lastfile] == NULL)
478 		u.u_lastfile--;
479 	setregs(exdata.ex_exec.a_entry, retval);
480 	/*
481 	 * Remember file name for accounting.
482 	 */
483 	u.u_acflag &= ~AFORK;
484 	if (indir)
485 		bcopy((caddr_t)cfname, (caddr_t)p->p_comm, MAXCOMLEN);
486 	else {
487 		if (ndp->ni_dent.d_namlen > MAXCOMLEN)
488 			ndp->ni_dent.d_namlen = MAXCOMLEN;
489 		bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)p->p_comm,
490 		    (unsigned)(ndp->ni_dent.d_namlen + 1));
491 	}
492 bad:
493 	if (bp)
494 		brelse(bp);
495 	if (bno)
496 		rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno);
497 	if (vp)
498 		vput(vp);
499 	return (error);
500 }
501 
502 /*
503  * Read in and set up memory for executed file.
504  */
505 getxfile(p, vp, ep, flags, nargc, uid, gid)
506 	register struct proc *p;
507 	register struct vnode *vp;
508 	register struct exec *ep;
509 	int flags, nargc, uid, gid;
510 {
511 	segsz_t ts, ds, ids, uds, ss;
512 	register struct ucred *cred = u.u_cred;
513 	off_t toff;
514 	int error;
515 
516 #ifdef HPUXCOMPAT
517 	if (ep->a_mid == MID_HPUX)
518 		toff = sizeof (struct hpux_exec);
519 	else
520 #endif
521 	toff = sizeof (struct exec);
522 	if (vp->v_text && (vp->v_text->x_flag & XTRC))
523 		return (ETXTBSY);
524 	if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 &&
525 	    vp->v_usecount != 1) {
526 		register struct file *fp;
527 
528 		for (fp = file; fp < fileNFILE; fp++) {
529 			if (fp->f_type == DTYPE_VNODE &&
530 			    fp->f_count > 0 &&
531 			    (struct vnode *)fp->f_data == vp &&
532 			    (fp->f_flag & FWRITE)) {
533 				return (ETXTBSY);
534 			}
535 		}
536 	}
537 
538 	/*
539 	 * Compute text and data sizes and make sure not too large.
540 	 * NB - Check data and bss separately as they may overflow
541 	 * when summed together.
542 	 */
543 	ts = clrnd(btoc(ep->a_text));
544 	ids = clrnd(btoc(ep->a_data));
545 	uds = clrnd(btoc(ep->a_bss));
546 	ds = clrnd(btoc(ep->a_data + ep->a_bss));
547 	ss = clrnd(SSIZE + btoc(nargc));
548 	if (error =
549 	    chksize((unsigned)ts, (unsigned)ids, (unsigned)uds, (unsigned)ss))
550 		return (error);
551 
552 	/*
553 	 * Make sure enough space to start process.
554 	 */
555 	u.u_cdmap = zdmap;
556 	u.u_csmap = zdmap;
557 	if (error = swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap))
558 		return (error);
559 
560 	/*
561 	 * At this point, we are committed to the new image!
562 	 * Release virtual memory resources of old process, and
563 	 * initialize the virtual memory of the new process.
564 	 * If we resulted from vfork(), instead wakeup our
565 	 * parent who will set SVFDONE when he has taken back
566 	 * our resources.
567 	 */
568 	if ((p->p_flag & SVFORK) == 0) {
569 #ifdef MAPMEM
570 		if (u.u_mmap && (error = mmexec(p)))
571 			return (error);
572 #endif
573 		vrelvm();
574 	} else {
575 		p->p_flag &= ~SVFORK;
576 		p->p_flag |= SKEEP;
577 		wakeup((caddr_t)p);
578 		while ((p->p_flag & SVFDONE) == 0)
579 			sleep((caddr_t)p, PZERO - 1);
580 		p->p_flag &= ~(SVFDONE|SKEEP);
581 	}
582 #ifdef hp300
583 	u.u_pcb.pcb_flags &= ~(PCB_AST|PCB_HPUXMMAP|PCB_HPUXBIN);
584 #ifdef HPUXCOMPAT
585 	/* remember that we were loaded from an HPUX format file */
586 	if (ep->a_mid == MID_HPUX)
587 		u.u_pcb.pcb_flags |= PCB_HPUXBIN;
588 #endif
589 #endif
590 	p->p_flag &= ~(SPAGV|SSEQL|SUANOM|SHPUX);
591 	p->p_flag |= flags | SEXEC;
592 	u.u_dmap = u.u_cdmap;
593 	u.u_smap = u.u_csmap;
594 	vgetvm(ts, ds, ss);
595 
596 	if ((flags & SPAGV) == 0)
597 		(void) vn_rdwr(UIO_READ, vp,
598 			(char *)ctob(dptov(p, 0)),
599 			(int)ep->a_data,
600 			(off_t)(toff + ep->a_text),
601 			UIO_USERSPACE, (IO_UNIT|IO_NODELOCKED), cred, (int *)0);
602 	xalloc(vp, ep, toff, cred);
603 #if defined(tahoe)
604 	/*
605 	 * Define new keys.
606 	 */
607 	if (p->p_textp == 0) {	/* use existing code key if shared */
608 		ckeyrelease(p->p_ckey);
609 		p->p_ckey = getcodekey();
610 	}
611 	mtpr(CCK, p->p_ckey);
612 	dkeyrelease(p->p_dkey);
613 	p->p_dkey = getdatakey();
614 	mtpr(DCK, p->p_dkey);
615 #endif
616 	if ((flags & SPAGV) && p->p_textp)
617 		vinifod(p, (struct fpte *)dptopte(p, 0),
618 		    PG_FTEXT, p->p_textp->x_vptr,
619 		    (long)(1 + ts/CLSIZE), (segsz_t)btoc(ep->a_data));
620 
621 #if defined(vax) || defined(tahoe)
622 	/* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */
623 	mtpr(TBIA, 0);
624 #endif
625 #ifdef hp300
626 	TBIAU();
627 #endif
628 #if defined(i386)
629 	tlbflush();
630 #endif
631 
632 	/*
633 	 * set SUID/SGID protections, if no tracing
634 	 */
635 	if ((p->p_flag&STRC)==0) {
636 		if (uid != cred->cr_uid || gid != cred->cr_gid) {
637 			u.u_cred = cred = crcopy(cred);
638 			/*
639 			 * If process is being ktraced, turn off - unless
640 			 * root set it.
641 			 */
642 			if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) {
643 				vrele(p->p_tracep);
644 				p->p_tracep = NULL;
645 				p->p_traceflag = 0;
646 			}
647 		}
648 		cred->cr_uid = uid;
649 		cred->cr_gid = gid;
650 		p->p_uid = uid;
651 	} else
652 		psignal(p, SIGTRAP);
653 	p->p_svuid = p->p_uid;
654 	p->p_svgid = cred->cr_gid;
655 	u.u_tsize = ts;
656 	u.u_dsize = ds;
657 	u.u_ssize = ss;
658 	u.u_prof.pr_scale = 0;
659 #if defined(tahoe)
660 	u.u_pcb.pcb_savacc.faddr = (float *)NULL;
661 #endif
662 	return (0);
663 }
664