Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
c4ec2128 KM |
2 | * Copyright (c) 1982, 1986, 1989 Regents of the University of California. |
3 | * All rights reserved. | |
da7c5cc6 | 4 | * |
c4ec2128 KM |
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 | * | |
69be5b7a | 17 | * @(#)kern_exec.c 7.15 (Berkeley) %G% |
da7c5cc6 | 18 | */ |
28db9b87 | 19 | |
94368568 JB |
20 | #include "param.h" |
21 | #include "systm.h" | |
22 | #include "map.h" | |
94368568 JB |
23 | #include "user.h" |
24 | #include "kernel.h" | |
25 | #include "proc.h" | |
c4ec2128 KM |
26 | #include "mount.h" |
27 | #include "ucred.h" | |
28 | #include "malloc.h" | |
94368568 | 29 | #include "buf.h" |
c4ec2128 | 30 | #include "vnode.h" |
94368568 JB |
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" | |
28db9b87 | 38 | |
d301d150 KM |
39 | #include "machine/reg.h" |
40 | #include "machine/pte.h" | |
41 | #include "machine/psl.h" | |
42 | #include "machine/mtpr.h" | |
43 | ||
28db9b87 SL |
44 | /* |
45 | * exec system call, with and without environments. | |
46 | */ | |
47 | struct execa { | |
48 | char *fname; | |
49 | char **argp; | |
50 | char **envp; | |
51 | }; | |
52 | ||
53 | execv() | |
54 | { | |
55 | ((struct execa *)u.u_ap)->envp = NULL; | |
56 | execve(); | |
57 | } | |
58 | ||
59 | execve() | |
60 | { | |
61 | register nc; | |
62 | register char *cp; | |
63 | register struct buf *bp; | |
c4ec2128 | 64 | struct buf *tbp; |
28db9b87 | 65 | register struct execa *uap; |
8011f5df MK |
66 | int na, ne, ucp, ap, cc; |
67 | unsigned len; | |
28db9b87 SL |
68 | int indir, uid, gid; |
69 | char *sharg; | |
c4ec2128 | 70 | struct vnode *vp; |
28db9b87 | 71 | swblk_t bno; |
c4ec2128 | 72 | struct vattr vattr; |
28db9b87 | 73 | char cfname[MAXCOMLEN + 1]; |
cb9392ae | 74 | char cfarg[MAXINTERP]; |
9fd50f35 | 75 | union { |
cb9392ae | 76 | char ex_shell[MAXINTERP]; /* #! and interpreter name */ |
9fd50f35 SL |
77 | struct exec ex_exec; |
78 | } exdata; | |
715baff1 | 79 | register struct nameidata *ndp = &u.u_nd; |
f3aaea26 | 80 | int resid, error; |
ec67a3ce MK |
81 | #ifdef SECSIZE |
82 | extern long argdbsize; /* XXX */ | |
83 | #endif SECSIZE | |
28db9b87 | 84 | |
c4ec2128 | 85 | ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF; |
715baff1 KM |
86 | ndp->ni_segflg = UIO_USERSPACE; |
87 | ndp->ni_dirp = ((struct execa *)u.u_ap)->fname; | |
c4ec2128 | 88 | if (u.u_error = namei(ndp)) { |
28db9b87 | 89 | return; |
c4ec2128 KM |
90 | } |
91 | vp = ndp->ni_vp; | |
28db9b87 SL |
92 | bno = 0; |
93 | bp = 0; | |
94 | indir = 0; | |
ba7abd07 MK |
95 | uid = u.u_cred->cr_uid; |
96 | gid = u.u_cred->cr_gid; | |
c4ec2128 KM |
97 | if (u.u_error = VOP_GETATTR(vp, &vattr, u.u_cred)) |
98 | goto bad; | |
99 | if (vp->v_mount->m_flag & M_NOEXEC) { | |
4193b6f2 | 100 | u.u_error = EACCES; |
c4ec2128 KM |
101 | goto bad; |
102 | } | |
103 | if ((vp->v_mount->m_flag & M_NOSUID) == 0) { | |
104 | if (vattr.va_mode & VSUID) | |
105 | uid = vattr.va_uid; | |
106 | if (vattr.va_mode & VSGID) | |
107 | gid = vattr.va_gid; | |
108 | } | |
28db9b87 SL |
109 | |
110 | again: | |
0aa3b235 | 111 | if (u.u_error = VOP_ACCESS(vp, VEXEC, u.u_cred)) |
28db9b87 | 112 | goto bad; |
c4ec2128 | 113 | if ((u.u_procp->p_flag & STRC) && |
0aa3b235 | 114 | (u.u_error = VOP_ACCESS(vp, VREAD, u.u_cred))) |
28db9b87 | 115 | goto bad; |
c4ec2128 KM |
116 | if (vp->v_type != VREG || |
117 | (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) { | |
28db9b87 SL |
118 | u.u_error = EACCES; |
119 | goto bad; | |
120 | } | |
121 | ||
122 | /* | |
f3aaea26 | 123 | * Read in first few bytes of file for segment sizes, magic number: |
c4ec2128 KM |
124 | * OMAGIC = plain executable |
125 | * NMAGIC = RO text | |
126 | * ZMAGIC = demand paged RO text | |
28db9b87 SL |
127 | * Also an ASCII line beginning with #! is |
128 | * the file name of a ``shell'' and arguments may be prepended | |
129 | * to the argument list if given here. | |
130 | * | |
131 | * SHELL NAMES ARE LIMITED IN LENGTH. | |
132 | * | |
133 | * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM | |
134 | * THE ASCII LINE. | |
135 | */ | |
9fd50f35 | 136 | exdata.ex_shell[0] = '\0'; /* for zero length files */ |
c4ec2128 KM |
137 | u.u_error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata), |
138 | (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), u.u_cred, &resid); | |
28db9b87 SL |
139 | if (u.u_error) |
140 | goto bad; | |
28db9b87 | 141 | #ifndef lint |
ce66cb03 | 142 | if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) && |
9fd50f35 | 143 | exdata.ex_shell[0] != '#') { |
28db9b87 SL |
144 | u.u_error = ENOEXEC; |
145 | goto bad; | |
146 | } | |
147 | #endif | |
aec7dd3b | 148 | switch ((int)exdata.ex_exec.a_magic) { |
28db9b87 | 149 | |
c4ec2128 | 150 | case OMAGIC: |
9fd50f35 SL |
151 | exdata.ex_exec.a_data += exdata.ex_exec.a_text; |
152 | exdata.ex_exec.a_text = 0; | |
28db9b87 SL |
153 | break; |
154 | ||
c4ec2128 KM |
155 | case ZMAGIC: |
156 | case NMAGIC: | |
9fd50f35 | 157 | if (exdata.ex_exec.a_text == 0) { |
28db9b87 SL |
158 | u.u_error = ENOEXEC; |
159 | goto bad; | |
160 | } | |
161 | break; | |
162 | ||
163 | default: | |
446115cb MK |
164 | if (exdata.ex_shell[0] != '#' || |
165 | exdata.ex_shell[1] != '!' || | |
166 | indir) { | |
28db9b87 SL |
167 | u.u_error = ENOEXEC; |
168 | goto bad; | |
169 | } | |
d26813a4 | 170 | for (cp = &exdata.ex_shell[2];; ++cp) { |
446115cb | 171 | if (cp >= &exdata.ex_shell[MAXINTERP]) { |
d26813a4 KB |
172 | u.u_error = ENOEXEC; |
173 | goto bad; | |
174 | } | |
175 | if (*cp == '\n') { | |
28db9b87 SL |
176 | *cp = '\0'; |
177 | break; | |
178 | } | |
d26813a4 KB |
179 | if (*cp == '\t') |
180 | *cp = ' '; | |
28db9b87 | 181 | } |
446115cb MK |
182 | cp = &exdata.ex_shell[2]; |
183 | while (*cp == ' ') | |
184 | cp++; | |
715baff1 | 185 | ndp->ni_dirp = cp; |
446115cb MK |
186 | while (*cp && *cp != ' ') |
187 | cp++; | |
e7db1101 | 188 | cfarg[0] = '\0'; |
28db9b87 | 189 | if (*cp) { |
446115cb MK |
190 | *cp++ = '\0'; |
191 | while (*cp == ' ') | |
192 | cp++; | |
ce66cb03 | 193 | if (*cp) |
cb9392ae | 194 | bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP); |
e7db1101 | 195 | } |
446115cb | 196 | indir = 1; |
c4ec2128 KM |
197 | vput(vp); |
198 | ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF; | |
715baff1 | 199 | ndp->ni_segflg = UIO_SYSSPACE; |
c4ec2128 | 200 | if (u.u_error = namei(ndp)) |
28db9b87 | 201 | return; |
c4ec2128 KM |
202 | vp = ndp->ni_vp; |
203 | if (u.u_error = VOP_GETATTR(vp, &vattr, u.u_cred)) | |
204 | goto bad; | |
ce66cb03 MK |
205 | bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname, |
206 | MAXCOMLEN); | |
207 | cfname[MAXCOMLEN] = '\0'; | |
ba7abd07 MK |
208 | uid = u.u_cred->cr_uid; /* shell scripts can't be setuid */ |
209 | gid = u.u_cred->cr_gid; | |
28db9b87 SL |
210 | goto again; |
211 | } | |
212 | ||
213 | /* | |
214 | * Collect arguments on "file" in swap space. | |
215 | */ | |
216 | na = 0; | |
217 | ne = 0; | |
218 | nc = 0; | |
f3aaea26 | 219 | cc = 0; |
28db9b87 | 220 | uap = (struct execa *)u.u_ap; |
ec67a3ce MK |
221 | #ifdef SECSIZE |
222 | bno = rmalloc(argmap, (clrnd((int)btoc(NCARGS))) * CLBYTES / argdbsize); | |
223 | #else SECSIZE | |
9fd50f35 | 224 | bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS)))); |
ec67a3ce | 225 | #endif SECSIZE |
9fd50f35 | 226 | if (bno == 0) { |
d03b3d84 | 227 | swkill(u.u_procp, "exec: no swap space"); |
28db9b87 SL |
228 | goto bad; |
229 | } | |
230 | if (bno % CLSIZE) | |
231 | panic("execa rmalloc"); | |
f3aaea26 SL |
232 | /* |
233 | * Copy arguments into file in argdev area. | |
234 | */ | |
28db9b87 SL |
235 | if (uap->argp) for (;;) { |
236 | ap = NULL; | |
ce66cb03 MK |
237 | sharg = NULL; |
238 | if (indir && na == 0) { | |
239 | sharg = cfname; | |
240 | ap = (int)sharg; | |
241 | uap->argp++; /* ignore argv[0] */ | |
242 | } else if (indir && (na == 1 && cfarg[0])) { | |
243 | sharg = cfarg; | |
244 | ap = (int)sharg; | |
245 | } else if (indir && (na == 1 || na == 2 && cfarg[0])) | |
28db9b87 SL |
246 | ap = (int)uap->fname; |
247 | else if (uap->argp) { | |
248 | ap = fuword((caddr_t)uap->argp); | |
249 | uap->argp++; | |
250 | } | |
f3aaea26 | 251 | if (ap == NULL && uap->envp) { |
28db9b87 | 252 | uap->argp = NULL; |
f3aaea26 SL |
253 | if ((ap = fuword((caddr_t)uap->envp)) != NULL) |
254 | uap->envp++, ne++; | |
28db9b87 SL |
255 | } |
256 | if (ap == NULL) | |
257 | break; | |
258 | na++; | |
f3aaea26 | 259 | if (ap == -1) { |
1daa95c7 | 260 | u.u_error = EFAULT; |
f3aaea26 SL |
261 | break; |
262 | } | |
28db9b87 | 263 | do { |
f3aaea26 SL |
264 | if (cc <= 0) { |
265 | /* | |
266 | * We depend on NCARGS being a multiple of | |
ec67a3ce | 267 | * CLBYTES. This way we need only check |
f3aaea26 SL |
268 | * overflow before each buffer allocation. |
269 | */ | |
270 | if (nc >= NCARGS-1) { | |
271 | error = E2BIG; | |
272 | break; | |
273 | } | |
28db9b87 SL |
274 | if (bp) |
275 | bdwrite(bp); | |
ec67a3ce MK |
276 | cc = CLBYTES; |
277 | #ifdef SECSIZE | |
278 | bp = getblk(argdev, bno + nc / argdbsize, cc, | |
279 | argdbsize); | |
280 | #else SECSIZE | |
c4ec2128 | 281 | bp = getblk(argdev_vp, bno + ctod(nc/NBPG), cc); |
ec67a3ce | 282 | #endif SECSIZE |
28db9b87 SL |
283 | cp = bp->b_un.b_addr; |
284 | } | |
ce66cb03 | 285 | if (sharg) { |
8011f5df | 286 | error = copystr(sharg, cp, (unsigned)cc, &len); |
ce66cb03 MK |
287 | sharg += len; |
288 | } else { | |
8011f5df MK |
289 | error = copyinstr((caddr_t)ap, cp, (unsigned)cc, |
290 | &len); | |
ce66cb03 MK |
291 | ap += len; |
292 | } | |
f3aaea26 SL |
293 | cp += len; |
294 | nc += len; | |
295 | cc -= len; | |
296 | } while (error == ENOENT); | |
297 | if (error) { | |
298 | u.u_error = error; | |
299 | if (bp) | |
300 | brelse(bp); | |
301 | bp = 0; | |
302 | goto badarg; | |
303 | } | |
28db9b87 SL |
304 | } |
305 | if (bp) | |
306 | bdwrite(bp); | |
307 | bp = 0; | |
308 | nc = (nc + NBPW-1) & ~(NBPW-1); | |
c4ec2128 | 309 | getxfile(vp, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid, u.u_cred); |
28db9b87 SL |
310 | if (u.u_error) { |
311 | badarg: | |
c4ec2128 KM |
312 | for (cc = 0; cc < nc; cc += CLBYTES) { |
313 | u.u_error = baddr(argdev_vp, bno + ctod(cc/NBPG), | |
9ad9d3f8 | 314 | CLBYTES, NOCRED, &tbp); |
c4ec2128 | 315 | bp = tbp; |
ec67a3ce | 316 | #endif SECSIZE |
28db9b87 SL |
317 | if (bp) { |
318 | bp->b_flags |= B_AGE; /* throw away */ | |
319 | bp->b_flags &= ~B_DELWRI; /* cancel io */ | |
320 | brelse(bp); | |
321 | bp = 0; | |
322 | } | |
323 | } | |
324 | goto bad; | |
325 | } | |
c4ec2128 KM |
326 | vput(vp); |
327 | vp = NULL; | |
28db9b87 SL |
328 | |
329 | /* | |
f3aaea26 | 330 | * Copy back arglist. |
28db9b87 SL |
331 | */ |
332 | ucp = USRSTACK - nc - NBPW; | |
333 | ap = ucp - na*NBPW - 3*NBPW; | |
334 | u.u_ar0[SP] = ap; | |
335 | (void) suword((caddr_t)ap, na-ne); | |
336 | nc = 0; | |
72d4f41a | 337 | cc = 0; |
28db9b87 SL |
338 | for (;;) { |
339 | ap += NBPW; | |
f3aaea26 | 340 | if (na == ne) { |
28db9b87 SL |
341 | (void) suword((caddr_t)ap, 0); |
342 | ap += NBPW; | |
343 | } | |
344 | if (--na < 0) | |
345 | break; | |
346 | (void) suword((caddr_t)ap, ucp); | |
347 | do { | |
72d4f41a | 348 | if (cc <= 0) { |
28db9b87 SL |
349 | if (bp) |
350 | brelse(bp); | |
ec67a3ce MK |
351 | cc = CLBYTES; |
352 | #ifdef SECSIZE | |
353 | bp = bread(argdev, bno + nc / argdbsize, cc, | |
354 | argdbsize); | |
355 | #else SECSIZE | |
c4ec2128 | 356 | error = bread(argdev_vp, |
9ad9d3f8 KM |
357 | (daddr_t)(bno + ctod(nc / NBPG)), cc, |
358 | NOCRED, &tbp); | |
c4ec2128 | 359 | bp = tbp; |
ec67a3ce | 360 | #endif SECSIZE |
28db9b87 SL |
361 | bp->b_flags |= B_AGE; /* throw away */ |
362 | bp->b_flags &= ~B_DELWRI; /* cancel io */ | |
363 | cp = bp->b_un.b_addr; | |
364 | } | |
8011f5df MK |
365 | error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc, |
366 | &len); | |
72d4f41a SL |
367 | ucp += len; |
368 | cp += len; | |
369 | nc += len; | |
370 | cc -= len; | |
371 | } while (error == ENOENT); | |
372 | if (error == EFAULT) | |
373 | panic("exec: EFAULT"); | |
28db9b87 SL |
374 | } |
375 | (void) suword((caddr_t)ap, 0); | |
ce66cb03 | 376 | |
ba7abd07 | 377 | execsigs(u.u_procp); |
ce66cb03 MK |
378 | |
379 | for (nc = u.u_lastfile; nc >= 0; --nc) { | |
380 | if (u.u_pofile[nc] & UF_EXCLOSE) { | |
69be5b7a | 381 | (void) closef(u.u_ofile[nc]); |
ce66cb03 MK |
382 | u.u_ofile[nc] = NULL; |
383 | u.u_pofile[nc] = 0; | |
384 | } | |
385 | u.u_pofile[nc] &= ~UF_MAPPED; | |
386 | } | |
387 | while (u.u_lastfile >= 0 && u.u_ofile[u.u_lastfile] == NULL) | |
388 | u.u_lastfile--; | |
9fd50f35 | 389 | setregs(exdata.ex_exec.a_entry); |
715baff1 KM |
390 | /* |
391 | * Remember file name for accounting. | |
392 | */ | |
393 | u.u_acflag &= ~AFORK; | |
ce66cb03 MK |
394 | if (indir) |
395 | bcopy((caddr_t)cfname, (caddr_t)u.u_comm, MAXCOMLEN); | |
396 | else { | |
397 | if (ndp->ni_dent.d_namlen > MAXCOMLEN) | |
398 | ndp->ni_dent.d_namlen = MAXCOMLEN; | |
399 | bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)u.u_comm, | |
400 | (unsigned)(ndp->ni_dent.d_namlen + 1)); | |
401 | } | |
28db9b87 SL |
402 | bad: |
403 | if (bp) | |
404 | brelse(bp); | |
405 | if (bno) | |
ec67a3ce MK |
406 | #ifdef SECSIZE |
407 | rmfree(argmap, (clrnd((int)btoc(NCARGS))) * CLBYTES / argdbsize, | |
408 | bno); | |
409 | #else SECSIZE | |
28db9b87 | 410 | rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno); |
ec67a3ce | 411 | #endif SECSIZE |
c4ec2128 KM |
412 | if (vp) |
413 | vput(vp); | |
28db9b87 SL |
414 | } |
415 | ||
416 | /* | |
417 | * Read in and set up memory for executed file. | |
418 | */ | |
c4ec2128 KM |
419 | getxfile(vp, ep, nargc, uid, gid, cred) |
420 | register struct vnode *vp; | |
9fd50f35 | 421 | register struct exec *ep; |
28db9b87 | 422 | int nargc, uid, gid; |
c4ec2128 | 423 | struct ucred *cred; |
28db9b87 | 424 | { |
ba7abd07 | 425 | register struct proc *p = u.u_procp; |
0c48b03e | 426 | size_t ts, ds, ids, uds, ss; |
28db9b87 SL |
427 | int pagi; |
428 | ||
c4ec2128 KM |
429 | if (ep->a_magic == ZMAGIC) |
430 | pagi = SPAGV; | |
28db9b87 SL |
431 | else |
432 | pagi = 0; | |
c4ec2128 | 433 | if (vp->v_text && (vp->v_text->x_flag & XTRC)) { |
ce08d752 MK |
434 | u.u_error = ETXTBSY; |
435 | goto bad; | |
436 | } | |
c4ec2128 KM |
437 | if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 && |
438 | vp->v_count != 1) { | |
28db9b87 SL |
439 | register struct file *fp; |
440 | ||
441 | for (fp = file; fp < fileNFILE; fp++) { | |
c4ec2128 | 442 | if (fp->f_type == DTYPE_VNODE && |
28db9b87 | 443 | fp->f_count > 0 && |
c4ec2128 KM |
444 | (struct vnode *)fp->f_data == vp && |
445 | (fp->f_flag & FWRITE)) { | |
28db9b87 SL |
446 | u.u_error = ETXTBSY; |
447 | goto bad; | |
448 | } | |
449 | } | |
450 | } | |
451 | ||
452 | /* | |
453 | * Compute text and data sizes and make sure not too large. | |
0c48b03e KM |
454 | * NB - Check data and bss separately as they may overflow |
455 | * when summed together. | |
28db9b87 | 456 | */ |
9fd50f35 | 457 | ts = clrnd(btoc(ep->a_text)); |
0c48b03e KM |
458 | ids = clrnd(btoc(ep->a_data)); |
459 | uds = clrnd(btoc(ep->a_bss)); | |
f3aaea26 | 460 | ds = clrnd(btoc(ep->a_data + ep->a_bss)); |
28db9b87 | 461 | ss = clrnd(SSIZE + btoc(nargc)); |
0c48b03e | 462 | if (chksize((unsigned)ts, (unsigned)ids, (unsigned)uds, (unsigned)ss)) |
28db9b87 SL |
463 | goto bad; |
464 | ||
465 | /* | |
466 | * Make sure enough space to start process. | |
467 | */ | |
468 | u.u_cdmap = zdmap; | |
469 | u.u_csmap = zdmap; | |
470 | if (swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap) == NULL) | |
471 | goto bad; | |
472 | ||
473 | /* | |
c4ec2128 | 474 | * At this point, we are committed to the new image! |
28db9b87 SL |
475 | * Release virtual memory resources of old process, and |
476 | * initialize the virtual memory of the new process. | |
477 | * If we resulted from vfork(), instead wakeup our | |
478 | * parent who will set SVFDONE when he has taken back | |
479 | * our resources. | |
480 | */ | |
ba7abd07 | 481 | if ((p->p_flag & SVFORK) == 0) |
28db9b87 SL |
482 | vrelvm(); |
483 | else { | |
ba7abd07 MK |
484 | p->p_flag &= ~SVFORK; |
485 | p->p_flag |= SKEEP; | |
486 | wakeup((caddr_t)p); | |
487 | while ((p->p_flag & SVFDONE) == 0) | |
488 | sleep((caddr_t)p, PZERO - 1); | |
489 | p->p_flag &= ~(SVFDONE|SKEEP); | |
28db9b87 | 490 | } |
ba7abd07 MK |
491 | p->p_flag &= ~(SPAGV|SSEQL|SUANOM); |
492 | p->p_flag |= pagi | SEXEC; | |
28db9b87 SL |
493 | u.u_dmap = u.u_cdmap; |
494 | u.u_smap = u.u_csmap; | |
495 | vgetvm(ts, ds, ss); | |
496 | ||
497 | if (pagi == 0) | |
c4ec2128 | 498 | u.u_error = vn_rdwr(UIO_READ, vp, |
28db9b87 | 499 | (char *)ctob(dptov(u.u_procp, 0)), |
9fd50f35 | 500 | (int)ep->a_data, |
8011f5df | 501 | (off_t)(sizeof (struct exec) + ep->a_text), |
c4ec2128 KM |
502 | UIO_USERSPACE, (IO_UNIT|IO_NODELOCKED), cred, (int *)0); |
503 | xalloc(vp, ep, pagi, cred); | |
fb1db32c MK |
504 | #if defined(tahoe) |
505 | /* | |
506 | * Define new keys. | |
507 | */ | |
ba7abd07 MK |
508 | if (p->p_textp == 0) { /* use existing code key if shared */ |
509 | ckeyrelease(p->p_ckey); | |
510 | p->p_ckey = getcodekey(); | |
fb1db32c | 511 | } |
ba7abd07 MK |
512 | mtpr(CCK, p->p_ckey); |
513 | dkeyrelease(p->p_dkey); | |
514 | p->p_dkey = getdatakey(); | |
515 | mtpr(DCK, p->p_dkey); | |
fb1db32c | 516 | #endif |
ba7abd07 MK |
517 | if (pagi && p->p_textp) |
518 | vinifod((struct fpte *)dptopte(p, 0), | |
519 | PG_FTEXT, p->p_textp->x_vptr, | |
8011f5df | 520 | (long)(1 + ts/CLSIZE), (size_t)btoc(ep->a_data)); |
28db9b87 | 521 | |
fb1db32c | 522 | #if defined(vax) || defined(tahoe) |
28db9b87 | 523 | /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */ |
28db9b87 SL |
524 | mtpr(TBIA, 0); |
525 | #endif | |
526 | ||
527 | if (u.u_error) | |
d03b3d84 | 528 | swkill(u.u_procp, "exec: I/O error mapping pages"); |
28db9b87 SL |
529 | /* |
530 | * set SUID/SGID protections, if no tracing | |
531 | */ | |
ba7abd07 MK |
532 | if ((p->p_flag&STRC)==0) { |
533 | if (uid != u.u_cred->cr_uid || gid != u.u_cred->cr_gid) | |
c4ec2128 | 534 | u.u_cred = crcopy(u.u_cred); |
ba7abd07 MK |
535 | u.u_cred->cr_uid = uid; |
536 | u.u_cred->cr_gid = gid; | |
537 | p->p_uid = uid; | |
28db9b87 | 538 | } else |
ba7abd07 MK |
539 | psignal(p, SIGTRAP); |
540 | p->p_svuid = p->p_uid; | |
541 | p->p_svgid = u.u_cred->cr_gid; | |
28db9b87 SL |
542 | u.u_tsize = ts; |
543 | u.u_dsize = ds; | |
544 | u.u_ssize = ss; | |
d4a03a57 | 545 | u.u_prof.pr_scale = 0; |
fb1db32c MK |
546 | #if defined(tahoe) |
547 | u.u_pcb.pcb_savacc.faddr = (float *)NULL; | |
548 | #endif | |
28db9b87 SL |
549 | bad: |
550 | return; | |
551 | } |