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 unchanged lines hidden (view full) --- 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 unchanged lines hidden (view full) --- 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> --- 14 unchanged lines hidden (view full) --- 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> --- 14 unchanged lines hidden (view full) --- 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 --- 33 unchanged lines hidden (view full) --- 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 --- 33 unchanged lines hidden (view full) --- 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, --- 6 unchanged lines hidden (view full) --- 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, --- 6 unchanged lines hidden (view full) --- 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 } --- 112 unchanged lines hidden (view full) --- 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 } --- 112 unchanged lines hidden (view full) --- 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; --- 17 unchanged lines hidden (view full) --- 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; --- 17 unchanged lines hidden (view full) --- 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} --- 235 unchanged lines hidden --- | 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} --- 235 unchanged lines hidden --- |