Implement 4.4's SUGID flag, which keeps track of processes which
authorGarrett Wollman <wollman@FreeBSD.org>
Tue, 15 Mar 1994 02:48:51 +0000 (02:48 +0000)
committerGarrett Wollman <wollman@FreeBSD.org>
Tue, 15 Mar 1994 02:48:51 +0000 (02:48 +0000)
call set*id() (reset on exec()).  Also, implement 4.4's logic for
setre[ug]id(), which is much simpler and closer to being the correct
behavior (given that we're stuck with setre[ug]id() for a variety of reasons).

sys/kern/kern_execve.c
sys/kern/kern_prot.c
sys/sys/proc.h

index d355d6f..6f68fe9 100644 (file)
@@ -19,7 +19,7 @@
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -28,7 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $Id: kern_execve.c,v 1.15 1994/02/04 06:58:11 wollman Exp $
+ *     $Id: kern_execve.c,v 1.16 1994/03/15 01:58:29 wollman Exp $
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -180,7 +180,7 @@ interpret:
                        (caddr_t)vnodep,                /* vnode */
                        0);                             /* offset */
        if (error) {
                        (caddr_t)vnodep,                /* vnode */
                        0);                             /* offset */
        if (error) {
-               printf("mmap failed: %d\n",error);
+               uprintf("mmap failed: %d\n",error);
                goto exec_fail_dealloc;
        }
        iparams->image_header = image_header;
                goto exec_fail_dealloc;
        }
        iparams->image_header = image_header;
@@ -296,6 +296,9 @@ interpret:
        /* clear "fork but no exec" flag, as we _are_ execing */
        p->p_acflag &= ~AFORK;
 
        /* clear "fork but no exec" flag, as we _are_ execing */
        p->p_acflag &= ~AFORK;
 
+       /* clear `set id since last exec' flag */
+       p->p_flag &= ~SUGID;
+
        /* Set entry address */
        setregs(p, iparams->entry_addr, stack_base);
 
        /* Set entry address */
        setregs(p, iparams->entry_addr, stack_base);
 
index d886dbb..e2ba54a 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *     from: @(#)kern_prot.c   7.21 (Berkeley) 5/3/91
  * SUCH DAMAGE.
  *
  *     from: @(#)kern_prot.c   7.21 (Berkeley) 5/3/91
- *     $Id: kern_prot.c,v 1.4 1993/11/25 01:33:04 wollman Exp $
+ *     $Id: kern_prot.c,v 1.5 1993/12/19 00:51:29 wollman Exp $
  */
 
 /*
  */
 
 /*
@@ -273,6 +273,7 @@ setuid(p, uap, retval)
        pc->pc_ucred->cr_uid = uid;
        pc->p_ruid = uid;
        pc->p_svuid = uid;
        pc->pc_ucred->cr_uid = uid;
        pc->p_ruid = uid;
        pc->p_svuid = uid;
+       p->p_flag |= SUGID;
        return (0);
 }
 
        return (0);
 }
 
@@ -301,6 +302,7 @@ seteuid(p, uap, retval)
         */
        pc->pc_ucred = crcopy(pc->pc_ucred);
        pc->pc_ucred->cr_uid = euid;
         */
        pc->pc_ucred = crcopy(pc->pc_ucred);
        pc->pc_ucred->cr_uid = euid;
+       p->p_flag |= SUGID;
        return (0);
 }
 
        return (0);
 }
 
@@ -325,7 +327,8 @@ setgid(p, uap, retval)
        pc->pc_ucred = crcopy(pc->pc_ucred);
        pc->pc_ucred->cr_groups[0] = gid;
        pc->p_rgid = gid;
        pc->pc_ucred = crcopy(pc->pc_ucred);
        pc->pc_ucred->cr_groups[0] = gid;
        pc->p_rgid = gid;
-       pc->p_svgid = gid;              /* ??? */
+       pc->p_svgid = gid;
+       p->p_flag |= SUGID;
        return (0);
 }
 
        return (0);
 }
 
@@ -350,6 +353,7 @@ setegid(p, uap, retval)
                return (error);
        pc->pc_ucred = crcopy(pc->pc_ucred);
        pc->pc_ucred->cr_groups[0] = egid;
                return (error);
        pc->pc_ucred = crcopy(pc->pc_ucred);
        pc->pc_ucred->cr_groups[0] = egid;
+       p->p_flag |= SUGID;
        return (0);
 }
 
        return (0);
 }
 
@@ -368,38 +372,30 @@ osetreuid(p, uap, retval)
        int *retval;
 {
        register struct pcred *pc = p->p_cred;
        int *retval;
 {
        register struct pcred *pc = p->p_cred;
-       register uid_t ruid, euid;
-       int error;
+       struct seteuid_args e_args;
 
 
-       if (uap->ruid == -1)
-               ruid = pc->p_ruid;
-       else
-               ruid = uap->ruid;
-       /*
-        * Allow setting real uid to previous effective, for swapping real and
-        * effective.  This should be:
-        *
-        * if (ruid != pc->p_ruid &&
-        *     (error = suser(pc->pc_ucred, &p->p_acflag)))
-        */
-       if (ruid != pc->p_ruid && ruid != pc->pc_ucred->cr_uid /* XXX */ &&
-           (error = suser(pc->pc_ucred, &p->p_acflag)))
-               return (error);
-       if (uap->euid == -1)
-               euid = pc->pc_ucred->cr_uid;
-       else
-               euid = uap->euid;
-       if (euid != pc->pc_ucred->cr_uid && euid != pc->p_ruid &&
-           euid != pc->p_svuid && (error = suser(pc->pc_ucred, &p->p_acflag)))
-               return (error);
        /*
        /*
-        * Everything's okay, do it.  Copy credentials so other references do
-        * not see our changes.
+        * Most calls to setreuid() are done in order to swap real and
+        * effective uids.  In old versions of BSD, this was the only
+        * way to temporarily renounce privileges and be able to get
+        * them back.  In the presence of the POSIX saved id, however,
+        * we can do this without modifying the real uid, which could have
+        * opened up a security hole.  So, we implement this: when the user
+        * attempts to set its real uid, we just check to make sure
+        * that they will be able to seteuid() back to that id at some
+        * later time, but don't actually change the real uid.
+        * Logic taken from 4.4BSD.
         */
         */
-       pc->pc_ucred = crcopy(pc->pc_ucred);
-       pc->pc_ucred->cr_uid = euid;
-       pc->p_ruid = ruid;
-       return (0);
+       if(uap->ruid != -1 && uap->ruid != pc->p_ruid
+          && uap->ruid != pc->p_svuid) {
+               return EPERM;
+       }
+
+       if(uap->euid == -1) {
+               return 0;
+       }
+       e_args.euid = uap->euid;
+       return seteuid(p, &e_args, retval);
 }
 
 struct osetregid_args {
 }
 
 struct osetregid_args {
@@ -415,35 +411,22 @@ osetregid(p, uap, retval)
        int *retval;
 {
        register struct pcred *pc = p->p_cred;
        int *retval;
 {
        register struct pcred *pc = p->p_cred;
-       register gid_t rgid, egid;
-       int error;
+       struct setegid_args e_args;
 
 
-       if (uap->rgid == -1)
-               rgid = pc->p_rgid;
-       else
-               rgid = uap->rgid;
        /*
        /*
-        * Allow setting real gid to previous effective, for swapping real and
-        * effective.  This didn't really work correctly in 4.[23], but is
-        * preserved so old stuff doesn't fail.  This should be:
-        *
-        * if (rgid != pc->p_rgid &&
-        *     (error = suser(pc->pc_ucred, &p->p_acflag)))
+        * Same comments as for setreuid() apply here.
         */
         */
-       if (rgid != pc->p_rgid && rgid != pc->pc_ucred->cr_groups[0] /* XXX */ &&
-           (error = suser(pc->pc_ucred, &p->p_acflag)))
-               return (error);
-       if (uap->egid == -1)
-               egid = pc->pc_ucred->cr_groups[0];
-       else
-               egid = uap->egid;
-       if (egid != pc->pc_ucred->cr_groups[0] && egid != pc->p_rgid &&
-           egid != pc->p_svgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
-               return (error);
-       pc->pc_ucred = crcopy(pc->pc_ucred);
-       pc->pc_ucred->cr_groups[0] = egid;
-       pc->p_rgid = rgid;
-       return (0);
+       if(uap->rgid != -1
+          && uap->rgid != pc->p_rgid
+          && uap->rgid != pc->p_svgid) {
+               return EPERM;
+       }
+
+       if(uap->egid == -1) {
+               return 0;
+       }
+       e_args.egid = uap->egid;
+       return setegid(p, &e_args, retval);
 }
 #endif
 
 }
 #endif
 
index f016173..132f7d5 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *     from: @(#)proc.h        7.28 (Berkeley) 5/30/91
  * SUCH DAMAGE.
  *
  *     from: @(#)proc.h        7.28 (Berkeley) 5/30/91
- *     $Id: proc.h,v 1.5 1993/12/19 00:55:20 wollman Exp $
+ *     $Id: proc.h,v 1.6 1994/01/14 16:25:46 davidg Exp $
  */
 
 #ifndef _PROC_H_
  */
 
 #ifndef _PROC_H_
@@ -182,34 +182,35 @@ struct    pcred {
 #define        SSTOP   6               /* process being traced */
 
 /* flag codes */
 #define        SSTOP   6               /* process being traced */
 
 /* flag codes */
-#define        SLOAD   0x0000001       /* in core */
-#define        SSYS    0x0000002       /* swapper or pager process */
-#define        SSINTR  0x0000004       /* sleep is interruptible */
-#define        SCTTY   0x0000008       /* has a controlling terminal */
-#define        SPPWAIT 0x0000010       /* parent is waiting for child to exec/exit */
-#define SEXEC  0x0000020       /* process called exec */
-#define        STIMO   0x0000040       /* timing out during sleep */
-#define        SSEL    0x0000080       /* selecting; wakeup/waiting danger */
-#define        SWEXIT  0x0000100       /* working on exiting */
-#define        SNOCLDSTOP 0x0000200    /* no SIGCHLD when children stop */
+#define        SLOAD   0x00000001      /* in core */
+#define        SSYS    0x00000002      /* swapper or pager process */
+#define        SSINTR  0x00000004      /* sleep is interruptible */
+#define        SCTTY   0x00000008      /* has a controlling terminal */
+#define        SPPWAIT 0x00000010      /* parent is waiting for child to exec/exit */
+#define SEXEC  0x00000020      /* process called exec */
+#define        STIMO   0x00000040      /* timing out during sleep */
+#define        SSEL    0x00000080      /* selecting; wakeup/waiting danger */
+#define        SWEXIT  0x00000100      /* working on exiting */
+#define        SNOCLDSTOP \
+               0x00000200      /* no SIGCHLD when children stop */
 /* the following three should probably be changed into a hold count */
 /* the following three should probably be changed into a hold count */
-#define        SLOCK   0x0000400       /* process being swapped out */
-#define        SKEEP   0x0000800       /* another flag to prevent swap out */
-#define        SPHYSIO 0x0001000       /* doing physical i/o */
-#define        STRC    0x0004000       /* process is being traced */
-#define        SWTED   0x0008000       /* another tracing flag */
-#define        SADVLCK 0x0040000       /* process may hold a POSIX advisory lock */
+#define        SLOCK   0x00000400      /* process being swapped out */
+#define        SKEEP   0x00000800      /* another flag to prevent swap out */
+#define        SPHYSIO 0x00001000      /* doing physical i/o */
+#define        STRC    0x00004000      /* process is being traced */
+#define        SWTED   0x00008000      /* another tracing flag */
+#define        SADVLCK 0x00040000      /* process may hold a POSIX advisory lock */
 /* the following should be moved to machine-dependent areas */
 /* the following should be moved to machine-dependent areas */
-#define        SOWEUPC 0x0002000       /* owe process an addupc() call at next ast */
+#define        SOWEUPC 0x00002000      /* owe process an addupc() call at next ast */
 #ifdef HPUXCOMPAT
 #ifdef HPUXCOMPAT
-#define        SHPUX   0x0010000       /* HP-UX process (HPUXCOMPAT) */
+#define        SHPUX   0x00010000      /* HP-UX process (HPUXCOMPAT) */
 #else
 #define        SHPUX   0               /* not HP-UX process (HPUXCOMPAT) */
 #endif
 #else
 #define        SHPUX   0               /* not HP-UX process (HPUXCOMPAT) */
 #endif
-/* not currently in use (never set) */
-#define        SPAGE   0x0020000       /* process in page wait state */
+#define        SUGID   0x00020000      /* process has changed [ug]id since exec */
 
 
-#define SPAGEDAEMON 0x0080000  /* process has been scanned by pageout daemon */
+#define SPAGEDAEMON \
+               0x00080000      /* process has been scanned by pageout daemon */
 
 #ifdef KERNEL
 /*
 
 #ifdef KERNEL
 /*