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