diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_exec.c | 27 | ||||
-rw-r--r-- | sys/kern/kern_prot.c | 20 |
2 files changed, 20 insertions, 27 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index f57de2b5d91..cfe0e18af44 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.50 2001/06/18 13:28:41 art Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.51 2001/06/19 07:54:36 deraadt Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -129,10 +129,19 @@ check_exec(p, epp) error = EACCES; goto bad1; } - - if ((vp->v_mount->mnt_flag & MNT_NOSUID)) + if ((vp->v_mount->mnt_flag & MNT_NOSUID) || + (p->p_flag & P_TRACED) || p->p_fd->fd_refcnt > 1) epp->ep_vap->va_mode &= ~(VSUID | VSGID); + /* + * Set the P_SUID* flags early so that we won't be fiddled with when + * we sleep later in this code. + * XXX - this could give us a few false positives and the caller must + * make sure to save and restore the flags if exec fails. + */ + if (epp->ep_vap->va_mode & (VSUID|VSGID)) + p->p_flag |= P_SUGID|P_SUGIDEXEC; + /* check access. for root we have to see if any exec bit on */ if ((error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) != 0) goto bad1; @@ -244,6 +253,7 @@ sys_execve(p, v, retval) char **tmpfap; int szsigcode; extern struct emul emul_native; + int saved_sugid; /* * figure out the maximum size of an exec header, if necessary. @@ -274,6 +284,7 @@ sys_execve(p, v, retval) pack.ep_emul = &emul_native; pack.ep_flags = 0; + saved_sugid = p->p_flag & (P_SUGID|P_SUGIDEXEC); /* see if we can run it. */ if ((error = check_exec(p, &pack)) != 0) { goto freehdr; @@ -485,14 +496,11 @@ sys_execve(p, v, retval) /* * deal with set[ug]id. - * MNT_NOEXEC has already been used to disable s[ug]id. + * MNT_NOEXEC and P_TRACED have already been used to disable s[ug]id. */ - if ((attr.va_mode & (VSUID | VSGID)) && proc_cansugid(p)) { + if ((attr.va_mode & (VSUID | VSGID))) { int i; - p->p_flag |= P_SUGID; - p->p_flag |= P_SUGIDEXEC; - #ifdef KTRACE /* * If process is being ktraced, turn off - unless @@ -508,6 +516,8 @@ sys_execve(p, v, retval) p->p_ucred->cr_uid = attr.va_uid; if (attr.va_mode & VSGID) p->p_ucred->cr_gid = attr.va_gid; + p->p_flag |= P_SUGID; + p->p_flag |= P_SUGIDEXEC; /* * For set[ug]id processes, a few caveats apply to @@ -647,6 +657,7 @@ bad: freehdr: free(pack.ep_hdr, M_EXEC); + p->p_flag = (p->p_flag & ~(P_SUGID|P_SUGIDEXEC)) | saved_sugid; return (error); exec_abort: diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 6eb98c91f4c..7a86e67f46b 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_prot.c,v 1.15 2001/06/18 13:18:36 art Exp $ */ +/* $OpenBSD: kern_prot.c,v 1.16 2001/06/19 07:54:37 deraadt Exp $ */ /* $NetBSD: kern_prot.c,v 1.33 1996/02/09 18:59:42 christos Exp $ */ /* @@ -53,7 +53,6 @@ #include <sys/timeb.h> #include <sys/times.h> #include <sys/malloc.h> -#include <sys/filedesc.h> #include <sys/mount.h> #include <sys/syscallargs.h> @@ -656,20 +655,3 @@ sys_setlogin(p, v, retval) error = EINVAL; return (error); } - -/* - * Check if a process is allowed to raise its privileges. - */ -int -proc_cansugid(struct proc *p) -{ - /* ptrace(2)d processes shouldn't. */ - if ((p->p_flag & P_TRACED) != 0) - return (EPERM); - - /* proceses with shared filedescriptors shouldn't. */ - if (p->p_fd->fd_refcnt > 1) - return (EPERM); - - return (0); -} |