Deleted Added
full compact
kern_exec.c (106459) kern_exec.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 ---