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