xref: /csrg-svn/sys/kern/kern_exec.c (revision 47655)
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.38 (Berkeley) 03/25/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, flags = 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 			flags |= SHPUX;
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 		flags |= SPAGV;
215 	case NMAGIC:
216 		if (exdata.ex_exec.a_text == 0) {
217 			error = ENOEXEC;
218 			goto bad;
219 		}
220 		break;
221 
222 	default:
223 		if (exdata.ex_shell[0] != '#' ||
224 		    exdata.ex_shell[1] != '!' ||
225 		    indir) {
226 			error = ENOEXEC;
227 			goto bad;
228 		}
229 		for (cp = &exdata.ex_shell[2];; ++cp) {
230 			if (cp >= &exdata.ex_shell[MAXINTERP]) {
231 				error = ENOEXEC;
232 				goto bad;
233 			}
234 			if (*cp == '\n') {
235 				*cp = '\0';
236 				break;
237 			}
238 			if (*cp == '\t')
239 				*cp = ' ';
240 		}
241 		cp = &exdata.ex_shell[2];
242 		while (*cp == ' ')
243 			cp++;
244 		ndp->ni_dirp = cp;
245 		while (*cp && *cp != ' ')
246 			cp++;
247 		cfarg[0] = '\0';
248 		if (*cp) {
249 			*cp++ = '\0';
250 			while (*cp == ' ')
251 				cp++;
252 			if (*cp)
253 				bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP);
254 		}
255 		indir = 1;
256 		vput(vp);
257 		ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
258 		ndp->ni_segflg = UIO_SYSSPACE;
259 		if (error = namei(ndp, p))
260 			return (error);
261 		vp = ndp->ni_vp;
262 		if (error = VOP_GETATTR(vp, &vattr, cred))
263 			goto bad;
264 		bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
265 		    MAXCOMLEN);
266 		cfname[MAXCOMLEN] = '\0';
267 		uid = cred->cr_uid;	/* shell scripts can't be setuid */
268 		gid = cred->cr_gid;
269 		goto again;
270 	}
271 
272 	/*
273 	 * Collect arguments on "file" in swap space.
274 	 */
275 	na = 0;
276 	ne = 0;
277 	nc = 0;
278 	cc = NCARGS;
279 	execargs = kmem_alloc_wait(exec_map, NCARGS);
280 	cp = (char *) execargs;
281 	/*
282 	 * Copy arguments into file in argdev area.
283 	 */
284 	if (uap->argp) for (;;) {
285 		ap = NULL;
286 		sharg = NULL;
287 		if (indir && na == 0) {
288 			sharg = cfname;
289 			ap = (int)sharg;
290 			uap->argp++;		/* ignore argv[0] */
291 		} else if (indir && (na == 1 && cfarg[0])) {
292 			sharg = cfarg;
293 			ap = (int)sharg;
294 		} else if (indir && (na == 1 || na == 2 && cfarg[0]))
295 			ap = (int)uap->fname;
296 		else if (uap->argp) {
297 			ap = fuword((caddr_t)uap->argp);
298 			uap->argp++;
299 		}
300 		if (ap == NULL && uap->envp) {
301 			uap->argp = NULL;
302 			if ((ap = fuword((caddr_t)uap->envp)) != NULL)
303 				uap->envp++, ne++;
304 		}
305 		if (ap == NULL)
306 			break;
307 		na++;
308 		if (ap == -1) {
309 			error = EFAULT;
310 			goto bad;
311 		}
312 		do {
313 			if (nc >= NCARGS-1) {
314 				error = E2BIG;
315 				break;
316 			}
317 			if (sharg) {
318 				error = copystr(sharg, cp, (unsigned)cc, &len);
319 				sharg += len;
320 			} else {
321 				error = copyinstr((caddr_t)ap, cp, (unsigned)cc,
322 				    &len);
323 				ap += len;
324 			}
325 			cp += len;
326 			nc += len;
327 			cc -= len;
328 		} while (error == ENAMETOOLONG);
329 		if (error)
330 			goto bad;
331 	}
332 	nc = (nc + NBPW-1) & ~(NBPW-1);
333 	error = getxfile(p, vp, &exdata.ex_exec, flags, nc + (na+4)*NBPW,
334 	    uid, gid);
335 	if (error)
336 		goto bad;
337 	vput(vp);
338 	vp = NULL;
339 
340 #ifdef HPUXCOMPAT
341 	/*
342 	 * We are now committed to the exec so we can save the exec
343 	 * header in the pcb where we can dump it if necessary in core()
344 	 */
345 	if (u.u_pcb.pcb_flags & PCB_HPUXBIN)
346 		bcopy((caddr_t)&hhead,
347 		      (caddr_t)u.u_pcb.pcb_exec, sizeof hhead);
348 #endif
349 
350 	/*
351 	 * Copy back arglist.
352 	 */
353 	ucp = USRSTACK - sizeof(u.u_pcb.pcb_sigc) - nc - NBPW;
354 	ap = ucp - na*NBPW - 3*NBPW;
355 	p->p_regs[SP] = ap;
356 	(void) suword((caddr_t)ap, na-ne);
357 	nc = 0;
358 	cp = (char *) execargs;
359 	cc = NCARGS;
360 	for (;;) {
361 		ap += NBPW;
362 		if (na == ne) {
363 			(void) suword((caddr_t)ap, 0);
364 			ap += NBPW;
365 		}
366 		if (--na < 0)
367 			break;
368 		(void) suword((caddr_t)ap, ucp);
369 		do {
370 			error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc,
371 			    &len);
372 			ucp += len;
373 			cp += len;
374 			nc += len;
375 			cc -= len;
376 		} while (error == ENAMETOOLONG);
377 		if (error == EFAULT)
378 			panic("exec: EFAULT");
379 	}
380 	(void) suword((caddr_t)ap, 0);
381 
382 	execsigs(p);
383 
384 	for (nc = fdp->fd_lastfile; nc >= 0; --nc) {
385 		if (fdp->fd_ofileflags[nc] & UF_EXCLOSE) {
386 			(void) closef(fdp->fd_ofiles[nc], p);
387 			fdp->fd_ofiles[nc] = NULL;
388 			fdp->fd_ofileflags[nc] = 0;
389 			if (nc < fdp->fd_freefile)
390 				fdp->fd_freefile = nc;
391 		}
392 		fdp->fd_ofileflags[nc] &= ~UF_MAPPED;
393 	}
394 	/*
395 	 * Adjust fd_lastfile to account for descriptors closed above.
396 	 * Don't decrement fd_lastfile past 0, as it's unsigned.
397 	 */
398 	while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
399 		fdp->fd_lastfile--;
400 	setregs(exdata.ex_exec.a_entry, retval);
401 	/*
402 	 * Install sigcode at top of user stack.
403 	 */
404 	copyout((caddr_t)u.u_pcb.pcb_sigc,
405 		(caddr_t)(USRSTACK - sizeof(u.u_pcb.pcb_sigc)),
406 		sizeof(u.u_pcb.pcb_sigc));
407 	/*
408 	 * Remember file name for accounting.
409 	 */
410 	p->p_acflag &= ~AFORK;
411 	if (indir)
412 		bcopy((caddr_t)cfname, (caddr_t)p->p_comm, MAXCOMLEN);
413 	else {
414 		if (ndp->ni_dent.d_namlen > MAXCOMLEN)
415 			ndp->ni_dent.d_namlen = MAXCOMLEN;
416 		bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)p->p_comm,
417 		    (unsigned)(ndp->ni_dent.d_namlen + 1));
418 	}
419 bad:
420 	if (execargs)
421 		kmem_free_wakeup(exec_map, execargs, NCARGS);
422 	if (vp)
423 		vput(vp);
424 	return (error);
425 }
426 
427 /*
428  * Read in and set up memory for executed file.
429  */
430 getxfile(p, vp, ep, flags, nargc, uid, gid)
431 	register struct proc *p;
432 	register struct vnode *vp;
433 	register struct exec *ep;
434 	int flags, nargc, uid, gid;
435 {
436 	segsz_t ts, ds, ss;
437 	register struct ucred *cred = p->p_ucred;
438 	off_t toff;
439 	int error = 0;
440 	vm_offset_t addr;
441 	vm_size_t size;
442 	struct vmspace *vm = p->p_vmspace;
443 
444 #ifdef HPUXCOMPAT
445 	if (ep->a_mid == MID_HPUX) {
446 		if (flags & SPAGV)
447 			toff = CLBYTES;
448 		else
449 			toff = sizeof (struct hpux_exec);
450 	} else
451 #endif
452 	if (flags & SPAGV)
453 		toff = CLBYTES;
454 	else
455 		toff = sizeof (struct exec);
456 	if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 &&
457 	    vp->v_usecount != 1) {
458 		register struct file *fp;
459 
460 		for (fp = file; fp < fileNFILE; fp++) {
461 			if (fp->f_type == DTYPE_VNODE &&
462 			    fp->f_count > 0 &&
463 			    (struct vnode *)fp->f_data == vp &&
464 			    (fp->f_flag & FWRITE)) {
465 				return (ETXTBSY);
466 			}
467 		}
468 	}
469 
470 	/*
471 	 * Compute text and data sizes and make sure not too large.
472 	 * NB - Check data and bss separately as they may overflow
473 	 * when summed together.
474 	 */
475 	ts = clrnd(btoc(ep->a_text));
476 	ds = clrnd(btoc(ep->a_data + ep->a_bss));
477 	ss = clrnd(SSIZE + btoc(nargc + sizeof(u.u_pcb.pcb_sigc)));
478 
479 	/*
480 	 * If we're sharing the address space, allocate a new space
481 	 * and release our reference to the old one.  Otherwise,
482 	 * empty out the existing vmspace.
483 	 */
484 	if (vm->vm_refcnt > 1) {
485 		p->p_vmspace = vmspace_alloc(vm_map_min(&vm->vm_map),
486 		    vm_map_max(&vm->vm_map), 1);
487 		vmspace_free(vm);
488 		vm = p->p_vmspace;
489 	} else {
490 #ifdef SYSVSHM
491 		if (vm->vm_shm)
492 			shmexit(p);
493 #endif
494 		(void) vm_map_remove(&vm->vm_map, vm_map_min(&vm->vm_map),
495 		    vm_map_max(&vm->vm_map));
496 	}
497 	/*
498 	 * If parent is waiting for us to exec or exit,
499 	 * SPPWAIT will be set; clear it and wakeup parent.
500 	 */
501 	if (p->p_flag & SPPWAIT) {
502 		p->p_flag &= ~SPPWAIT;
503 		wakeup((caddr_t) p->p_pptr);
504 	}
505 #ifdef hp300
506 	u.u_pcb.pcb_flags &= ~(PCB_AST|PCB_HPUXMMAP|PCB_HPUXBIN);
507 #ifdef HPUXCOMPAT
508 	/* remember that we were loaded from an HPUX format file */
509 	if (ep->a_mid == MID_HPUX)
510 		u.u_pcb.pcb_flags |= PCB_HPUXBIN;
511 #endif
512 #endif
513 	p->p_flag &= ~(SPAGV|SSEQL|SUANOM|SHPUX);
514 	p->p_flag |= flags | SEXEC;
515 	addr = VM_MIN_ADDRESS;
516 	if (vm_allocate(&vm->vm_map, &addr, round_page(ctob(ts + ds)), FALSE)) {
517 		uprintf("Cannot allocate text+data space\n");
518 		error = ENOMEM;			/* XXX */
519 		goto badmap;
520 	}
521 	size = round_page(MAXSSIZ);		/* XXX */
522 	addr = trunc_page(VM_MAX_ADDRESS - size);
523 	if (vm_allocate(&vm->vm_map, &addr, size, FALSE)) {
524 		uprintf("Cannot allocate stack space\n");
525 		error = ENOMEM;			/* XXX */
526 		goto badmap;
527 	}
528 	vm->vm_maxsaddr = (caddr_t)addr;
529 	vm->vm_taddr = (caddr_t)VM_MIN_ADDRESS;
530 	vm->vm_daddr = (caddr_t)(VM_MIN_ADDRESS + ctob(ts));
531 
532 	if ((flags & SPAGV) == 0) {
533 		/*
534 		 * Read in data segment.
535 		 */
536 		(void) vn_rdwr(UIO_READ, vp, vm->vm_daddr, (int) ep->a_data,
537 			(off_t)(toff + ep->a_text), UIO_USERSPACE,
538 			(IO_UNIT|IO_NODELOCKED), cred, (int *)0);
539 		/*
540 		 * Read in text segment if necessary (0410),
541 		 * and read-protect it.
542 		 */
543 		if (ep->a_text > 0) {
544 			error = vn_rdwr(UIO_READ, vp, vm->vm_taddr,
545 				(int)ep->a_text, toff, UIO_USERSPACE,
546 				(IO_UNIT|IO_NODELOCKED), cred, (int *)0);
547 			(void) vm_map_protect(&vm->vm_map, VM_MIN_ADDRESS,
548 				VM_MIN_ADDRESS + trunc_page(ep->a_text),
549 				VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
550 		}
551 	} else {
552 		/*
553 		 * Allocate a region backed by the exec'ed vnode.
554 		 */
555 		addr = VM_MIN_ADDRESS;
556 		size = round_page(ep->a_text + ep->a_data);
557 		error = vm_mmap(&vm->vm_map, &addr, size, VM_PROT_ALL,
558 			MAP_FILE|MAP_COPY|MAP_FIXED,
559 			(caddr_t)vp, (vm_offset_t)toff);
560 		(void) vm_map_protect(&vm->vm_map, addr,
561 			addr + trunc_page(ep->a_text),
562 			VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
563 		vp->v_flag |= VTEXT;
564 	}
565 badmap:
566 	if (error) {
567 		printf("pid %d: VM allocation failure\n", p->p_pid);
568 		uprintf("sorry, pid %d was killed in exec: VM allocation\n",
569 			p->p_pid);
570 		psignal(p, SIGKILL);
571 		p->p_flag |= SULOCK;
572 		return(error);
573 	}
574 
575 	/*
576 	 * set SUID/SGID protections, if no tracing
577 	 */
578 	if ((p->p_flag&STRC)==0) {
579 		if (uid != cred->cr_uid || gid != cred->cr_gid) {
580 			p->p_ucred = cred = crcopy(cred);
581 			/*
582 			 * If process is being ktraced, turn off - unless
583 			 * root set it.
584 			 */
585 			if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) {
586 				vrele(p->p_tracep);
587 				p->p_tracep = NULL;
588 				p->p_traceflag = 0;
589 			}
590 		}
591 		cred->cr_uid = uid;
592 		cred->cr_gid = gid;
593 	} else
594 		psignal(p, SIGTRAP);
595 	p->p_cred->p_svuid = cred->cr_uid;
596 	p->p_cred->p_svgid = cred->cr_gid;
597 	vm->vm_tsize = ts;
598 	vm->vm_dsize = ds;
599 	vm->vm_ssize = ss;
600 	p->p_stats->p_prof.pr_scale = 0;
601 #if defined(tahoe)
602 	u.u_pcb.pcb_savacc.faddr = (float *)NULL;
603 #endif
604 	return (0);
605 }
606