Deleted Added
full compact
kern_exec.c (32286) kern_exec.c (32446)
1/*
2 * Copyright (c) 1993, David Greenman
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*
2 * Copyright (c) 1993, David Greenman
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: kern_exec.c,v 1.72 1997/12/27 02:56:21 bde Exp $
26 * $Id: kern_exec.c,v 1.73 1998/01/06 05:15:34 dyson Exp $
27 */
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/sysproto.h>
32#include <sys/signalvar.h>
33#include <sys/kernel.h>
34#include <sys/mount.h>
35#include <sys/filedesc.h>
36#include <sys/fcntl.h>
37#include <sys/acct.h>
38#include <sys/exec.h>
39#include <sys/imgact.h>
40#include <sys/imgact_elf.h>
41#include <sys/wait.h>
42#include <sys/proc.h>
43#include <sys/pioctl.h>
44#include <sys/malloc.h>
45#include <sys/namei.h>
46#include <sys/sysent.h>
47#include <sys/shm.h>
48#include <sys/sysctl.h>
49#include <sys/vnode.h>
50#include <sys/buf.h>
51
52#include <vm/vm.h>
53#include <vm/vm_param.h>
54#include <vm/vm_prot.h>
55#include <sys/lock.h>
56#include <vm/pmap.h>
27 */
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/sysproto.h>
32#include <sys/signalvar.h>
33#include <sys/kernel.h>
34#include <sys/mount.h>
35#include <sys/filedesc.h>
36#include <sys/fcntl.h>
37#include <sys/acct.h>
38#include <sys/exec.h>
39#include <sys/imgact.h>
40#include <sys/imgact_elf.h>
41#include <sys/wait.h>
42#include <sys/proc.h>
43#include <sys/pioctl.h>
44#include <sys/malloc.h>
45#include <sys/namei.h>
46#include <sys/sysent.h>
47#include <sys/shm.h>
48#include <sys/sysctl.h>
49#include <sys/vnode.h>
50#include <sys/buf.h>
51
52#include <vm/vm.h>
53#include <vm/vm_param.h>
54#include <vm/vm_prot.h>
55#include <sys/lock.h>
56#include <vm/pmap.h>
57#include <vm/vm_page.h>
57#include <vm/vm_map.h>
58#include <vm/vm_kern.h>
59#include <vm/vm_extern.h>
60#include <vm/vm_object.h>
61#include <vm/vm_zone.h>
58#include <vm/vm_map.h>
59#include <vm/vm_kern.h>
60#include <vm/vm_extern.h>
61#include <vm/vm_object.h>
62#include <vm/vm_zone.h>
63#include <vm/vm_pager.h>
64#include <vm/vm_pageout.h>
62
63#include <machine/reg.h>
64
65static int *exec_copyout_strings __P((struct image_params *));
66
65
66#include <machine/reg.h>
67
68static int *exec_copyout_strings __P((struct image_params *));
69
67static int exec_check_permissions(struct image_params *);
70static int exec_check_permissions __P((struct image_params *));
71static int exec_map_first_page __P((struct image_params *));
72static void exec_unmap_first_page __P((struct image_params *));
68
69/*
70 * XXX trouble here if sizeof(caddr_t) != sizeof(int), other parts
71 * of the sysctl code also assumes this, and sizeof(int) == sizeof(long).
72 */
73static struct ps_strings *ps_strings = PS_STRINGS;
74SYSCTL_INT(_kern, KERN_PS_STRINGS, ps_strings, 0, &ps_strings, 0, "");
75
76static caddr_t usrstack = (caddr_t)USRSTACK;
77SYSCTL_INT(_kern, KERN_USRSTACK, usrstack, 0, &usrstack, 0, "");
78
79/*
80 * execsw_set is constructed for us by the linker. Each of the items
81 * is a pointer to a `const struct execsw', hence the double pointer here.
82 */
83static const struct execsw **execsw =
84 (const struct execsw **)&execsw_set.ls_items[0];
85
86#ifndef _SYS_SYSPROTO_H_
87struct execve_args {
88 char *fname;
89 char **argv;
90 char **envv;
91};
92#endif
93
94/*
95 * execve() system call.
96 */
97int
98execve(p, uap)
99 struct proc *p;
100 register struct execve_args *uap;
101{
102 struct nameidata nd, *ndp;
103 int *stack_base;
104 int error, len, i;
105 struct image_params image_params, *imgp;
106 struct vattr attr;
107 struct buf *bp = NULL;
108
109 imgp = &image_params;
110
111 /*
112 * Initialize part of the common data
113 */
114 imgp->proc = p;
115 imgp->uap = uap;
116 imgp->attr = &attr;
73
74/*
75 * XXX trouble here if sizeof(caddr_t) != sizeof(int), other parts
76 * of the sysctl code also assumes this, and sizeof(int) == sizeof(long).
77 */
78static struct ps_strings *ps_strings = PS_STRINGS;
79SYSCTL_INT(_kern, KERN_PS_STRINGS, ps_strings, 0, &ps_strings, 0, "");
80
81static caddr_t usrstack = (caddr_t)USRSTACK;
82SYSCTL_INT(_kern, KERN_USRSTACK, usrstack, 0, &usrstack, 0, "");
83
84/*
85 * execsw_set is constructed for us by the linker. Each of the items
86 * is a pointer to a `const struct execsw', hence the double pointer here.
87 */
88static const struct execsw **execsw =
89 (const struct execsw **)&execsw_set.ls_items[0];
90
91#ifndef _SYS_SYSPROTO_H_
92struct execve_args {
93 char *fname;
94 char **argv;
95 char **envv;
96};
97#endif
98
99/*
100 * execve() system call.
101 */
102int
103execve(p, uap)
104 struct proc *p;
105 register struct execve_args *uap;
106{
107 struct nameidata nd, *ndp;
108 int *stack_base;
109 int error, len, i;
110 struct image_params image_params, *imgp;
111 struct vattr attr;
112 struct buf *bp = NULL;
113
114 imgp = &image_params;
115
116 /*
117 * Initialize part of the common data
118 */
119 imgp->proc = p;
120 imgp->uap = uap;
121 imgp->attr = &attr;
117 imgp->image_header = NULL;
118 imgp->argc = imgp->envc = 0;
119 imgp->argv0 = NULL;
120 imgp->entry_addr = 0;
121 imgp->vmspace_destroyed = 0;
122 imgp->interpreted = 0;
123 imgp->interpreter_name[0] = '\0';
124 imgp->auxargs = NULL;
122 imgp->argc = imgp->envc = 0;
123 imgp->argv0 = NULL;
124 imgp->entry_addr = 0;
125 imgp->vmspace_destroyed = 0;
126 imgp->interpreted = 0;
127 imgp->interpreter_name[0] = '\0';
128 imgp->auxargs = NULL;
129 imgp->vp = NULL;
130 imgp->firstpage = NULL;
125
126 /*
127 * Allocate temporary demand zeroed space for argument and
128 * environment strings
129 */
131
132 /*
133 * Allocate temporary demand zeroed space for argument and
134 * environment strings
135 */
130 imgp->stringbase = (char *)kmem_alloc_wait(exec_map, ARG_MAX);
136 imgp->stringbase = (char *)kmem_alloc_wait(exec_map, ARG_MAX + PAGE_SIZE);
131 if (imgp->stringbase == NULL) {
132 error = ENOMEM;
133 goto exec_fail;
134 }
135 imgp->stringp = imgp->stringbase;
136 imgp->stringspace = ARG_MAX;
137 if (imgp->stringbase == NULL) {
138 error = ENOMEM;
139 goto exec_fail;
140 }
141 imgp->stringp = imgp->stringbase;
142 imgp->stringspace = ARG_MAX;
143 imgp->image_header = imgp->stringbase + ARG_MAX;
137
138 /*
139 * Translate the file name. namei() returns a vnode pointer
140 * in ni_vp amoung other things.
141 */
142 ndp = &nd;
143 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME,
144 UIO_USERSPACE, uap->fname, p);
145
146interpret:
147
148 error = namei(ndp);
149 if (error) {
144
145 /*
146 * Translate the file name. namei() returns a vnode pointer
147 * in ni_vp amoung other things.
148 */
149 ndp = &nd;
150 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME,
151 UIO_USERSPACE, uap->fname, p);
152
153interpret:
154
155 error = namei(ndp);
156 if (error) {
150 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, ARG_MAX);
157 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase,
158 ARG_MAX + PAGE_SIZE);
151 goto exec_fail;
152 }
153
154 imgp->vp = ndp->ni_vp;
155
156 /*
157 * Check file permissions (also 'opens' file)
158 */
159 error = exec_check_permissions(imgp);
160 if (error) {
161 VOP_UNLOCK(imgp->vp, 0, p);
162 goto exec_fail_dealloc;
163 }
164
159 goto exec_fail;
160 }
161
162 imgp->vp = ndp->ni_vp;
163
164 /*
165 * Check file permissions (also 'opens' file)
166 */
167 error = exec_check_permissions(imgp);
168 if (error) {
169 VOP_UNLOCK(imgp->vp, 0, p);
170 goto exec_fail_dealloc;
171 }
172
165 /*
166 * Get the image header, which we define here as meaning the first
167 * page of the executable.
168 */
169 if (imgp->vp->v_object && imgp->vp->v_mount &&
170 imgp->vp->v_mount->mnt_stat.f_iosize >= PAGE_SIZE &&
171 imgp->vp->v_object->un_pager.vnp.vnp_size >=
172 imgp->vp->v_mount->mnt_stat.f_iosize) {
173 /*
174 * Get a buffer with (at least) the first page.
175 */
176 error = bread(imgp->vp, 0, imgp->vp->v_mount->mnt_stat.f_iosize,
177 p->p_ucred, &bp);
178 imgp->image_header = bp->b_data;
179 } else {
180 int resid;
181
182 /*
183 * The filesystem block size is too small, so do this the hard
184 * way. Malloc some space and read PAGE_SIZE worth of the image
185 * header into it.
186 */
187 imgp->image_header = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
188 error = vn_rdwr(UIO_READ, imgp->vp,
189 (void *)imgp->image_header, PAGE_SIZE, 0,
190 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
191 /*
192 * Clear out any remaining junk.
193 */
194 if (!error && resid)
195 bzero((char *)imgp->image_header + PAGE_SIZE - resid, resid);
196 }
173 error = exec_map_first_page(imgp);
197 VOP_UNLOCK(imgp->vp, 0, p);
198 if (error)
199 goto exec_fail_dealloc;
200
201 /*
202 * Loop through list of image activators, calling each one.
203 * If there is no match, the activator returns -1. If there
204 * is a match, but there was an error during the activation,
205 * the error is returned. Otherwise 0 means success. If the
206 * image is interpreted, loop back up and try activating
207 * the interpreter.
208 */
209 for (i = 0; execsw[i]; ++i) {
210 if (execsw[i]->ex_imgact)
211 error = (*execsw[i]->ex_imgact)(imgp);
212 else
213 continue;
214 if (error == -1)
215 continue;
216 if (error)
217 goto exec_fail_dealloc;
218 if (imgp->interpreted) {
174 VOP_UNLOCK(imgp->vp, 0, p);
175 if (error)
176 goto exec_fail_dealloc;
177
178 /*
179 * Loop through list of image activators, calling each one.
180 * If there is no match, the activator returns -1. If there
181 * is a match, but there was an error during the activation,
182 * the error is returned. Otherwise 0 means success. If the
183 * image is interpreted, loop back up and try activating
184 * the interpreter.
185 */
186 for (i = 0; execsw[i]; ++i) {
187 if (execsw[i]->ex_imgact)
188 error = (*execsw[i]->ex_imgact)(imgp);
189 else
190 continue;
191 if (error == -1)
192 continue;
193 if (error)
194 goto exec_fail_dealloc;
195 if (imgp->interpreted) {
219 /* free old bp/image_header */
220 if (bp != NULL) {
221 brelse(bp);
222 bp = NULL;
223 } else
224 free((void *)imgp->image_header, M_TEMP);
225 imgp->image_header = NULL;
196 exec_unmap_first_page(imgp);
226 /* free old vnode and name buffer */
227 vrele(ndp->ni_vp);
228 zfree(namei_zone, ndp->ni_cnd.cn_pnbuf);
229 /* set new name to that of the interpreter */
230 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME,
231 UIO_SYSSPACE, imgp->interpreter_name, p);
232 goto interpret;
233 }
234 break;
235 }
236 /* If we made it through all the activators and none matched, exit. */
237 if (error == -1) {
238 error = ENOEXEC;
239 goto exec_fail_dealloc;
240 }
241
242 /*
243 * Copy out strings (args and env) and initialize stack base
244 */
245 stack_base = exec_copyout_strings(imgp);
246 p->p_vmspace->vm_minsaddr = (char *)stack_base;
247
248 /*
249 * If custom stack fixup routine present for this process
250 * let it do the stack setup.
251 * Else stuff argument count as first item on stack
252 */
253 if (p->p_sysent->sv_fixup)
254 (*p->p_sysent->sv_fixup)(&stack_base, imgp);
255 else
256 suword(--stack_base, imgp->argc);
257
258 /*
259 * For security and other reasons, the file descriptor table cannot
260 * be shared after an exec.
261 */
262 if (p->p_fd->fd_refcnt > 1) {
263 struct filedesc *tmp;
264
265 tmp = fdcopy(p);
266 fdfree(p);
267 p->p_fd = tmp;
268 }
269
270 /* close files on exec */
271 fdcloseexec(p);
272
273 /* reset caught signals */
274 execsigs(p);
275
276 /* name this process - nameiexec(p, ndp) */
277 len = min(ndp->ni_cnd.cn_namelen,MAXCOMLEN);
278 bcopy(ndp->ni_cnd.cn_nameptr, p->p_comm, len);
279 p->p_comm[len] = 0;
280
281 /*
282 * mark as execed, wakeup the process that vforked (if any) and tell
283 * it that it now has it's own resources back
284 */
285 p->p_flag |= P_EXEC;
286 if (p->p_pptr && (p->p_flag & P_PPWAIT)) {
287 p->p_flag &= ~P_PPWAIT;
288 wakeup((caddr_t)p->p_pptr);
289 }
290
291 /*
292 * Implement image setuid/setgid.
293 *
294 * Don't honor setuid/setgid if the filesystem prohibits it or if
295 * the process is being traced.
296 */
297 if ((attr.va_mode & VSUID && p->p_ucred->cr_uid != attr.va_uid ||
298 attr.va_mode & VSGID && p->p_ucred->cr_gid != attr.va_gid) &&
299 (imgp->vp->v_mount->mnt_flag & MNT_NOSUID) == 0 &&
300 (p->p_flag & P_TRACED) == 0) {
301 /*
302 * Turn off syscall tracing for set-id programs, except for
303 * root.
304 */
305 if (p->p_tracep && suser(p->p_ucred, &p->p_acflag)) {
306 p->p_traceflag = 0;
307 vrele(p->p_tracep);
308 p->p_tracep = NULL;
309 }
310 /*
311 * Set the new credentials.
312 */
313 p->p_ucred = crcopy(p->p_ucred);
314 if (attr.va_mode & VSUID)
315 p->p_ucred->cr_uid = attr.va_uid;
316 if (attr.va_mode & VSGID)
317 p->p_ucred->cr_gid = attr.va_gid;
318 setsugid(p);
319 } else {
320 if (p->p_ucred->cr_uid == p->p_cred->p_ruid &&
321 p->p_ucred->cr_gid == p->p_cred->p_rgid)
322 p->p_flag &= ~P_SUGID;
323 }
324
325 /*
326 * Implement correct POSIX saved-id behavior.
327 */
328 p->p_cred->p_svuid = p->p_ucred->cr_uid;
329 p->p_cred->p_svgid = p->p_ucred->cr_gid;
330
331 /*
332 * Store the vp for use in procfs
333 */
334 if (p->p_textvp) /* release old reference */
335 vrele(p->p_textvp);
336 VREF(ndp->ni_vp);
337 p->p_textvp = ndp->ni_vp;
338
339 /*
340 * If tracing the process, trap to debugger so breakpoints
341 * can be set before the program executes.
342 */
343 STOPEVENT(p, S_EXEC, 0);
344
345 if (p->p_flag & P_TRACED)
346 psignal(p, SIGTRAP);
347
348 /* clear "fork but no exec" flag, as we _are_ execing */
349 p->p_acflag &= ~AFORK;
350
351 /* Set entry address */
352 setregs(p, imgp->entry_addr, (u_long)stack_base);
353
197 /* free old vnode and name buffer */
198 vrele(ndp->ni_vp);
199 zfree(namei_zone, ndp->ni_cnd.cn_pnbuf);
200 /* set new name to that of the interpreter */
201 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME,
202 UIO_SYSSPACE, imgp->interpreter_name, p);
203 goto interpret;
204 }
205 break;
206 }
207 /* If we made it through all the activators and none matched, exit. */
208 if (error == -1) {
209 error = ENOEXEC;
210 goto exec_fail_dealloc;
211 }
212
213 /*
214 * Copy out strings (args and env) and initialize stack base
215 */
216 stack_base = exec_copyout_strings(imgp);
217 p->p_vmspace->vm_minsaddr = (char *)stack_base;
218
219 /*
220 * If custom stack fixup routine present for this process
221 * let it do the stack setup.
222 * Else stuff argument count as first item on stack
223 */
224 if (p->p_sysent->sv_fixup)
225 (*p->p_sysent->sv_fixup)(&stack_base, imgp);
226 else
227 suword(--stack_base, imgp->argc);
228
229 /*
230 * For security and other reasons, the file descriptor table cannot
231 * be shared after an exec.
232 */
233 if (p->p_fd->fd_refcnt > 1) {
234 struct filedesc *tmp;
235
236 tmp = fdcopy(p);
237 fdfree(p);
238 p->p_fd = tmp;
239 }
240
241 /* close files on exec */
242 fdcloseexec(p);
243
244 /* reset caught signals */
245 execsigs(p);
246
247 /* name this process - nameiexec(p, ndp) */
248 len = min(ndp->ni_cnd.cn_namelen,MAXCOMLEN);
249 bcopy(ndp->ni_cnd.cn_nameptr, p->p_comm, len);
250 p->p_comm[len] = 0;
251
252 /*
253 * mark as execed, wakeup the process that vforked (if any) and tell
254 * it that it now has it's own resources back
255 */
256 p->p_flag |= P_EXEC;
257 if (p->p_pptr && (p->p_flag & P_PPWAIT)) {
258 p->p_flag &= ~P_PPWAIT;
259 wakeup((caddr_t)p->p_pptr);
260 }
261
262 /*
263 * Implement image setuid/setgid.
264 *
265 * Don't honor setuid/setgid if the filesystem prohibits it or if
266 * the process is being traced.
267 */
268 if ((attr.va_mode & VSUID && p->p_ucred->cr_uid != attr.va_uid ||
269 attr.va_mode & VSGID && p->p_ucred->cr_gid != attr.va_gid) &&
270 (imgp->vp->v_mount->mnt_flag & MNT_NOSUID) == 0 &&
271 (p->p_flag & P_TRACED) == 0) {
272 /*
273 * Turn off syscall tracing for set-id programs, except for
274 * root.
275 */
276 if (p->p_tracep && suser(p->p_ucred, &p->p_acflag)) {
277 p->p_traceflag = 0;
278 vrele(p->p_tracep);
279 p->p_tracep = NULL;
280 }
281 /*
282 * Set the new credentials.
283 */
284 p->p_ucred = crcopy(p->p_ucred);
285 if (attr.va_mode & VSUID)
286 p->p_ucred->cr_uid = attr.va_uid;
287 if (attr.va_mode & VSGID)
288 p->p_ucred->cr_gid = attr.va_gid;
289 setsugid(p);
290 } else {
291 if (p->p_ucred->cr_uid == p->p_cred->p_ruid &&
292 p->p_ucred->cr_gid == p->p_cred->p_rgid)
293 p->p_flag &= ~P_SUGID;
294 }
295
296 /*
297 * Implement correct POSIX saved-id behavior.
298 */
299 p->p_cred->p_svuid = p->p_ucred->cr_uid;
300 p->p_cred->p_svgid = p->p_ucred->cr_gid;
301
302 /*
303 * Store the vp for use in procfs
304 */
305 if (p->p_textvp) /* release old reference */
306 vrele(p->p_textvp);
307 VREF(ndp->ni_vp);
308 p->p_textvp = ndp->ni_vp;
309
310 /*
311 * If tracing the process, trap to debugger so breakpoints
312 * can be set before the program executes.
313 */
314 STOPEVENT(p, S_EXEC, 0);
315
316 if (p->p_flag & P_TRACED)
317 psignal(p, SIGTRAP);
318
319 /* clear "fork but no exec" flag, as we _are_ execing */
320 p->p_acflag &= ~AFORK;
321
322 /* Set entry address */
323 setregs(p, imgp->entry_addr, (u_long)stack_base);
324
325exec_fail_dealloc:
326
354 /*
355 * free various allocated resources
356 */
327 /*
328 * free various allocated resources
329 */
357 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, ARG_MAX);
358 if (bp != NULL)
359 brelse(bp);
360 else if (imgp->image_header != NULL)
361 free((void *)imgp->image_header, M_TEMP);
362 vrele(ndp->ni_vp);
363 zfree(namei_zone, ndp->ni_cnd.cn_pnbuf);
330 if (imgp->firstpage)
331 exec_unmap_first_page(imgp);
364
332
365 return (0);
366
367exec_fail_dealloc:
368 if (imgp->stringbase != NULL)
333 if (imgp->stringbase != NULL)
369 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, ARG_MAX);
370 if (bp != NULL)
371 brelse(bp);
372 else if (imgp->image_header != NULL)
373 free((void *)imgp->image_header, M_TEMP);
334 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase,
335 ARG_MAX + PAGE_SIZE);
336
374 if (ndp->ni_vp) {
375 vrele(ndp->ni_vp);
376 zfree(namei_zone, ndp->ni_cnd.cn_pnbuf);
377 }
378
337 if (ndp->ni_vp) {
338 vrele(ndp->ni_vp);
339 zfree(namei_zone, ndp->ni_cnd.cn_pnbuf);
340 }
341
342 if (error == 0)
343 return (0);
344
379exec_fail:
380 if (imgp->vmspace_destroyed) {
381 /* sorry, no more process anymore. exit gracefully */
382 exit1(p, W_EXITCODE(0, SIGABRT));
383 /* NOT REACHED */
384 return(0);
385 } else {
386 return(error);
387 }
388}
389
345exec_fail:
346 if (imgp->vmspace_destroyed) {
347 /* sorry, no more process anymore. exit gracefully */
348 exit1(p, W_EXITCODE(0, SIGABRT));
349 /* NOT REACHED */
350 return(0);
351 } else {
352 return(error);
353 }
354}
355
356int
357exec_map_first_page(imgp)
358 struct image_params *imgp;
359{
360 int s;
361 vm_page_t m;
362 vm_object_t object;
363
364
365 if (imgp->firstpage) {
366 exec_unmap_first_page(imgp);
367 }
368
369 object = imgp->vp->v_object;
370 s = splvm();
371
372retry:
373 m = vm_page_lookup(object, 0);
374 if (m == NULL) {
375 m = vm_page_alloc(object, 0, VM_ALLOC_NORMAL);
376 if (m == NULL) {
377 VM_WAIT;
378 goto retry;
379 }
380 } else if ((m->flags & PG_BUSY) || m->busy) {
381 m->flags |= PG_WANTED;
382 tsleep(m, PVM, "execpw", 0);
383 goto retry;
384 }
385
386 m->flags |= PG_BUSY;
387
388 if ((m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL) {
389 int rv;
390 rv = vm_pager_get_pages(object, &m, 1, 0);
391 if (rv != VM_PAGER_OK) {
392 vm_page_protect(m, VM_PROT_NONE);
393 vm_page_deactivate(m);
394 PAGE_WAKEUP(m);
395 splx(s);
396 return EIO;
397 }
398 }
399
400 vm_page_wire(m);
401 PAGE_WAKEUP(m);
402 splx(s);
403
404 pmap_kenter((vm_offset_t) imgp->image_header, VM_PAGE_TO_PHYS(m));
405 imgp->firstpage = m;
406
407 return 0;
408}
409
410void
411exec_unmap_first_page(imgp)
412 struct image_params *imgp;
413{
414 if (imgp->firstpage) {
415 pmap_kremove((vm_offset_t) imgp->image_header);
416 vm_page_unwire(imgp->firstpage);
417 imgp->firstpage = NULL;
418 }
419}
420
390/*
391 * Destroy old address space, and allocate a new stack
392 * The new stack is only SGROWSIZ large because it is grown
393 * automatically in trap.c.
394 */
395int
396exec_new_vmspace(imgp)
397 struct image_params *imgp;
398{
399 int error;
400 struct vmspace *vmspace = imgp->proc->p_vmspace;
401 caddr_t stack_addr = (caddr_t) (USRSTACK - SGROWSIZ);
402 vm_map_t map = &vmspace->vm_map;
403
404 imgp->vmspace_destroyed = 1;
405
406 /*
407 * Blow away entire process VM, if address space not shared,
408 * otherwise, create a new VM space so that other threads are
409 * not disrupted
410 */
411 if (vmspace->vm_refcnt == 1) {
412 if (vmspace->vm_shm)
413 shmexit(imgp->proc);
414 pmap_remove_pages(&vmspace->vm_pmap, 0, USRSTACK);
415 vm_map_remove(map, 0, USRSTACK);
416 } else {
417 vmspace_exec(imgp->proc);
418 vmspace = imgp->proc->p_vmspace;
419 map = &vmspace->vm_map;
420 }
421
422 /* Allocate a new stack */
421/*
422 * Destroy old address space, and allocate a new stack
423 * The new stack is only SGROWSIZ large because it is grown
424 * automatically in trap.c.
425 */
426int
427exec_new_vmspace(imgp)
428 struct image_params *imgp;
429{
430 int error;
431 struct vmspace *vmspace = imgp->proc->p_vmspace;
432 caddr_t stack_addr = (caddr_t) (USRSTACK - SGROWSIZ);
433 vm_map_t map = &vmspace->vm_map;
434
435 imgp->vmspace_destroyed = 1;
436
437 /*
438 * Blow away entire process VM, if address space not shared,
439 * otherwise, create a new VM space so that other threads are
440 * not disrupted
441 */
442 if (vmspace->vm_refcnt == 1) {
443 if (vmspace->vm_shm)
444 shmexit(imgp->proc);
445 pmap_remove_pages(&vmspace->vm_pmap, 0, USRSTACK);
446 vm_map_remove(map, 0, USRSTACK);
447 } else {
448 vmspace_exec(imgp->proc);
449 vmspace = imgp->proc->p_vmspace;
450 map = &vmspace->vm_map;
451 }
452
453 /* Allocate a new stack */
423 error = vm_map_find(map, NULL, 0, (vm_offset_t *)&stack_addr,
424 SGROWSIZ, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0);
454 error = vm_map_insert(&vmspace->vm_map, NULL, 0,
455 (vm_offset_t) stack_addr, (vm_offset_t) USRSTACK,
456 VM_PROT_ALL, VM_PROT_ALL, 0);
425 if (error)
457 if (error)
426 return(error);
458 return (error);
427
428 vmspace->vm_ssize = SGROWSIZ >> PAGE_SHIFT;
429
430 /* Initialize maximum stack address */
431 vmspace->vm_maxsaddr = (char *)USRSTACK - MAXSSIZ;
432
433 return(0);
434}
435
436/*
437 * Copy out argument and environment strings from the old process
438 * address space into the temporary string buffer.
439 */
440int
441exec_extract_strings(imgp)
442 struct image_params *imgp;
443{
444 char **argv, **envv;
445 char *argp, *envp;
446 int error, length;
447
448 /*
449 * extract arguments first
450 */
451
452 argv = imgp->uap->argv;
453
454 if (argv) {
455 argp = (caddr_t) fuword(argv);
456 if (argp == (caddr_t) -1)
457 return (EFAULT);
458 if (argp)
459 argv++;
460 if (imgp->argv0)
461 argp = imgp->argv0;
462 if (argp) {
463 do {
464 if (argp == (caddr_t) -1)
465 return (EFAULT);
466 if ((error = copyinstr(argp, imgp->stringp,
467 imgp->stringspace, &length))) {
468 if (error == ENAMETOOLONG)
469 return(E2BIG);
470 return (error);
471 }
472 imgp->stringspace -= length;
473 imgp->stringp += length;
474 imgp->argc++;
475 } while ((argp = (caddr_t) fuword(argv++)));
476 }
477 }
478
479 /*
480 * extract environment strings
481 */
482
483 envv = imgp->uap->envv;
484
485 if (envv) {
486 while ((envp = (caddr_t) fuword(envv++))) {
487 if (envp == (caddr_t) -1)
488 return (EFAULT);
489 if ((error = copyinstr(envp, imgp->stringp,
490 imgp->stringspace, &length))) {
491 if (error == ENAMETOOLONG)
492 return(E2BIG);
493 return (error);
494 }
495 imgp->stringspace -= length;
496 imgp->stringp += length;
497 imgp->envc++;
498 }
499 }
500
501 return (0);
502}
503
504/*
505 * Copy strings out to the new process address space, constructing
506 * new arg and env vector tables. Return a pointer to the base
507 * so that it can be used as the initial stack pointer.
508 */
509int *
510exec_copyout_strings(imgp)
511 struct image_params *imgp;
512{
513 int argc, envc;
514 char **vectp;
515 char *stringp, *destp;
516 int *stack_base;
517 struct ps_strings *arginfo;
518 int szsigcode;
519
520 /*
521 * Calculate string base and vector table pointers.
522 * Also deal with signal trampoline code for this exec type.
523 */
524 arginfo = PS_STRINGS;
525 szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
526 destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
527 roundup((ARG_MAX - imgp->stringspace), sizeof(char *));
528
529 /*
530 * install sigcode
531 */
532 if (szsigcode)
533 copyout(imgp->proc->p_sysent->sv_sigcode,
534 ((caddr_t)arginfo - szsigcode), szsigcode);
535
536 /*
537 * If we have a valid auxargs ptr, prepare some room
538 * on the stack.
539 */
540 if (imgp->auxargs)
541 /*
542 * The '+ 2' is for the null pointers at the end of each of the
543 * arg and env vector sets, and 'AT_COUNT*2' is room for the
544 * ELF Auxargs data.
545 */
546 vectp = (char **)(destp - (imgp->argc + imgp->envc + 2 +
547 AT_COUNT*2) * sizeof(char*));
548 else
549 /*
550 * The '+ 2' is for the null pointers at the end of each of the
551 * arg and env vector sets
552 */
553 vectp = (char **)
554 (destp - (imgp->argc + imgp->envc + 2) * sizeof(char*));
555
556 /*
557 * vectp also becomes our initial stack base
558 */
559 stack_base = (int *)vectp;
560
561 stringp = imgp->stringbase;
562 argc = imgp->argc;
563 envc = imgp->envc;
564
565 /*
566 * Copy out strings - arguments and environment.
567 */
568 copyout(stringp, destp, ARG_MAX - imgp->stringspace);
569
570 /*
571 * Fill in "ps_strings" struct for ps, w, etc.
572 */
573 suword(&arginfo->ps_argvstr, (int)vectp);
574 suword(&arginfo->ps_nargvstr, argc);
575
576 /*
577 * Fill in argument portion of vector table.
578 */
579 for (; argc > 0; --argc) {
580 suword(vectp++, (int)destp);
581 while (*stringp++ != 0)
582 destp++;
583 destp++;
584 }
585
586 /* a null vector table pointer seperates the argp's from the envp's */
587 suword(vectp++, 0);
588
589 suword(&arginfo->ps_envstr, (int)vectp);
590 suword(&arginfo->ps_nenvstr, envc);
591
592 /*
593 * Fill in environment portion of vector table.
594 */
595 for (; envc > 0; --envc) {
596 suword(vectp++, (int)destp);
597 while (*stringp++ != 0)
598 destp++;
599 destp++;
600 }
601
602 /* end of vector table is a null pointer */
603 suword(vectp, 0);
604
605 return (stack_base);
606}
607
608/*
609 * Check permissions of file to execute.
610 * Return 0 for success or error code on failure.
611 */
612static int
613exec_check_permissions(imgp)
614 struct image_params *imgp;
615{
616 struct proc *p = imgp->proc;
617 struct vnode *vp = imgp->vp;
618 struct vattr *attr = imgp->attr;
619 int error;
620
621 /* Get file attributes */
622 error = VOP_GETATTR(vp, attr, p->p_ucred, p);
623 if (error)
624 return (error);
625
626 /*
627 * 1) Check if file execution is disabled for the filesystem that this
628 * file resides on.
629 * 2) Insure that at least one execute bit is on - otherwise root
630 * will always succeed, and we don't want to happen unless the
631 * file really is executable.
632 * 3) Insure that the file is a regular file.
633 */
634 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) ||
635 ((attr->va_mode & 0111) == 0) ||
636 (attr->va_type != VREG)) {
637 return (EACCES);
638 }
639
640 /*
641 * Zero length files can't be exec'd
642 */
643 if (attr->va_size == 0)
644 return (ENOEXEC);
645
646 /*
647 * Check for execute permission to file based on current credentials.
648 */
649 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
650 if (error)
651 return (error);
652
653 /*
654 * Check number of open-for-writes on the file and deny execution
655 * if there are any.
656 */
657 if (vp->v_writecount)
658 return (ETXTBSY);
659
660 /*
661 * Call filesystem specific open routine (which does nothing in the
662 * general case).
663 */
664 error = VOP_OPEN(vp, FREAD, p->p_ucred, p);
665 if (error)
666 return (error);
667
668 return (0);
669}
459
460 vmspace->vm_ssize = SGROWSIZ >> PAGE_SHIFT;
461
462 /* Initialize maximum stack address */
463 vmspace->vm_maxsaddr = (char *)USRSTACK - MAXSSIZ;
464
465 return(0);
466}
467
468/*
469 * Copy out argument and environment strings from the old process
470 * address space into the temporary string buffer.
471 */
472int
473exec_extract_strings(imgp)
474 struct image_params *imgp;
475{
476 char **argv, **envv;
477 char *argp, *envp;
478 int error, length;
479
480 /*
481 * extract arguments first
482 */
483
484 argv = imgp->uap->argv;
485
486 if (argv) {
487 argp = (caddr_t) fuword(argv);
488 if (argp == (caddr_t) -1)
489 return (EFAULT);
490 if (argp)
491 argv++;
492 if (imgp->argv0)
493 argp = imgp->argv0;
494 if (argp) {
495 do {
496 if (argp == (caddr_t) -1)
497 return (EFAULT);
498 if ((error = copyinstr(argp, imgp->stringp,
499 imgp->stringspace, &length))) {
500 if (error == ENAMETOOLONG)
501 return(E2BIG);
502 return (error);
503 }
504 imgp->stringspace -= length;
505 imgp->stringp += length;
506 imgp->argc++;
507 } while ((argp = (caddr_t) fuword(argv++)));
508 }
509 }
510
511 /*
512 * extract environment strings
513 */
514
515 envv = imgp->uap->envv;
516
517 if (envv) {
518 while ((envp = (caddr_t) fuword(envv++))) {
519 if (envp == (caddr_t) -1)
520 return (EFAULT);
521 if ((error = copyinstr(envp, imgp->stringp,
522 imgp->stringspace, &length))) {
523 if (error == ENAMETOOLONG)
524 return(E2BIG);
525 return (error);
526 }
527 imgp->stringspace -= length;
528 imgp->stringp += length;
529 imgp->envc++;
530 }
531 }
532
533 return (0);
534}
535
536/*
537 * Copy strings out to the new process address space, constructing
538 * new arg and env vector tables. Return a pointer to the base
539 * so that it can be used as the initial stack pointer.
540 */
541int *
542exec_copyout_strings(imgp)
543 struct image_params *imgp;
544{
545 int argc, envc;
546 char **vectp;
547 char *stringp, *destp;
548 int *stack_base;
549 struct ps_strings *arginfo;
550 int szsigcode;
551
552 /*
553 * Calculate string base and vector table pointers.
554 * Also deal with signal trampoline code for this exec type.
555 */
556 arginfo = PS_STRINGS;
557 szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
558 destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
559 roundup((ARG_MAX - imgp->stringspace), sizeof(char *));
560
561 /*
562 * install sigcode
563 */
564 if (szsigcode)
565 copyout(imgp->proc->p_sysent->sv_sigcode,
566 ((caddr_t)arginfo - szsigcode), szsigcode);
567
568 /*
569 * If we have a valid auxargs ptr, prepare some room
570 * on the stack.
571 */
572 if (imgp->auxargs)
573 /*
574 * The '+ 2' is for the null pointers at the end of each of the
575 * arg and env vector sets, and 'AT_COUNT*2' is room for the
576 * ELF Auxargs data.
577 */
578 vectp = (char **)(destp - (imgp->argc + imgp->envc + 2 +
579 AT_COUNT*2) * sizeof(char*));
580 else
581 /*
582 * The '+ 2' is for the null pointers at the end of each of the
583 * arg and env vector sets
584 */
585 vectp = (char **)
586 (destp - (imgp->argc + imgp->envc + 2) * sizeof(char*));
587
588 /*
589 * vectp also becomes our initial stack base
590 */
591 stack_base = (int *)vectp;
592
593 stringp = imgp->stringbase;
594 argc = imgp->argc;
595 envc = imgp->envc;
596
597 /*
598 * Copy out strings - arguments and environment.
599 */
600 copyout(stringp, destp, ARG_MAX - imgp->stringspace);
601
602 /*
603 * Fill in "ps_strings" struct for ps, w, etc.
604 */
605 suword(&arginfo->ps_argvstr, (int)vectp);
606 suword(&arginfo->ps_nargvstr, argc);
607
608 /*
609 * Fill in argument portion of vector table.
610 */
611 for (; argc > 0; --argc) {
612 suword(vectp++, (int)destp);
613 while (*stringp++ != 0)
614 destp++;
615 destp++;
616 }
617
618 /* a null vector table pointer seperates the argp's from the envp's */
619 suword(vectp++, 0);
620
621 suword(&arginfo->ps_envstr, (int)vectp);
622 suword(&arginfo->ps_nenvstr, envc);
623
624 /*
625 * Fill in environment portion of vector table.
626 */
627 for (; envc > 0; --envc) {
628 suword(vectp++, (int)destp);
629 while (*stringp++ != 0)
630 destp++;
631 destp++;
632 }
633
634 /* end of vector table is a null pointer */
635 suword(vectp, 0);
636
637 return (stack_base);
638}
639
640/*
641 * Check permissions of file to execute.
642 * Return 0 for success or error code on failure.
643 */
644static int
645exec_check_permissions(imgp)
646 struct image_params *imgp;
647{
648 struct proc *p = imgp->proc;
649 struct vnode *vp = imgp->vp;
650 struct vattr *attr = imgp->attr;
651 int error;
652
653 /* Get file attributes */
654 error = VOP_GETATTR(vp, attr, p->p_ucred, p);
655 if (error)
656 return (error);
657
658 /*
659 * 1) Check if file execution is disabled for the filesystem that this
660 * file resides on.
661 * 2) Insure that at least one execute bit is on - otherwise root
662 * will always succeed, and we don't want to happen unless the
663 * file really is executable.
664 * 3) Insure that the file is a regular file.
665 */
666 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) ||
667 ((attr->va_mode & 0111) == 0) ||
668 (attr->va_type != VREG)) {
669 return (EACCES);
670 }
671
672 /*
673 * Zero length files can't be exec'd
674 */
675 if (attr->va_size == 0)
676 return (ENOEXEC);
677
678 /*
679 * Check for execute permission to file based on current credentials.
680 */
681 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
682 if (error)
683 return (error);
684
685 /*
686 * Check number of open-for-writes on the file and deny execution
687 * if there are any.
688 */
689 if (vp->v_writecount)
690 return (ETXTBSY);
691
692 /*
693 * Call filesystem specific open routine (which does nothing in the
694 * general case).
695 */
696 error = VOP_OPEN(vp, FREAD, p->p_ucred, p);
697 if (error)
698 return (error);
699
700 return (0);
701}