Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.1.100 /fs/exec.c

Filename:/fs/exec.c
Lines Added:37
Lines Deleted:23
Also changed in: (Previous) 2.1.93  2.1.92  2.1.91  2.1.90  2.1.89  2.1.77 
(Following) 2.1.104  2.1.116  2.1.118  2.1.120  2.1.126  2.1.127 

Location
[  2.1.100
  [  fs
     o  exec.c

Patch

diff -u --recursive --new-file v2.1.99/linux/fs/exec.c linux/fs/exec.c
--- v2.1.99/linux/fs/exec.c   Mon Apr  6 17:41:00 1998
+++ linux/fs/exec.c   Wed May  6 11:01:46 1998
@@ -419,6 +419,7 @@
    retval = new_page_tables(current);
    if (retval)
       goto fail_restore;
+   activate_context(current);
    up(&mm->mmap_sem);
    mmput(old_mm);
    return 0;
@@ -564,7 +565,7 @@
 int prepare_binprm(struct linux_binprm *bprm)
 {
    int mode;
-   int retval,id_change;
+   int retval,id_change,cap_raised;
    struct inode * inode = bprm->dentry->d_inode;
 
    mode = inode->i_mode;
@@ -584,7 +585,7 @@
 
    bprm->e_uid = current->euid;
    bprm->e_gid = current->egid;
-   id_change = 0;
+   id_change = cap_raised = 0;
 
    /* Set-uid? */
    if (mode & S_ISUID) {
@@ -630,21 +631,25 @@
          cap_set_full(bprm->cap_effective);
    }
 
-        /* We use a conservative definition of suid for capabilities.
-         * The process is suid if the permitted set is not a subset of
-         * the current permitted set after the exec call.
-         *         new permitted set = forced | (allowed & inherited)
-         *                       pP' = fP     | (fI      & pI)
-         */
-
-        if ((bprm->cap_permitted.cap |
-        (current->cap_inheritable.cap &
-         bprm->cap_inheritable.cap)) &
-       ~current->cap_permitted.cap) {
-      id_change = 1;
+        /* Only if pP' is _not_ a subset of pP, do we consider there
+         * has been a capability related "change of capability".  In
+         * such cases, we need to check that the elevation of
+         * privilege does not go against other system constraints.
+         * The new Permitted set is defined below -- see (***). */
+   {
+      kernel_cap_t working =
+         cap_combine(bprm->cap_permitted,
+                cap_intersect(bprm->cap_inheritable,
+                    current->cap_inheritable));
+      if (!cap_issubset(working, current->cap_permitted)) {
+         cap_raised = 1;
+      }
    }
 
-   if (id_change) {
+
+
+
+   if (id_change || cap_raised) {
       /* We can't suid-execute if we're sharing parts of the executable */
       /* or if we're being traced (or if suid execs are not allowed)    */
       /* (current->mm->count > 1 is ok, as we'll get a new mm anyway)   */
@@ -653,8 +658,10 @@
           || (current->fs->count > 1)
           || (atomic_read(¤t->sig->count) > 1)
           || (current->files->count > 1)) {
-         if (!suser())
-            return -EPERM;
+          if (id_change && !capable(CAP_SETUID))
+             return -EPERM;
+          if (cap_raised && !capable(CAP_SETPCAP))
+              return -EPERM;
       }
    }
 
@@ -669,7 +676,7 @@
  * The formula used for evolving capabilities is:
  *
  *       pI' = pI
- *       pP' = fP | (fI & pI)
+ * (***) pP' = fP | (fI & pI)
  *       pE' = pP' & fE          [NB. fE is 0 or ~0]
  *
  * I=Inheritable, P=Permitted, E=Effective // p=process, f=file
@@ -678,11 +685,18 @@
 
 void compute_creds(struct linux_binprm *bprm) 
 {
-   int new_permitted = bprm->cap_permitted.cap |
-      (bprm->cap_inheritable.cap & current->cap_inheritable.cap);
-
-   current->cap_permitted.cap = new_permitted;
-   current->cap_effective.cap = new_permitted & bprm->cap_effective.cap;
+   /* For init, we want to retain the capabilities set
+         * in the init_task struct. Thus we skip the usual
+         * capability rules */
+   if (current->pid != 1) {
+      int new_permitted = bprm->cap_permitted.cap |
+         (bprm->cap_inheritable.cap & 
+         current->cap_inheritable.cap);
+
+      current->cap_permitted.cap = new_permitted;
+      current->cap_effective.cap = new_permitted & 
+                  bprm->cap_effective.cap;
+   }
    
         /* AUD: Audit candidate if current->cap_effective is set */
 


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.