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