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