kern_sharedpage.c (106459) | kern_sharedpage.c (106468) |
---|---|
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 * $FreeBSD: head/sys/kern/kern_exec.c 106459 2002-11-05 14:57:49Z rwatson $ | 26 * $FreeBSD: head/sys/kern/kern_exec.c 106468 2002-11-05 17:51:56Z rwatson $ |
27 */ 28 29#include "opt_ktrace.h" 30#include "opt_mac.h" 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/lock.h> --- 37 unchanged lines hidden (view full) --- 72 73MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments"); 74 75static MALLOC_DEFINE(M_ATEXEC, "atexec", "atexec callback"); 76 77static int sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS); 78static int sysctl_kern_usrstack(SYSCTL_HANDLER_ARGS); 79static int kern_execve(struct thread *td, char *fname, char **argv, | 27 */ 28 29#include "opt_ktrace.h" 30#include "opt_mac.h" 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/lock.h> --- 37 unchanged lines hidden (view full) --- 72 73MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments"); 74 75static MALLOC_DEFINE(M_ATEXEC, "atexec", "atexec callback"); 76 77static int sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS); 78static int sysctl_kern_usrstack(SYSCTL_HANDLER_ARGS); 79static int kern_execve(struct thread *td, char *fname, char **argv, |
80 char **envv); | 80 char **envv, struct mac *mac_p); |
81 82/* 83 * callout list for things to do at exec time 84 */ 85struct execlist { 86 execlist_fn function; 87 TAILQ_ENTRY(execlist) next; 88}; --- 50 unchanged lines hidden (view full) --- 139 140/* 141 * In-kernel implementation of execve(). All arguments are assumed to be 142 * userspace pointers from the passed thread. 143 * 144 * MPSAFE 145 */ 146static int | 81 82/* 83 * callout list for things to do at exec time 84 */ 85struct execlist { 86 execlist_fn function; 87 TAILQ_ENTRY(execlist) next; 88}; --- 50 unchanged lines hidden (view full) --- 139 140/* 141 * In-kernel implementation of execve(). All arguments are assumed to be 142 * userspace pointers from the passed thread. 143 * 144 * MPSAFE 145 */ 146static int |
147kern_execve(td, fname, argv, envv) | 147kern_execve(td, fname, argv, envv, mac_p) |
148 struct thread *td; 149 char *fname; 150 char **argv; 151 char **envv; | 148 struct thread *td; 149 char *fname; 150 char **argv; 151 char **envv; |
152 struct mac *mac_p; |
|
152{ 153 struct proc *p = td->td_proc; 154 struct nameidata nd, *ndp; 155 struct ucred *newcred = NULL, *oldcred; 156 struct uidinfo *euip; 157 register_t *stack_base; 158 int error, len, i; 159 struct image_params image_params, *imgp; 160 struct vattr attr; 161 int (*img_first)(struct image_params *); 162 struct pargs *oldargs = NULL, *newargs = NULL; 163 struct procsig *oldprocsig, *newprocsig; 164#ifdef KTRACE 165 struct vnode *tracevp = NULL; 166#endif 167 struct vnode *textvp = NULL; 168 int credential_changing; 169 int textset; 170#ifdef MAC | 153{ 154 struct proc *p = td->td_proc; 155 struct nameidata nd, *ndp; 156 struct ucred *newcred = NULL, *oldcred; 157 struct uidinfo *euip; 158 register_t *stack_base; 159 int error, len, i; 160 struct image_params image_params, *imgp; 161 struct vattr attr; 162 int (*img_first)(struct image_params *); 163 struct pargs *oldargs = NULL, *newargs = NULL; 164 struct procsig *oldprocsig, *newprocsig; 165#ifdef KTRACE 166 struct vnode *tracevp = NULL; 167#endif 168 struct vnode *textvp = NULL; 169 int credential_changing; 170 int textset; 171#ifdef MAC |
171 int will_transition; | 172 struct label interplabel; /* label of the interpreted vnode */ 173 struct label execlabel; /* optional label argument */ 174 int will_transition, interplabelvalid = 0; |
172#endif 173 174 imgp = &image_params; 175 176 /* 177 * Lock the process and set the P_INEXEC flag to indicate that 178 * it should be left alone until we're done here. This is 179 * necessary to avoid race conditions - e.g. in ptrace() - --- 20 unchanged lines hidden (view full) --- 200 PROC_UNLOCK(p); 201 202 /* 203 * Initialize part of the common data 204 */ 205 imgp->proc = p; 206 imgp->userspace_argv = argv; 207 imgp->userspace_envv = envv; | 175#endif 176 177 imgp = &image_params; 178 179 /* 180 * Lock the process and set the P_INEXEC flag to indicate that 181 * it should be left alone until we're done here. This is 182 * necessary to avoid race conditions - e.g. in ptrace() - --- 20 unchanged lines hidden (view full) --- 203 PROC_UNLOCK(p); 204 205 /* 206 * Initialize part of the common data 207 */ 208 imgp->proc = p; 209 imgp->userspace_argv = argv; 210 imgp->userspace_envv = envv; |
211 imgp->execlabel = NULL; |
|
208 imgp->attr = &attr; 209 imgp->argc = imgp->envc = 0; 210 imgp->argv0 = NULL; 211 imgp->entry_addr = 0; 212 imgp->vmspace_destroyed = 0; 213 imgp->interpreted = 0; 214 imgp->interpreter_name[0] = '\0'; 215 imgp->auxargs = NULL; 216 imgp->vp = NULL; 217 imgp->object = NULL; 218 imgp->firstpage = NULL; 219 imgp->ps_strings = 0; 220 imgp->auxarg_size = 0; 221 | 212 imgp->attr = &attr; 213 imgp->argc = imgp->envc = 0; 214 imgp->argv0 = NULL; 215 imgp->entry_addr = 0; 216 imgp->vmspace_destroyed = 0; 217 imgp->interpreted = 0; 218 imgp->interpreter_name[0] = '\0'; 219 imgp->auxargs = NULL; 220 imgp->vp = NULL; 221 imgp->object = NULL; 222 imgp->firstpage = NULL; 223 imgp->ps_strings = 0; 224 imgp->auxarg_size = 0; 225 |
226#ifdef MAC 227 error = mac_execve_enter(imgp, mac_p, &execlabel); 228 if (error) { 229 mtx_lock(&Giant); 230 goto exec_fail; 231 } 232#endif 233 |
|
222 /* 223 * Allocate temporary demand zeroed space for argument and 224 * environment strings 225 */ 226 imgp->stringbase = (char *)kmem_alloc_wait(exec_map, ARG_MAX + 227 PAGE_SIZE); 228 if (imgp->stringbase == NULL) { 229 error = ENOMEM; --- 90 unchanged lines hidden (view full) --- 320 * VV_TEXT needs to be unset for scripts. There is a short 321 * period before we determine that something is a script where 322 * VV_TEXT will be set. The vnode lock is held over this 323 * entire period so nothing should illegitimately be blocked. 324 */ 325 imgp->vp->v_vflag &= ~VV_TEXT; 326 /* free name buffer and old vnode */ 327 NDFREE(ndp, NDF_ONLY_PNBUF); | 234 /* 235 * Allocate temporary demand zeroed space for argument and 236 * environment strings 237 */ 238 imgp->stringbase = (char *)kmem_alloc_wait(exec_map, ARG_MAX + 239 PAGE_SIZE); 240 if (imgp->stringbase == NULL) { 241 error = ENOMEM; --- 90 unchanged lines hidden (view full) --- 332 * VV_TEXT needs to be unset for scripts. There is a short 333 * period before we determine that something is a script where 334 * VV_TEXT will be set. The vnode lock is held over this 335 * entire period so nothing should illegitimately be blocked. 336 */ 337 imgp->vp->v_vflag &= ~VV_TEXT; 338 /* free name buffer and old vnode */ 339 NDFREE(ndp, NDF_ONLY_PNBUF); |
340#ifdef MAC 341 mac_init_vnode_label(&interplabel); 342 mac_copy_vnode_label(&ndp->ni_vp->v_label, &interplabel); 343 interplabelvalid = 1; 344#endif |
|
328 vput(ndp->ni_vp); 329 vm_object_deallocate(imgp->object); 330 imgp->object = NULL; 331 /* set new name to that of the interpreter */ 332 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME, 333 UIO_SYSSPACE, imgp->interpreter_name, td); 334 goto interpret; 335 } --- 91 unchanged lines hidden (view full) --- 427 wakeup(p->p_pptr); 428 } 429 430 /* 431 * Implement image setuid/setgid. 432 * 433 * Don't honor setuid/setgid if the filesystem prohibits it or if 434 * the process is being traced. | 345 vput(ndp->ni_vp); 346 vm_object_deallocate(imgp->object); 347 imgp->object = NULL; 348 /* set new name to that of the interpreter */ 349 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME, 350 UIO_SYSSPACE, imgp->interpreter_name, td); 351 goto interpret; 352 } --- 91 unchanged lines hidden (view full) --- 444 wakeup(p->p_pptr); 445 } 446 447 /* 448 * Implement image setuid/setgid. 449 * 450 * Don't honor setuid/setgid if the filesystem prohibits it or if 451 * the process is being traced. |
452 * 453 * XXXMAC: For the time being, use NOSUID to also prohibit 454 * transitions on the file system. |
|
435 */ 436 oldcred = p->p_ucred; 437 credential_changing = 0; 438 credential_changing |= (attr.va_mode & VSUID) && oldcred->cr_uid != 439 attr.va_uid; 440 credential_changing |= (attr.va_mode & VSGID) && oldcred->cr_gid != 441 attr.va_gid; 442#ifdef MAC | 455 */ 456 oldcred = p->p_ucred; 457 credential_changing = 0; 458 credential_changing |= (attr.va_mode & VSUID) && oldcred->cr_uid != 459 attr.va_uid; 460 credential_changing |= (attr.va_mode & VSGID) && oldcred->cr_gid != 461 attr.va_gid; 462#ifdef MAC |
443 will_transition = mac_execve_will_transition(oldcred, imgp->vp); | 463 will_transition = mac_execve_will_transition(oldcred, imgp->vp, 464 interplabelvalid ? &interplabel : NULL, imgp); |
444 credential_changing |= will_transition; 445#endif 446 447 if (credential_changing && 448 (imgp->vp->v_mount->mnt_flag & MNT_NOSUID) == 0 && 449 (p->p_flag & P_TRACED) == 0) { 450 /* 451 * Turn off syscall tracing for set-id programs, except for --- 29 unchanged lines hidden (view full) --- 481 * Set the new credentials. 482 */ 483 crcopy(newcred, oldcred); 484 if (attr.va_mode & VSUID) 485 change_euid(newcred, euip); 486 if (attr.va_mode & VSGID) 487 change_egid(newcred, attr.va_gid); 488#ifdef MAC | 465 credential_changing |= will_transition; 466#endif 467 468 if (credential_changing && 469 (imgp->vp->v_mount->mnt_flag & MNT_NOSUID) == 0 && 470 (p->p_flag & P_TRACED) == 0) { 471 /* 472 * Turn off syscall tracing for set-id programs, except for --- 29 unchanged lines hidden (view full) --- 502 * Set the new credentials. 503 */ 504 crcopy(newcred, oldcred); 505 if (attr.va_mode & VSUID) 506 change_euid(newcred, euip); 507 if (attr.va_mode & VSGID) 508 change_egid(newcred, attr.va_gid); 509#ifdef MAC |
489 if (will_transition) 490 mac_execve_transition(oldcred, newcred, imgp->vp); | 510 if (will_transition) { 511 mac_execve_transition(oldcred, newcred, imgp->vp, 512 interplabelvalid ? &interplabel : NULL, imgp); 513 } |
491#endif 492 /* 493 * Implement correct POSIX saved-id behavior. 494 * 495 * XXXMAC: Note that the current logic will save the 496 * uid and gid if a MAC domain transition occurs, even 497 * though maybe it shouldn't. 498 */ --- 124 unchanged lines hidden (view full) --- 623exec_fail: 624 /* we're done here, clear P_INEXEC */ 625 PROC_LOCK(p); 626 p->p_flag &= ~P_INEXEC; 627 PROC_UNLOCK(p); 628 629 if (imgp->vmspace_destroyed) { 630 /* sorry, no more process anymore. exit gracefully */ | 514#endif 515 /* 516 * Implement correct POSIX saved-id behavior. 517 * 518 * XXXMAC: Note that the current logic will save the 519 * uid and gid if a MAC domain transition occurs, even 520 * though maybe it shouldn't. 521 */ --- 124 unchanged lines hidden (view full) --- 646exec_fail: 647 /* we're done here, clear P_INEXEC */ 648 PROC_LOCK(p); 649 p->p_flag &= ~P_INEXEC; 650 PROC_UNLOCK(p); 651 652 if (imgp->vmspace_destroyed) { 653 /* sorry, no more process anymore. exit gracefully */ |
654#ifdef MAC 655 mac_execve_exit(imgp); 656 if (interplabelvalid) 657 mac_destroy_vnode_label(&interplabel); 658#endif |
|
631 exit1(td, W_EXITCODE(0, SIGABRT)); 632 /* NOT REACHED */ 633 error = 0; 634 } 635done2: | 659 exit1(td, W_EXITCODE(0, SIGABRT)); 660 /* NOT REACHED */ 661 error = 0; 662 } 663done2: |
664#ifdef MAC 665 mac_execve_exit(imgp); 666 if (interplabelvalid) 667 mac_destroy_vnode_label(&interplabel); 668#endif |
|
636 mtx_unlock(&Giant); 637 return (error); 638} 639 640#ifndef _SYS_SYSPROTO_H_ 641struct execve_args { 642 char *fname; 643 char **argv; --- 9 unchanged lines hidden (view full) --- 653 struct thread *td; 654 struct execve_args /* { 655 syscallarg(char *) fname; 656 syscallarg(char **) argv; 657 syscallarg(char **) envv; 658 } */ *uap; 659{ 660 | 669 mtx_unlock(&Giant); 670 return (error); 671} 672 673#ifndef _SYS_SYSPROTO_H_ 674struct execve_args { 675 char *fname; 676 char **argv; --- 9 unchanged lines hidden (view full) --- 686 struct thread *td; 687 struct execve_args /* { 688 syscallarg(char *) fname; 689 syscallarg(char **) argv; 690 syscallarg(char **) envv; 691 } */ *uap; 692{ 693 |
661 return (kern_execve(td, uap->fname, uap->argv, uap->envv)); | 694#ifdef MAC 695 return (kern_execve(td, uap->fname, uap->argv, uap->envv, NULL)); 696#else 697 return (ENOSYS); 698#endif |
662} 663 | 699} 700 |
701#ifndef _SYS_SYSPROTO_H_ 702struct __mac_execve_args { 703 char *fname; 704 char **argv; 705 char **envv; 706 struct mac *mac_p; 707}; 708#endif 709 710/* 711 * MPSAFE 712 */ |
|
664int | 713int |
714__mac_execve(td, uap) 715 struct thread *td; 716 struct __mac_execve_args /* { 717 syscallarg(char *) fname; 718 syscallarg(char **) argv; 719 syscallarg(char **) envv; 720 syscallarg(struct mac *) mac_p; 721 } */ *uap; 722{ 723 724 return (kern_execve(td, uap->fname, uap->argv, uap->envv, 725 uap->mac_p)); 726} 727 728int |
|
665exec_map_first_page(imgp) 666 struct image_params *imgp; 667{ 668 int rv, i; 669 int initial_pagein; 670 vm_page_t ma[VM_INITIAL_PAGEIN]; 671 vm_object_t object; 672 --- 344 unchanged lines hidden (view full) --- 1017 struct vnode *vp = imgp->vp; 1018 struct vattr *attr = imgp->attr; 1019 struct thread *td; 1020 int error; 1021 1022 td = curthread; /* XXXKSE */ 1023 1024#ifdef MAC | 729exec_map_first_page(imgp) 730 struct image_params *imgp; 731{ 732 int rv, i; 733 int initial_pagein; 734 vm_page_t ma[VM_INITIAL_PAGEIN]; 735 vm_object_t object; 736 --- 344 unchanged lines hidden (view full) --- 1081 struct vnode *vp = imgp->vp; 1082 struct vattr *attr = imgp->attr; 1083 struct thread *td; 1084 int error; 1085 1086 td = curthread; /* XXXKSE */ 1087 1088#ifdef MAC |
1025 error = mac_check_vnode_exec(td->td_ucred, imgp->vp); | 1089 error = mac_check_vnode_exec(td->td_ucred, imgp->vp, imgp); |
1026 if (error) 1027 return (error); 1028#endif 1029 1030 /* Get file attributes */ 1031 error = VOP_GETATTR(vp, attr, td->td_ucred, td); 1032 if (error) 1033 return (error); --- 142 unchanged lines hidden --- | 1090 if (error) 1091 return (error); 1092#endif 1093 1094 /* Get file attributes */ 1095 error = VOP_GETATTR(vp, attr, td->td_ucred, td); 1096 if (error) 1097 return (error); --- 142 unchanged lines hidden --- |