LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 1/4] security: capabilities patch (version 0.4.4), part 1/4: enlarge capability sets
@ 2006-09-10 13:37 David Madore
  2006-09-10 13:41 ` [PATCH 2/4] security: capabilities patch (version 0.4.4), part 2/4: change inheritance semantics David Madore
                   ` (3 more replies)
  0 siblings, 4 replies; 29+ messages in thread
From: David Madore @ 2006-09-10 13:37 UTC (permalink / raw)
  To: Linux Kernel mailing-list, LSM mailing-list


Increase the size of capability sets to 64 bits:

 * bits 32-47 are "regular", i.e., present by default on non-root
   processes;

 * maintain compatibility with former kernel interface for capset()
   and capget().

See <URL: http://www.madore.org/~david/linux/newcaps/ > for more
detailed explanations.

Signed-off-by: David A. Madore <david.madore@ens.fr>

---
 fs/open.c                  |    3 ++-
 fs/proc/array.c            |    6 +++---
 include/linux/capability.h |   30 ++++++++++++++++++-----------
 kernel/capability.c        |   46 +++++++++++++++++++++++++++++++++++---------
 security/commoncap.c       |   16 +++++++++++----
 security/dummy.c           |    6 +++---
 6 files changed, 75 insertions(+), 32 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 303f06d..e58a525 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -515,7 +515,8 @@ asmlinkage long sys_faccessat(int dfd, c
 	 * but we cannot because user_path_walk can sleep.
 	 */
 	if (current->uid)
-		cap_clear(current->cap_effective);
+		current->cap_effective = cap_intersect(current->cap_effective,
+						       CAP_REGULAR_SET);
 	else
 		current->cap_effective = current->cap_permitted;
 
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 0b615d6..6724fc2 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -285,9 +285,9 @@ static inline char * task_sig(struct tas
 
 static inline char *task_cap(struct task_struct *p, char *buffer)
 {
-    return buffer + sprintf(buffer, "CapInh:\t%016x\n"
-			    "CapPrm:\t%016x\n"
-			    "CapEff:\t%016x\n",
+    return buffer + sprintf(buffer, "CapInh:\t%016llx\n"
+			    "CapPrm:\t%016llx\n"
+			    "CapEff:\t%016llx\n",
 			    cap_t(p->cap_inheritable),
 			    cap_t(p->cap_permitted),
 			    cap_t(p->cap_effective));
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 6548b35..aa00b60 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -27,7 +27,8 @@ #include <linux/compiler.h>
    library since the draft standard requires the use of malloc/free
    etc.. */
  
-#define _LINUX_CAPABILITY_VERSION  0x19980330
+#define _LINUX_CAPABILITY_VERSION  0x20060903
+#define _LINUX_CAPABILITY_OLD_VERSION  0x19980330
 
 typedef struct __user_cap_header_struct {
 	__u32 version;
@@ -35,10 +36,16 @@ typedef struct __user_cap_header_struct 
 } __user *cap_user_header_t;
  
 typedef struct __user_cap_data_struct {
+        __u64 effective;
+        __u64 permitted;
+        __u64 inheritable;
+} __user *cap_user_data_t;
+ 
+typedef struct __user_cap_data_old_struct {
         __u32 effective;
         __u32 permitted;
         __u32 inheritable;
-} __user *cap_user_data_t;
+} __user *cap_user_data_old_t;
   
 #ifdef __KERNEL__
 
@@ -50,12 +57,12 @@ #include <asm/current.h>
 #ifdef STRICT_CAP_T_TYPECHECKS
 
 typedef struct kernel_cap_struct {
-	__u32 cap;
+	__u64 cap;
 } kernel_cap_t;
 
 #else
 
-typedef __u32 kernel_cap_t;
+typedef __u64 kernel_cap_t;
 
 #endif
   
@@ -310,12 +317,13 @@ #define cap_t(x) (x)
 
 #endif
 
-#define CAP_EMPTY_SET       to_cap_t(0)
-#define CAP_FULL_SET        to_cap_t(~0)
-#define CAP_INIT_EFF_SET    to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP))
-#define CAP_INIT_INH_SET    to_cap_t(0)
+#define CAP_EMPTY_SET       to_cap_t(0ULL)
+#define CAP_FULL_SET        to_cap_t(~0ULL)
+#define CAP_REGULAR_SET     to_cap_t(0x0000ffff00000000ULL)
+#define CAP_INIT_EFF_SET    to_cap_t(~0ULL)
+#define CAP_INIT_INH_SET    to_cap_t(~0ULL)
 
-#define CAP_TO_MASK(x) (1 << (x))
+#define CAP_TO_MASK(x) (1ULL << (x))
 #define cap_raise(c, flag)   (cap_t(c) |=  CAP_TO_MASK(flag))
 #define cap_lower(c, flag)   (cap_t(c) &= ~CAP_TO_MASK(flag))
 #define cap_raised(c, flag)  (cap_t(c) & CAP_TO_MASK(flag))
@@ -351,8 +359,8 @@ static inline kernel_cap_t cap_invert(ke
 #define cap_isclear(c)       (!cap_t(c))
 #define cap_issubset(a,set)  (!(cap_t(a) & ~cap_t(set)))
 
-#define cap_clear(c)         do { cap_t(c) =  0; } while(0)
-#define cap_set_full(c)      do { cap_t(c) = ~0; } while(0)
+#define cap_clear(c)         do { cap_t(c) =  0ULL; } while(0)
+#define cap_set_full(c)      do { cap_t(c) = ~0ULL; } while(0)
 #define cap_mask(c,mask)     do { cap_t(c) &= cap_t(mask); } while(0)
 
 #define cap_is_fs_cap(c)     (CAP_TO_MASK(c) & CAP_FS_MASK)
diff --git a/kernel/capability.c b/kernel/capability.c
index c7685ad..32b2521 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -52,7 +52,8 @@ asmlinkage long sys_capget(cap_user_head
      if (get_user(version, &header->version))
 	     return -EFAULT;
 
-     if (version != _LINUX_CAPABILITY_VERSION) {
+     if (version != _LINUX_CAPABILITY_VERSION
+	 && version != _LINUX_CAPABILITY_OLD_VERSION) {
 	     if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
 		     return -EFAULT; 
              return -EINVAL;
@@ -82,8 +83,18 @@ out:
      read_unlock(&tasklist_lock); 
      spin_unlock(&task_capability_lock);
 
-     if (!ret && copy_to_user(dataptr, &data, sizeof data))
-          return -EFAULT; 
+     if (!ret) {
+	     if (version == _LINUX_CAPABILITY_OLD_VERSION) {
+		     struct __user_cap_data_old_struct data_old;
+		     data_old.effective = data_old.effective & 0xffffffffULL;
+		     data_old.permitted = data_old.permitted & 0xffffffffULL;
+		     data_old.inheritable = data_old.inheritable & 0xffffffffULL;
+		     if (copy_to_user(dataptr, &data_old, sizeof data_old))
+			     return -EFAULT;
+	     } else
+		     if (copy_to_user(dataptr, &data, sizeof data))
+			     return -EFAULT;
+     }
 
      return ret;
 }
@@ -179,7 +190,8 @@ asmlinkage long sys_capset(cap_user_head
      if (get_user(version, &header->version))
 	     return -EFAULT; 
 
-     if (version != _LINUX_CAPABILITY_VERSION) {
+     if (version != _LINUX_CAPABILITY_VERSION
+	 && version != _LINUX_CAPABILITY_OLD_VERSION) {
 	     if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
 		     return -EFAULT; 
              return -EINVAL;
@@ -191,10 +203,25 @@ asmlinkage long sys_capset(cap_user_head
      if (pid && pid != current->pid && !capable(CAP_SETPCAP))
              return -EPERM;
 
-     if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
-	 copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) ||
-	 copy_from_user(&permitted, &data->permitted, sizeof(permitted)))
-	     return -EFAULT; 
+     if (version == _LINUX_CAPABILITY_OLD_VERSION) {
+	     const cap_user_data_old_t data2 = (void *)data;
+	     __u32 w;
+	     /* Assume caller wants to keep all regular caps and clear
+	      * all unknown additional caps.  Is this right? */
+	     if (copy_from_user(&w, &data2->effective, sizeof(w)))
+		     return -EFAULT;
+	     effective = (__u64)w | CAP_REGULAR_SET;
+	     if (copy_from_user(&w, &data2->inheritable, sizeof(w)))
+		     return -EFAULT;
+	     inheritable = (__u64)w | CAP_REGULAR_SET;
+	     if (copy_from_user(&w, &data2->permitted, sizeof(w)))
+		     return -EFAULT;
+	     permitted = (__u64)w | CAP_REGULAR_SET;
+     } else
+	     if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
+		 copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) ||
+		 copy_from_user(&permitted, &data->permitted, sizeof(permitted)))
+		     return -EFAULT; 
 
      spin_lock(&task_capability_lock);
      read_lock(&tasklist_lock);
@@ -237,7 +264,8 @@ out:
 int __capable(struct task_struct *t, int cap)
 {
 	if (security_capable(t, cap) == 0) {
-		t->flags |= PF_SUPERPRIV;
+		if (!cap_raised(CAP_REGULAR_SET, cap))
+			t->flags |= PF_SUPERPRIV;
 		return 1;
 	}
 	return 0;
diff --git a/security/commoncap.c b/security/commoncap.c
index f50fc29..91dc53d 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -244,13 +244,19 @@ static inline void cap_emulate_setxuid (
 					int old_suid)
 {
 	if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
-	    (current->uid != 0 && current->euid != 0 && current->suid != 0) &&
-	    !current->keep_capabilities) {
-		cap_clear (current->cap_permitted);
-		cap_clear (current->cap_effective);
+	    (current->uid != 0 && current->euid != 0 && current->suid != 0)) {
+		if (!current->keep_capabilities) {
+			current->cap_permitted
+				= cap_intersect (current->cap_permitted,
+						 CAP_REGULAR_SET);
+			current->cap_effective
+				= cap_intersect (current->cap_effective,
+						 CAP_REGULAR_SET);
+		}
 	}
 	if (old_euid == 0 && current->euid != 0) {
-		cap_clear (current->cap_effective);
+		current->cap_effective = cap_intersect (current->cap_effective,
+							CAP_REGULAR_SET);
 	}
 	if (old_euid != 0 && current->euid == 0) {
 		current->cap_effective = current->cap_permitted;
diff --git a/security/dummy.c b/security/dummy.c
index 58c6d39..572a15b 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -37,11 +37,11 @@ static int dummy_ptrace (struct task_str
 static int dummy_capget (struct task_struct *target, kernel_cap_t * effective,
 			 kernel_cap_t * inheritable, kernel_cap_t * permitted)
 {
-	*effective = *inheritable = *permitted = 0;
+	*effective = *inheritable = *permitted = CAP_REGULAR_SET;
 	if (!issecure(SECURE_NOROOT)) {
 		if (target->euid == 0) {
-			*permitted |= (~0 & ~CAP_FS_MASK);
-			*effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK);
+			*permitted |= (CAP_FULL_SET & ~CAP_FS_MASK);
+			*effective |= (CAP_FULL_SET & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK);
 		}
 		if (target->fsuid == 0) {
 			*permitted |= CAP_FS_MASK;

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 2/4] security: capabilities patch (version 0.4.4), part 2/4: change inheritance semantics
  2006-09-10 13:37 [PATCH 1/4] security: capabilities patch (version 0.4.4), part 1/4: enlarge capability sets David Madore
@ 2006-09-10 13:41 ` David Madore
  2006-09-10 13:42 ` [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities David Madore
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 29+ messages in thread
From: David Madore @ 2006-09-10 13:41 UTC (permalink / raw)
  To: Linux Kernel mailing-list, LSM mailing-list


Make capabilities inheritable by default.  The following remarks
apply:

 * executables are assumed by default to have a full set of
   "inheritable" (allowed) and "effective" capabilities,

 * w.r.t. capabilities(7)-documented behavior, inheritance of the
   effective bits is changed (use P(eff) rather than F(eff) in half
   of the formula),

 * also, inheritance of the inheritable set is based on the new
   permitted set rather than on the old inheritable.

Capability sets are now sanitized upon suid/sgid exec (even non-root).

See <URL: http://www.madore.org/~david/linux/newcaps/ > for more
detailed explanations.

Signed-off-by: David A. Madore <david.madore@ens.fr>

---
 fs/exec.c                  |    4 ++
 include/linux/binfmts.h    |    1 
 include/linux/securebits.h |    4 ++
 kernel/capability.c        |    2 -
 security/commoncap.c       |   90 ++++++++++++++++++++++++++++++--------------
 5 files changed, 72 insertions(+), 29 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 54135df..e4d0a2c 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -925,10 +925,13 @@ int prepare_binprm(struct linux_binprm *
 
 	bprm->e_uid = current->euid;
 	bprm->e_gid = current->egid;
+	bprm->is_suid = 0;
+	bprm->is_sgid = 0;
 
 	if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) {
 		/* Set-uid? */
 		if (mode & S_ISUID) {
+			bprm->is_suid = 1;
 			current->personality &= ~PER_CLEAR_ON_SETID;
 			bprm->e_uid = inode->i_uid;
 		}
@@ -940,6 +943,7 @@ int prepare_binprm(struct linux_binprm *
 		 * executable.
 		 */
 		if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
+			bprm->is_sgid = 1;
 			current->personality &= ~PER_CLEAR_ON_SETID;
 			bprm->e_gid = inode->i_gid;
 		}
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index c1e82c5..c7fb183 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -29,6 +29,7 @@ struct linux_binprm{
 	struct file * file;
 	int e_uid, e_gid;
 	kernel_cap_t cap_inheritable, cap_permitted, cap_effective;
+	char is_suid, is_sgid;
 	void *security;
 	int argc, envc;
 	char * filename;	/* Name of binary as seen by procps */
diff --git a/include/linux/securebits.h b/include/linux/securebits.h
index 5b06178..0092332 100644
--- a/include/linux/securebits.h
+++ b/include/linux/securebits.h
@@ -18,6 +18,10 @@ #define SECURE_NOROOT            0
    privileges. When unset, setuid doesn't change privileges. */
 #define SECURE_NO_SETUID_FIXUP   2
 
+/* When set, exec()ing a suid/sgid program does not force reinstate
+   all "regular" capabilities. */
+#define SECURE_NO_SXID_SANITIZE  4
+
 /* Each securesetting is implemented using two bits. One bit specify
    whether the setting is on or off. The other bit specify whether the
    setting is fixed or not. A setting which is fixed cannot be changed
diff --git a/kernel/capability.c b/kernel/capability.c
index 32b2521..2bb802a 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -15,7 +15,7 @@ #include <linux/syscalls.h>
 #include <asm/uaccess.h>
 
 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
-kernel_cap_t cap_bset = CAP_INIT_EFF_SET;
+kernel_cap_t cap_bset = CAP_INIT_INH_SET;
 
 EXPORT_SYMBOL(securebits);
 EXPORT_SYMBOL(cap_bset);
diff --git a/security/commoncap.c b/security/commoncap.c
index 91dc53d..291a4bd 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -12,6 +12,7 @@ #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/security.h>
+#include <linux/securebits.h>
 #include <linux/file.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
@@ -97,6 +98,8 @@ int cap_capset_check (struct task_struct
 	if (!cap_issubset (*effective, *permitted)) {
 		return -EPERM;
 	}
+	/* we allow Inheritable not to be a subset of Permitted:
+	 * cap_capset_set will intersect them anyway */
 
 	return 0;
 }
@@ -105,7 +108,7 @@ void cap_capset_set (struct task_struct 
 		     kernel_cap_t *inheritable, kernel_cap_t *permitted)
 {
 	target->cap_effective = *effective;
-	target->cap_inheritable = *inheritable;
+	target->cap_inheritable = cap_intersect (*permitted, *inheritable);
 	target->cap_permitted = *permitted;
 }
 
@@ -114,39 +117,66 @@ int cap_bprm_set_security (struct linux_
 	/* Copied from fs/exec.c:prepare_binprm. */
 
 	/* We don't have VFS support for capabilities yet */
-	cap_clear (bprm->cap_inheritable);
+	cap_set_full (bprm->cap_inheritable);
 	cap_clear (bprm->cap_permitted);
-	cap_clear (bprm->cap_effective);
+	cap_set_full (bprm->cap_effective);
+
+	/* Sanitize caps for all suid/sgid programs. */
+	if (!issecure (SECURE_NO_SXID_SANITIZE) && (bprm->is_suid
+						    || bprm->is_sgid)) {
+		/* Ensure that they get _at least_ regular caps. */
+		bprm->cap_permitted = CAP_REGULAR_SET;
+		if ((current->uid != 0 && current->euid != 0
+		     && current->suid != 0)
+		    || issecure (SECURE_NOROOT)) {
+			/* Ensure that they don't get _more_ caps when they
+			   might not expect it.  Note that dropping
+			   capabilities on change of ?uid from ==0 to !=0 will
+			   be handled by cap_task_post_setuid() called from
+			   cap_bprm_apply_creds() below.  Yuck!!!!!!  This is
+			   soooooo ugly! */
+			bprm->cap_inheritable = CAP_REGULAR_SET;
+			bprm->cap_effective = CAP_REGULAR_SET;
+		}
+	}
 
 	/*  To support inheritance of root-permissions and suid-root
 	 *  executables under compatibility mode, we raise all three
 	 *  capability sets for the file.
-	 *
-	 *  If only the real uid is 0, we only raise the inheritable
-	 *  and permitted sets of the executable file.
 	 */
-
 	if (!issecure (SECURE_NOROOT)) {
-		if (bprm->e_uid == 0 || current->uid == 0) {
+		if (bprm->is_suid && bprm->e_uid == 0) {
 			cap_set_full (bprm->cap_inheritable);
 			cap_set_full (bprm->cap_permitted);
-		}
-		if (bprm->e_uid == 0)
 			cap_set_full (bprm->cap_effective);
+		}
 	}
+
 	return 0;
 }
 
 void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
 {
 	/* Derived from fs/exec.c:compute_creds. */
-	kernel_cap_t new_permitted, working;
+	kernel_cap_t new_permitted, new_effective, working;
+	uid_t old_ruid, old_euid, old_suid;
 
+	/* P'(per) = (P(inh) & F(inh)) | (F(per) & bset) */
 	new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
 	working = cap_intersect (bprm->cap_inheritable,
 				 current->cap_inheritable);
 	new_permitted = cap_combine (new_permitted, working);
 
+	/* P'(eff) = (P(inh) & P(eff) & F(inh)) | (F(per) & F(eff) & bset) */
+	new_effective = cap_intersect (bprm->cap_permitted, bprm->cap_effective);
+	new_effective = cap_intersect (new_effective, cap_bset);
+	working = cap_intersect (bprm->cap_inheritable,
+				 current->cap_effective);
+	working = cap_intersect (working, current->cap_inheritable);
+	new_effective = cap_combine (new_effective, working);
+
+	/* P'(inh) = P'(per) */
+
 	if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
 	    !cap_issubset (new_permitted, current->cap_permitted)) {
 		current->mm->dumpable = suid_dumpable;
@@ -159,36 +189,37 @@ void cap_bprm_apply_creds (struct linux_
 			if (!capable (CAP_SETPCAP)) {
 				new_permitted = cap_intersect (new_permitted,
 							current->cap_permitted);
+				new_effective = cap_intersect (new_permitted,
+							       new_effective);
 			}
 		}
 	}
 
+	old_ruid = current->uid;
+	old_euid = current->euid;
+	old_suid = current->suid;
 	current->suid = current->euid = current->fsuid = bprm->e_uid;
 	current->sgid = current->egid = current->fsgid = bprm->e_gid;
 
-	/* 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) {
-		current->cap_permitted = new_permitted;
-		current->cap_effective =
-		    cap_intersect (new_permitted, bprm->cap_effective);
-	}
-
-	/* AUD: Audit candidate if current->cap_effective is set */
+	current->cap_permitted = new_permitted;
+	current->cap_effective = new_effective;
+	current->cap_inheritable = new_permitted;
 
 	current->keep_capabilities = 0;
+	/* Make sure we drop capabilities if required by suid. */
+	cap_task_post_setuid (old_ruid, old_euid, old_suid, LSM_SETID_RES);
+
+	/* AUD: Audit candidate if current->cap_effective is set */
 }
 
 int cap_bprm_secureexec (struct linux_binprm *bprm)
 {
 	/* If/when this module is enhanced to incorporate capability
 	   bits on files, the test below should be extended to also perform a 
-	   test between the old and new capability sets.  For now,
-	   it simply preserves the legacy decision algorithm used by
-	   the old userland. */
-	return (current->euid != current->uid ||
-		current->egid != current->gid);
+	   test between the old and new capability sets. */
+	return ((bprm->is_suid || bprm->is_sgid)
+		&& !cap_issubset (bprm->cap_permitted,
+				  current->cap_permitted));
 }
 
 int cap_inode_setxattr(struct dentry *dentry, char *name, void *value,
@@ -253,12 +284,15 @@ static inline void cap_emulate_setxuid (
 				= cap_intersect (current->cap_effective,
 						 CAP_REGULAR_SET);
 		}
+		current->cap_inheritable
+			= cap_intersect (current->cap_inheritable,
+					 CAP_REGULAR_SET);
 	}
-	if (old_euid == 0 && current->euid != 0) {
+	if (old_euid == 0 && current->euid != 0 && !current->keep_capabilities) {
 		current->cap_effective = cap_intersect (current->cap_effective,
 							CAP_REGULAR_SET);
 	}
-	if (old_euid != 0 && current->euid == 0) {
+	if (old_euid != 0 && current->euid == 0 && !current->keep_capabilities) {
 		current->cap_effective = current->cap_permitted;
 	}
 }

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-10 13:37 [PATCH 1/4] security: capabilities patch (version 0.4.4), part 1/4: enlarge capability sets David Madore
  2006-09-10 13:41 ` [PATCH 2/4] security: capabilities patch (version 0.4.4), part 2/4: change inheritance semantics David Madore
@ 2006-09-10 13:42 ` David Madore
  2006-09-10 16:23   ` Alan Cox
  2006-09-10 13:44 ` David Madore
  2006-09-10 13:46 ` [PATCH 4/4] security: capabilities patch (version 0.4.4), part 4/4: add filesystem support David Madore
  3 siblings, 1 reply; 29+ messages in thread
From: David Madore @ 2006-09-10 13:42 UTC (permalink / raw)
  To: Linux Kernel mailing-list, LSM mailing-list


Introduce six new "regular" (=on-by-default) capabilities:

 * CAP_REG_FORK, CAP_REG_OPEN, CAP_REG_EXEC allow access to the
   fork(), open() and exec() syscalls,

 * CAP_REG_SXID allows privilege gain on suid/sgid exec,

 * CAP_REG_WRITE controls any write-access to the filesystem,

 * CAP_REG_PTRACE allows ptrace().

See <URL: http://www.madore.org/~david/linux/newcaps/ > for more
detailed explanations.

Signed-off-by: David A. Madore <david.madore@ens.fr>

---
 fs/exec.c                  |    4 ++
 include/linux/binfmts.h    |    1 
 include/linux/securebits.h |    4 ++
 kernel/capability.c        |    2 -
 security/commoncap.c       |   90 ++++++++++++++++++++++++++++++--------------
 5 files changed, 72 insertions(+), 29 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 54135df..e4d0a2c 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -925,10 +925,13 @@ int prepare_binprm(struct linux_binprm *
 
 	bprm->e_uid = current->euid;
 	bprm->e_gid = current->egid;
+	bprm->is_suid = 0;
+	bprm->is_sgid = 0;
 
 	if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) {
 		/* Set-uid? */
 		if (mode & S_ISUID) {
+			bprm->is_suid = 1;
 			current->personality &= ~PER_CLEAR_ON_SETID;
 			bprm->e_uid = inode->i_uid;
 		}
@@ -940,6 +943,7 @@ int prepare_binprm(struct linux_binprm *
 		 * executable.
 		 */
 		if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
+			bprm->is_sgid = 1;
 			current->personality &= ~PER_CLEAR_ON_SETID;
 			bprm->e_gid = inode->i_gid;
 		}
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index c1e82c5..c7fb183 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -29,6 +29,7 @@ struct linux_binprm{
 	struct file * file;
 	int e_uid, e_gid;
 	kernel_cap_t cap_inheritable, cap_permitted, cap_effective;
+	char is_suid, is_sgid;
 	void *security;
 	int argc, envc;
 	char * filename;	/* Name of binary as seen by procps */
diff --git a/include/linux/securebits.h b/include/linux/securebits.h
index 5b06178..0092332 100644
--- a/include/linux/securebits.h
+++ b/include/linux/securebits.h
@@ -18,6 +18,10 @@ #define SECURE_NOROOT            0
    privileges. When unset, setuid doesn't change privileges. */
 #define SECURE_NO_SETUID_FIXUP   2
 
+/* When set, exec()ing a suid/sgid program does not force reinstate
+   all "regular" capabilities. */
+#define SECURE_NO_SXID_SANITIZE  4
+
 /* Each securesetting is implemented using two bits. One bit specify
    whether the setting is on or off. The other bit specify whether the
    setting is fixed or not. A setting which is fixed cannot be changed
diff --git a/kernel/capability.c b/kernel/capability.c
index 32b2521..2bb802a 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -15,7 +15,7 @@ #include <linux/syscalls.h>
 #include <asm/uaccess.h>
 
 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
-kernel_cap_t cap_bset = CAP_INIT_EFF_SET;
+kernel_cap_t cap_bset = CAP_INIT_INH_SET;
 
 EXPORT_SYMBOL(securebits);
 EXPORT_SYMBOL(cap_bset);
diff --git a/security/commoncap.c b/security/commoncap.c
index 91dc53d..291a4bd 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -12,6 +12,7 @@ #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/security.h>
+#include <linux/securebits.h>
 #include <linux/file.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
@@ -97,6 +98,8 @@ int cap_capset_check (struct task_struct
 	if (!cap_issubset (*effective, *permitted)) {
 		return -EPERM;
 	}
+	/* we allow Inheritable not to be a subset of Permitted:
+	 * cap_capset_set will intersect them anyway */
 
 	return 0;
 }
@@ -105,7 +108,7 @@ void cap_capset_set (struct task_struct 
 		     kernel_cap_t *inheritable, kernel_cap_t *permitted)
 {
 	target->cap_effective = *effective;
-	target->cap_inheritable = *inheritable;
+	target->cap_inheritable = cap_intersect (*permitted, *inheritable);
 	target->cap_permitted = *permitted;
 }
 
@@ -114,39 +117,66 @@ int cap_bprm_set_security (struct linux_
 	/* Copied from fs/exec.c:prepare_binprm. */
 
 	/* We don't have VFS support for capabilities yet */
-	cap_clear (bprm->cap_inheritable);
+	cap_set_full (bprm->cap_inheritable);
 	cap_clear (bprm->cap_permitted);
-	cap_clear (bprm->cap_effective);
+	cap_set_full (bprm->cap_effective);
+
+	/* Sanitize caps for all suid/sgid programs. */
+	if (!issecure (SECURE_NO_SXID_SANITIZE) && (bprm->is_suid
+						    || bprm->is_sgid)) {
+		/* Ensure that they get _at least_ regular caps. */
+		bprm->cap_permitted = CAP_REGULAR_SET;
+		if ((current->uid != 0 && current->euid != 0
+		     && current->suid != 0)
+		    || issecure (SECURE_NOROOT)) {
+			/* Ensure that they don't get _more_ caps when they
+			   might not expect it.  Note that dropping
+			   capabilities on change of ?uid from ==0 to !=0 will
+			   be handled by cap_task_post_setuid() called from
+			   cap_bprm_apply_creds() below.  Yuck!!!!!!  This is
+			   soooooo ugly! */
+			bprm->cap_inheritable = CAP_REGULAR_SET;
+			bprm->cap_effective = CAP_REGULAR_SET;
+		}
+	}
 
 	/*  To support inheritance of root-permissions and suid-root
 	 *  executables under compatibility mode, we raise all three
 	 *  capability sets for the file.
-	 *
-	 *  If only the real uid is 0, we only raise the inheritable
-	 *  and permitted sets of the executable file.
 	 */
-
 	if (!issecure (SECURE_NOROOT)) {
-		if (bprm->e_uid == 0 || current->uid == 0) {
+		if (bprm->is_suid && bprm->e_uid == 0) {
 			cap_set_full (bprm->cap_inheritable);
 			cap_set_full (bprm->cap_permitted);
-		}
-		if (bprm->e_uid == 0)
 			cap_set_full (bprm->cap_effective);
+		}
 	}
+
 	return 0;
 }
 
 void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
 {
 	/* Derived from fs/exec.c:compute_creds. */
-	kernel_cap_t new_permitted, working;
+	kernel_cap_t new_permitted, new_effective, working;
+	uid_t old_ruid, old_euid, old_suid;
 
+	/* P'(per) = (P(inh) & F(inh)) | (F(per) & bset) */
 	new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
 	working = cap_intersect (bprm->cap_inheritable,
 				 current->cap_inheritable);
 	new_permitted = cap_combine (new_permitted, working);
 
+	/* P'(eff) = (P(inh) & P(eff) & F(inh)) | (F(per) & F(eff) & bset) */
+	new_effective = cap_intersect (bprm->cap_permitted, bprm->cap_effective);
+	new_effective = cap_intersect (new_effective, cap_bset);
+	working = cap_intersect (bprm->cap_inheritable,
+				 current->cap_effective);
+	working = cap_intersect (working, current->cap_inheritable);
+	new_effective = cap_combine (new_effective, working);
+
+	/* P'(inh) = P'(per) */
+
 	if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
 	    !cap_issubset (new_permitted, current->cap_permitted)) {
 		current->mm->dumpable = suid_dumpable;
@@ -159,36 +189,37 @@ void cap_bprm_apply_creds (struct linux_
 			if (!capable (CAP_SETPCAP)) {
 				new_permitted = cap_intersect (new_permitted,
 							current->cap_permitted);
+				new_effective = cap_intersect (new_permitted,
+							       new_effective);
 			}
 		}
 	}
 
+	old_ruid = current->uid;
+	old_euid = current->euid;
+	old_suid = current->suid;
 	current->suid = current->euid = current->fsuid = bprm->e_uid;
 	current->sgid = current->egid = current->fsgid = bprm->e_gid;
 
-	/* 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) {
-		current->cap_permitted = new_permitted;
-		current->cap_effective =
-		    cap_intersect (new_permitted, bprm->cap_effective);
-	}
-
-	/* AUD: Audit candidate if current->cap_effective is set */
+	current->cap_permitted = new_permitted;
+	current->cap_effective = new_effective;
+	current->cap_inheritable = new_permitted;
 
 	current->keep_capabilities = 0;
+	/* Make sure we drop capabilities if required by suid. */
+	cap_task_post_setuid (old_ruid, old_euid, old_suid, LSM_SETID_RES);
+
+	/* AUD: Audit candidate if current->cap_effective is set */
 }
 
 int cap_bprm_secureexec (struct linux_binprm *bprm)
 {
 	/* If/when this module is enhanced to incorporate capability
 	   bits on files, the test below should be extended to also perform a 
-	   test between the old and new capability sets.  For now,
-	   it simply preserves the legacy decision algorithm used by
-	   the old userland. */
-	return (current->euid != current->uid ||
-		current->egid != current->gid);
+	   test between the old and new capability sets. */
+	return ((bprm->is_suid || bprm->is_sgid)
+		&& !cap_issubset (bprm->cap_permitted,
+				  current->cap_permitted));
 }
 
 int cap_inode_setxattr(struct dentry *dentry, char *name, void *value,
@@ -253,12 +284,15 @@ static inline void cap_emulate_setxuid (
 				= cap_intersect (current->cap_effective,
 						 CAP_REGULAR_SET);
 		}
+		current->cap_inheritable
+			= cap_intersect (current->cap_inheritable,
+					 CAP_REGULAR_SET);
 	}
-	if (old_euid == 0 && current->euid != 0) {
+	if (old_euid == 0 && current->euid != 0 && !current->keep_capabilities) {
 		current->cap_effective = cap_intersect (current->cap_effective,
 							CAP_REGULAR_SET);
 	}
-	if (old_euid != 0 && current->euid == 0) {
+	if (old_euid != 0 && current->euid == 0 && !current->keep_capabilities) {
 		current->cap_effective = current->cap_permitted;
 	}
 }

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-10 13:37 [PATCH 1/4] security: capabilities patch (version 0.4.4), part 1/4: enlarge capability sets David Madore
  2006-09-10 13:41 ` [PATCH 2/4] security: capabilities patch (version 0.4.4), part 2/4: change inheritance semantics David Madore
  2006-09-10 13:42 ` [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities David Madore
@ 2006-09-10 13:44 ` David Madore
  2006-09-10 13:46 ` [PATCH 4/4] security: capabilities patch (version 0.4.4), part 4/4: add filesystem support David Madore
  3 siblings, 0 replies; 29+ messages in thread
From: David Madore @ 2006-09-10 13:44 UTC (permalink / raw)
  To: Linux Kernel mailing-list, LSM mailing-list


[Sorry!  Previous mail had the wrong patch...  This one is correct.]

Introduce six new "regular" (=on-by-default) capabilities:

 * CAP_REG_FORK, CAP_REG_OPEN, CAP_REG_EXEC allow access to the
   fork(), open() and exec() syscalls,

 * CAP_REG_SXID allows privilege gain on suid/sgid exec,

 * CAP_REG_WRITE controls any write-access to the filesystem,

 * CAP_REG_PTRACE allows ptrace().

See <URL: http://www.madore.org/~david/linux/newcaps/ > for more
detailed explanations.

Signed-off-by: David A. Madore <david.madore@ens.fr>

---
 fs/exec.c                  |    5 +++++
 fs/namei.c                 |    2 +-
 fs/open.c                  |   26 ++++++++++++++++++++------
 fs/xattr.c                 |    3 ++-
 include/linux/capability.h |   23 +++++++++++++++++++++++
 kernel/fork.c              |    2 ++
 kernel/ptrace.c            |    2 ++
 7 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index e4d0a2c..1a7ff92 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -929,6 +929,9 @@ int prepare_binprm(struct linux_binprm *
 	bprm->is_sgid = 0;
 
 	if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) {
+		if (!capable(CAP_REG_SXID))
+			return -EPERM;
+
 		/* Set-uid? */
 		if (mode & S_ISUID) {
 			bprm->is_suid = 1;
@@ -1137,6 +1140,8 @@ int do_execve(char * filename,
 	int retval;
 	int i;
 
+	if (!capable(CAP_REG_EXEC))
+		return -EPERM;
 	retval = -ENOMEM;
 	bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
 	if (!bprm)
diff --git a/fs/namei.c b/fs/namei.c
index 432d6bc..69a3bae 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -242,7 +242,7 @@ int permission(struct inode *inode, int 
 		/*
 		 * Nobody gets write access to an immutable file.
 		 */
-		if (IS_IMMUTABLE(inode))
+		if (IS_IMMUTABLE(inode) || !capable(CAP_REG_WRITE))
 			return -EACCES;
 	}
 
diff --git a/fs/open.c b/fs/open.c
index e58a525..77a12ba 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -253,7 +253,7 @@ static long do_sys_truncate(const char _
 		goto dput_and_out;
 
 	error = -EPERM;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || !capable(CAP_REG_WRITE))
 		goto dput_and_out;
 
 	/*
@@ -382,6 +382,10 @@ asmlinkage long sys_utime(char __user * 
 	if (IS_RDONLY(inode))
 		goto dput_and_out;
 
+	error = -EPERM;
+	if (!capable(CAP_REG_WRITE))
+		goto dput_and_out;
+
 	/* Don't worry, the checks are done in inode_change_ok() */
 	newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
 	if (times) {
@@ -439,6 +443,10 @@ long do_utimes(int dfd, char __user *fil
 	if (IS_RDONLY(inode))
 		goto dput_and_out;
 
+	error = -EPERM;
+	if (!capable(CAP_REG_WRITE))
+		goto dput_and_out;
+
 	/* Don't worry, the checks are done in inode_change_ok() */
 	newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
 	if (times) {
@@ -640,7 +648,7 @@ asmlinkage long sys_fchmod(unsigned int 
 	if (IS_RDONLY(inode))
 		goto out_putf;
 	err = -EPERM;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || !capable(CAP_REG_WRITE))
 		goto out_putf;
 	mutex_lock(&inode->i_mutex);
 	if (mode == (mode_t) -1)
@@ -674,7 +682,7 @@ asmlinkage long sys_fchmodat(int dfd, co
 		goto dput_and_out;
 
 	error = -EPERM;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || !capable(CAP_REG_WRITE))
 		goto dput_and_out;
 
 	mutex_lock(&inode->i_mutex);
@@ -711,7 +719,7 @@ static int chown_common(struct dentry * 
 	if (IS_RDONLY(inode))
 		goto out;
 	error = -EPERM;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || !capable(CAP_REG_WRITE))
 		goto out;
 	newattrs.ia_valid =  ATTR_CTIME;
 	if (user != (uid_t) -1) {
@@ -1105,7 +1113,10 @@ asmlinkage long sys_open(const char __us
 	if (force_o_largefile())
 		flags |= O_LARGEFILE;
 
-	ret = do_sys_open(AT_FDCWD, filename, flags, mode);
+	if (capable(CAP_REG_OPEN))
+		ret = do_sys_open(AT_FDCWD, filename, flags, mode);
+	else
+		ret = -EPERM;
 	/* avoid REGPARM breakage on x86: */
 	prevent_tail_call(ret);
 	return ret;
@@ -1120,7 +1131,10 @@ asmlinkage long sys_openat(int dfd, cons
 	if (force_o_largefile())
 		flags |= O_LARGEFILE;
 
-	ret = do_sys_open(dfd, filename, flags, mode);
+	if (capable(CAP_REG_OPEN))
+		ret = do_sys_open(dfd, filename, flags, mode);
+	else
+		ret = -EPERM;
 	/* avoid REGPARM breakage on x86: */
 	prevent_tail_call(ret);
 	return ret;
diff --git a/fs/xattr.c b/fs/xattr.c
index c32f15b..33b70ce 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -35,7 +35,8 @@ xattr_permission(struct inode *inode, co
 	if (mask & MAY_WRITE) {
 		if (IS_RDONLY(inode))
 			return -EROFS;
-		if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		if (IS_IMMUTABLE(inode) || IS_APPEND(inode)
+		    || !capable(CAP_REG_WRITE))
 			return -EPERM;
 	}
 
diff --git a/include/linux/capability.h b/include/linux/capability.h
index aa00b60..efc268e 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -295,6 +295,29 @@ #define CAP_AUDIT_WRITE      29
 
 #define CAP_AUDIT_CONTROL    30
 
+
+/**
+ ** Regular capabilities (normally possessed by all processes).
+ **/
+
+/* Can fork() */
+#define CAP_REG_FORK         32
+
+/* Can open() */
+#define CAP_REG_OPEN         33
+
+/* Can exec() */
+#define CAP_REG_EXEC         34
+
+/* Might gain permissions on exec() */
+#define CAP_REG_SXID         35
+
+/* Perform write access to the filesystem */
+#define CAP_REG_WRITE        36
+
+/* Can use ptrace() */
+#define CAP_REG_PTRACE       37
+
 #ifdef __KERNEL__
 /* 
  * Bounding set
diff --git a/kernel/fork.c b/kernel/fork.c
index f9b014e..20f559f 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1347,6 +1347,8 @@ long do_fork(unsigned long clone_flags,
 	struct pid *pid = alloc_pid();
 	long nr;
 
+	if (!capable(CAP_REG_FORK))
+		return -EPERM;
 	if (!pid)
 		return -EAGAIN;
 	nr = pid->nr;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 9a111f7..093307d 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -132,6 +132,8 @@ static int may_attach(struct task_struct
 	/* Don't let security modules deny introspection */
 	if (task == current)
 		return 0;
+	if (!capable(CAP_REG_PTRACE))
+		return -EPERM;
 	if (((current->uid != task->euid) ||
 	     (current->uid != task->suid) ||
 	     (current->uid != task->uid) ||

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 4/4] security: capabilities patch (version 0.4.4), part 4/4: add filesystem support
  2006-09-10 13:37 [PATCH 1/4] security: capabilities patch (version 0.4.4), part 1/4: enlarge capability sets David Madore
                   ` (2 preceding siblings ...)
  2006-09-10 13:44 ` David Madore
@ 2006-09-10 13:46 ` David Madore
  3 siblings, 0 replies; 29+ messages in thread
From: David Madore @ 2006-09-10 13:46 UTC (permalink / raw)
  To: Linux Kernel mailing-list, LSM mailing-list

Add filesystem support for capabilities.  This is controlled by the
security.capability extended attribute.

Originally a merge from <URL: http://lkml.org/lkml/2006/9/6/229 >.

Notes:

 * mounting nosuid deactivates the permitted ("forced") set of
   capabilities on executables, similarly if no CAP_REG_SXID.

See <URL: http://www.madore.org/~david/linux/newcaps/ > for more
detailed explanations.

Signed-off-by: David A. Madore <david.madore@ens.fr>

---
 include/linux/capability.h |    3 +
 include/linux/security.h   |   10 ++-
 security/Kconfig           |   10 +++
 security/capability.c      |    4 +
 security/commoncap.c       |  154 ++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 177 insertions(+), 4 deletions(-)

diff --git a/include/linux/capability.h b/include/linux/capability.h
index efc268e..428ccc5 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -295,6 +295,9 @@ #define CAP_AUDIT_WRITE      29
 
 #define CAP_AUDIT_CONTROL    30
 
+/* Number of low (=system, =additional) caps */
+#define CAP_NUMCAPS_SYS	     30
+
 
 /**
  ** Regular capabilities (normally possessed by all processes).
diff --git a/include/linux/security.h b/include/linux/security.h
index 6bc2aad..265ab00 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -51,6 +51,10 @@ extern int cap_inode_setxattr(struct den
 extern int cap_inode_removexattr(struct dentry *dentry, char *name);
 extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
 extern void cap_task_reparent_to_init (struct task_struct *p);
+extern int cap_task_kill(struct task_struct *p, struct siginfo *info, int sig, u32 secid);
+extern int cap_task_setscheduler (struct task_struct *p, int policy, struct sched_param *lp);
+extern int cap_task_setioprio (struct task_struct *p, int ioprio);
+extern int cap_task_setnice (struct task_struct *p, int nice);
 extern int cap_syslog (int type);
 extern int cap_vm_enough_memory (long pages);
 
@@ -2544,12 +2548,12 @@ static inline int security_task_setgroup
 
 static inline int security_task_setnice (struct task_struct *p, int nice)
 {
-	return 0;
+	return cap_task_setnice(p, nice);
 }
 
 static inline int security_task_setioprio (struct task_struct *p, int ioprio)
 {
-	return 0;
+	return cap_task_setioprio(p, ioprio);
 }
 
 static inline int security_task_getioprio (struct task_struct *p)
@@ -2584,7 +2588,7 @@ static inline int security_task_kill (st
 				      struct siginfo *info, int sig,
 				      u32 secid)
 {
-	return 0;
+	return cap_task_kill(p, info, sig, secid);
 }
 
 static inline int security_task_wait (struct task_struct *p)
diff --git a/security/Kconfig b/security/Kconfig
index 67785df..ce2bac7 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -80,6 +80,16 @@ config SECURITY_CAPABILITIES
 	  This enables the "default" Linux capabilities functionality.
 	  If you are unsure how to answer this question, answer Y.
 
+config SECURITY_FS_CAPABILITIES
+	bool "Filesystem Capabilities"
+	depends on SECURITY_CAPABILITIES
+	default n
+	help
+	  This enables filesystem capabilities, allowing you to give
+	  binaries a subset of root's powers without using setuid 0.
+
+	  If in doubt, answer N.
+
 config SECURITY_ROOTPLUG
 	tristate "Root Plug Support"
 	depends on USB && SECURITY
diff --git a/security/capability.c b/security/capability.c
index b868e7e..14cb592 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -40,6 +40,10 @@ static struct security_operations capabi
 	.inode_setxattr =		cap_inode_setxattr,
 	.inode_removexattr =		cap_inode_removexattr,
 
+	.task_kill =			cap_task_kill,
+	.task_setscheduler =		cap_task_setscheduler,
+	.task_setioprio =		cap_task_setioprio,
+	.task_setnice =			cap_task_setnice,
 	.task_post_setuid =		cap_task_post_setuid,
 	.task_reparent_to_init =	cap_task_reparent_to_init,
 
diff --git a/security/commoncap.c b/security/commoncap.c
index 291a4bd..1988efc 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -24,6 +24,7 @@ #include <linux/netlink.h>
 #include <linux/ptrace.h>
 #include <linux/xattr.h>
 #include <linux/hugetlb.h>
+#include <linux/mount.h>
 
 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
 {
@@ -112,11 +113,55 @@ void cap_capset_set (struct task_struct 
 	target->cap_permitted = *permitted;
 }
 
+#define XATTR_CAPS_SUFFIX "capability"
+#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
+struct vfs_cap_data_struct {
+	__u32 version;
+	__u32 effective;
+	__u32 permitted;
+	__u32 inheritable;
+};
+
+static inline void convert_to_le(struct vfs_cap_data_struct *cap)
+{
+	cap->version = le32_to_cpu(cap->version);
+	cap->effective = le32_to_cpu(cap->effective);
+	cap->permitted = le32_to_cpu(cap->permitted);
+	cap->inheritable = le32_to_cpu(cap->inheritable);
+}
+
+static int check_cap_sanity(struct vfs_cap_data_struct *cap)
+{
+	int i;
+
+	if (cap->version != _LINUX_CAPABILITY_OLD_VERSION)
+		return -EPERM;
+
+	for (i=CAP_NUMCAPS_SYS; i<sizeof(cap->effective); i++) {
+		if (cap->effective & CAP_TO_MASK(i))
+			return -EPERM;
+	}
+	for (i=CAP_NUMCAPS_SYS; i<sizeof(cap->permitted); i++) {
+		if (cap->permitted & CAP_TO_MASK(i))
+			return -EPERM;
+	}
+	for (i=CAP_NUMCAPS_SYS; i<sizeof(cap->inheritable); i++) {
+		if (cap->inheritable & CAP_TO_MASK(i))
+			return -EPERM;
+	}
+
+	return 0;
+}
+
 int cap_bprm_set_security (struct linux_binprm *bprm)
 {
+	struct dentry *dentry;
+	ssize_t rc;
+	struct vfs_cap_data_struct cap_struct;
+	struct inode *inode;
+
 	/* Copied from fs/exec.c:prepare_binprm. */
 
-	/* We don't have VFS support for capabilities yet */
 	cap_set_full (bprm->cap_inheritable);
 	cap_clear (bprm->cap_permitted);
 	cap_set_full (bprm->cap_effective);
@@ -152,6 +197,53 @@ int cap_bprm_set_security (struct linux_
 		}
 	}
 
+#ifdef CONFIG_SECURITY_FS_CAPABILITIES
+	/* Locate any VFS capabilities: */
+
+	dentry = dget(bprm->file->f_dentry);
+	inode = dentry->d_inode;
+	if (!inode->i_op || !inode->i_op->getxattr) {
+		dput(dentry);
+		return 0;
+	}
+
+	rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, &cap_struct,
+						sizeof(cap_struct));
+	dput(dentry);
+
+	if (rc == -ENODATA)
+		return 0;
+
+	if (rc < 0) {
+		printk(KERN_NOTICE "%s: Error (%ld) getting xattr\n",
+				__FUNCTION__, (long int)rc);
+		return rc;
+	}
+
+	if (rc != sizeof(cap_struct)) {
+		printk(KERN_NOTICE "%s: got wrong size for getxattr (%ld)\n",
+					__FUNCTION__, (long int)rc);
+		return -EPERM;
+	}
+	
+	convert_to_le(&cap_struct);
+	if (check_cap_sanity(&cap_struct))
+		return -EPERM;
+
+	bprm->cap_effective = cap_combine (cap_intersect (bprm->cap_effective,
+							  CAP_REGULAR_SET),
+					   to_cap_t(cap_struct.effective));
+	bprm->cap_permitted = cap_combine (cap_intersect (bprm->cap_permitted,
+							  CAP_REGULAR_SET),
+					   to_cap_t(cap_struct.permitted));
+	if (!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)
+	    || !capable(CAP_REG_SXID)) /* Don't allow to gain privileges! */
+		cap_clear (bprm->cap_permitted);
+	bprm->cap_inheritable = cap_combine (cap_intersect (bprm->cap_inheritable,
+							    CAP_REGULAR_SET),
+					     to_cap_t(cap_struct.inheritable));
+
+#endif
 	return 0;
 }
 
@@ -340,6 +432,62 @@ int cap_task_post_setuid (uid_t old_ruid
 	return 0;
 }
 
+/*
+ * Rationale: code calling task_setscheduler, task_setioprio, and
+ * task_setnice, assumes that
+ *   . if capable(cap_sys_nice), then those actions should be allowed
+ *   . if not capable(cap_sys_nice), but acting on your own processes,
+ *   	then those actions should be allowed
+ * This is insufficient now since you can call code without suid, but
+ * yet with increased caps.
+ * So we check for increased caps on the target process.
+ */
+static inline int cap_safe_nice(struct task_struct *p)
+{
+	if (!cap_issubset(p->cap_permitted, current->cap_permitted) &&
+	    !__capable(current, CAP_SYS_NICE))
+		return -EPERM;
+	return 0;
+}
+
+int cap_task_setscheduler (struct task_struct *p, int policy,
+			   struct sched_param *lp)
+{
+	return cap_safe_nice(p);
+}
+
+int cap_task_setioprio (struct task_struct *p, int ioprio)
+{
+	return cap_safe_nice(p);
+}
+
+int cap_task_setnice (struct task_struct *p, int nice)
+{
+	return cap_safe_nice(p);
+}
+
+int cap_task_kill(struct task_struct *p, struct siginfo *info,
+				int sig, u32 secid)
+{
+	if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
+		return 0;
+
+	if (secid)
+		/*
+		 * Signal sent as a particular user.
+		 * Capabilities are ignored.  May be wrong, but it's the
+		 * only thing we can do at the moment.
+		 * Used only by usb drivers?
+		 */
+		return 0;
+	if (capable(CAP_KILL))
+		return 0;
+	if (cap_issubset(p->cap_permitted, current->cap_permitted))
+		return 0;
+
+	return -EPERM;
+}
+
 void cap_task_reparent_to_init (struct task_struct *p)
 {
 	p->cap_effective = CAP_INIT_EFF_SET;
@@ -377,6 +525,10 @@ EXPORT_SYMBOL(cap_bprm_secureexec);
 EXPORT_SYMBOL(cap_inode_setxattr);
 EXPORT_SYMBOL(cap_inode_removexattr);
 EXPORT_SYMBOL(cap_task_post_setuid);
+EXPORT_SYMBOL(cap_task_kill);
+EXPORT_SYMBOL(cap_task_setscheduler);
+EXPORT_SYMBOL(cap_task_setioprio);
+EXPORT_SYMBOL(cap_task_setnice);
 EXPORT_SYMBOL(cap_task_reparent_to_init);
 EXPORT_SYMBOL(cap_syslog);
 EXPORT_SYMBOL(cap_vm_enough_memory);

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-10 16:23   ` Alan Cox
@ 2006-09-10 16:09     ` David Madore
  2006-09-11  8:06       ` James Morris
  2006-09-10 17:56     ` Joshua Brindle
  1 sibling, 1 reply; 29+ messages in thread
From: David Madore @ 2006-09-10 16:09 UTC (permalink / raw)
  To: Alan Cox; +Cc: Linux Kernel mailing-list, LSM mailing-list

On Sun, Sep 10, 2006 at 05:23:13PM +0100, Alan Cox wrote:
> CAP_REG_EXEC seems meaningless, I can do the same with mmap by hand for
> most types of binary execution except setuid (which is separate it
> seems)

Actually I meant those caps to be more of a proof of concept than as a
really useful set, so I have nothing against CAP_REG_EXEC being
deleted.  However, it still performs one (small) function even in the
absence of suid/sgid executables: you can execute files with omde --x
which you can't do with mmap().  (Also, I'm not 100% sure the kernel
doesn't do some magic things on exec(), perhaps some magic forms of
accounting or whatever, which you couldn't do with mmap().)

> Given the capability model is accepted as inferior to things like
> SELinux policies why do we actually want to fix this anyway. It's
> unfortunate we can't discard the existing capabilities model (which has
> flaws) as well really.

Can a non-root user create limited-rights processes without assistance
from the sysadmin, under SElinux?  I was under the impression that it
wasn't the case.  Also, SElinux is immensely more difficult to
understand and operate with than a mere set of capabilities: and I
think that simplicity is (sometimes) of value.

-- 
     David A. Madore
    (david.madore@ens.fr,
     http://www.madore.org/~david/ )

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-10 13:42 ` [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities David Madore
@ 2006-09-10 16:23   ` Alan Cox
  2006-09-10 16:09     ` David Madore
  2006-09-10 17:56     ` Joshua Brindle
  0 siblings, 2 replies; 29+ messages in thread
From: Alan Cox @ 2006-09-10 16:23 UTC (permalink / raw)
  To: David Madore; +Cc: Linux Kernel mailing-list, LSM mailing-list

Ar Sul, 2006-09-10 am 15:42 +0200, ysgrifennodd David Madore:
> Introduce six new "regular" (=on-by-default) capabilities:
> 
>  * CAP_REG_FORK, CAP_REG_OPEN, CAP_REG_EXEC allow access to the
>    fork(), open() and exec() syscalls,

CAP_REG_EXEC seems meaningless, I can do the same with mmap by hand for
most types of binary execution except setuid (which is separate it
seems)

Given the capability model is accepted as inferior to things like
SELinux policies why do we actually want to fix this anyway. It's
unfortunate we can't discard the existing capabilities model (which has
flaws) as well really.

Alan


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-10 16:23   ` Alan Cox
  2006-09-10 16:09     ` David Madore
@ 2006-09-10 17:56     ` Joshua Brindle
  2006-09-10 20:03       ` David Madore
  2006-09-17 18:14       ` Pavel Machek
  1 sibling, 2 replies; 29+ messages in thread
From: Joshua Brindle @ 2006-09-10 17:56 UTC (permalink / raw)
  To: Alan Cox; +Cc: David Madore, Linux Kernel mailing-list, LSM mailing-list

Alan Cox wrote:
> Ar Sul, 2006-09-10 am 15:42 +0200, ysgrifennodd David Madore:
>   
>> Introduce six new "regular" (=on-by-default) capabilities:
>>
>>  * CAP_REG_FORK, CAP_REG_OPEN, CAP_REG_EXEC allow access to the
>>    fork(), open() and exec() syscalls,
>>     
>
> CAP_REG_EXEC seems meaningless, I can do the same with mmap by hand for
> most types of binary execution except setuid (which is separate it
> seems)
>
> Given the capability model is accepted as inferior to things like
> SELinux policies why do we actually want to fix this anyway. It's
> unfortunate we can't discard the existing capabilities model (which has
> flaws) as well really.
>
>   
To expand on this a little, some of the capabilities you are looking to 
add are of very little if any use without being able to specify objects. 
For example, CAP_REG_OPEN is whether the process can open any file 
instead of specific ones. How many applications open no files whatsoever 
in practice? Even if there are some as soon as they change and need to 
open a file they'll need this capability and will be able to open any. 
CAP_REG_WRITE has the same problem. For a description of why 
CAP_REG_EXEC is meaningless see the digsig thread on the LSM list from 
earlier this year.

Further, adding more capabilities would likely make existing LSM's (like 
SELinux) deal with them. Since most LSM's already handle these 
permissions on a per-object basis these will be entirely redundant and 
more disruptive than useful.

Additionally since dropping capabilities is entirely discretionary and 
applications would be modified to actually drop the capabilities I can't 
ever see this being used in practice. It also embeds the policy into 
applications spread across the filesystem instead of having a 
centralized policy.  Since these are non-standard capabilities any 
application modified to take advantage of them could only do so on Linux.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-10 17:56     ` Joshua Brindle
@ 2006-09-10 20:03       ` David Madore
  2006-09-11  6:10         ` Jan Engelhardt
  2006-09-11 13:42         ` Stephen Smalley
  2006-09-17 18:14       ` Pavel Machek
  1 sibling, 2 replies; 29+ messages in thread
From: David Madore @ 2006-09-10 20:03 UTC (permalink / raw)
  To: Joshua Brindle; +Cc: Linux Kernel mailing-list, LSM mailing-list

On Sun, Sep 10, 2006 at 01:56:43PM -0400, Joshua Brindle wrote:
> To expand on this a little, some of the capabilities you are looking to 
> add are of very little if any use without being able to specify objects. 
> For example, CAP_REG_OPEN is whether the process can open any file 
> instead of specific ones. How many applications open no files whatsoever 
> in practice? Even if there are some as soon as they change and need to 
> open a file they'll need this capability and will be able to open any. 
> CAP_REG_WRITE has the same problem. For a description of why 
> CAP_REG_EXEC is meaningless see the digsig thread on the LSM list from 
> earlier this year.

CAP_REG_OPEN and CAP_REG_EXEC might be useful only for demonstration
purposes, but I've *often* wished I could run a program without
CAP_REG_WRITE because I wasn't root and I wanted to make *sure* it
didn't write any file anywhere.  Instead I had to run them from a
user-mode-linux, which is horribly messy and doesn't work well (and,
at best, with a noticeable slowdown).

Again, I ask: is SElinux useable if you aren't root?  (Assuming it's
activated, of course: I mean, can you create new policies to make
certain programs run with restricted privileges?)  I thought it
wasn't, but maybe I'm wrong.

-- 
     David A. Madore
    (david.madore@ens.fr,
     http://www.madore.org/~david/ )

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-10 20:03       ` David Madore
@ 2006-09-11  6:10         ` Jan Engelhardt
  2006-09-11  6:51           ` David Madore
  2006-09-11 13:42         ` Stephen Smalley
  1 sibling, 1 reply; 29+ messages in thread
From: Jan Engelhardt @ 2006-09-11  6:10 UTC (permalink / raw)
  To: David Madore; +Cc: Joshua Brindle, Linux Kernel mailing-list, LSM mailing-list


>> To expand on this a little, some of the capabilities you are looking to 
>> add are of very little if any use without being able to specify objects. 
>> For example, CAP_REG_OPEN is whether the process can open any file 
>> instead of specific ones. How many applications open no files whatsoever 
>> in practice? Even if there are some as soon as they change and need to 
>> open a file they'll need this capability and will be able to open any. 
>> CAP_REG_WRITE has the same problem. For a description of why 
>> CAP_REG_EXEC is meaningless see the digsig thread on the LSM list from 
>> earlier this year.
>
>CAP_REG_OPEN and CAP_REG_EXEC might be useful only for demonstration
>purposes, but I've *often* wished I could run a program without

You cannot reasonable run a program without CAP_REG_OPEN, because 
ld.so, libc.so and libdl.so all may load a ton of required files 
underneath you.

$ strace -e open ls 2>&1 >/dev/null | grep open | wc -l
36



Jan Engelhardt
-- 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-11  6:10         ` Jan Engelhardt
@ 2006-09-11  6:51           ` David Madore
  0 siblings, 0 replies; 29+ messages in thread
From: David Madore @ 2006-09-11  6:51 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Linux Kernel mailing-list, LSM mailing-list

On Mon, Sep 11, 2006 at 08:10:17AM +0200, Jan Engelhardt wrote:
> You cannot reasonable run a program without CAP_REG_OPEN, because 
> ld.so, libc.so and libdl.so all may load a ton of required files 
> underneath you.

A program might quite conceivably drop CAP_REG_OPEN willingly once
it's started, or the administrator might use capset() on it once it's
running.  But, again, this cap is mostly a proof of concept: the
really useful ones are CAP_REG_WRITE and CAP_REG_SXID.

-- 
     David A. Madore
    (david.madore@ens.fr,
     http://www.madore.org/~david/ )

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-10 16:09     ` David Madore
@ 2006-09-11  8:06       ` James Morris
  2006-09-11 12:03         ` Joshua Brindle
  0 siblings, 1 reply; 29+ messages in thread
From: James Morris @ 2006-09-11  8:06 UTC (permalink / raw)
  To: David Madore; +Cc: Alan Cox, Linux Kernel mailing-list, LSM mailing-list

On Sun, 10 Sep 2006, David Madore wrote:

> Can a non-root user create limited-rights processes without assistance
> from the sysadmin, under SElinux?

SELinux uses a restrictive model, where privileges can only be removed, 
not added.



- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-11  8:06       ` James Morris
@ 2006-09-11 12:03         ` Joshua Brindle
  2006-09-11 16:22           ` Casey Schaufler
  2006-09-17 18:06           ` Pavel Machek
  0 siblings, 2 replies; 29+ messages in thread
From: Joshua Brindle @ 2006-09-11 12:03 UTC (permalink / raw)
  To: James Morris
  Cc: David Madore, Alan Cox, Linux Kernel mailing-list, LSM mailing-list

James Morris wrote:
> On Sun, 10 Sep 2006, David Madore wrote:
>
>   
>> Can a non-root user create limited-rights processes without assistance
>> from the sysadmin, under SElinux?
>>     
>
> SELinux uses a restrictive model, where privileges can only be removed, 
> not added.
>
>   
I think he was asking if a non-admin user can create processes of less 
privilege without becoming root. The answer is yes, however, it is 
policy driven. Users will have numerous 'derived' types that are less 
privilege than, for example, their interactive shell. For example, 
user_irc_t or user_evolution_t. The transitions will happen when the 
user runs irc or evolution and those apps will be limited to the rights 
they require. These are fine grained though, and mandatory. These 
capabilities are so course grained I just can't see anyone ever using them.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-10 20:03       ` David Madore
  2006-09-11  6:10         ` Jan Engelhardt
@ 2006-09-11 13:42         ` Stephen Smalley
  1 sibling, 0 replies; 29+ messages in thread
From: Stephen Smalley @ 2006-09-11 13:42 UTC (permalink / raw)
  To: David Madore; +Cc: Joshua Brindle, Linux Kernel mailing-list, LSM mailing-list

On Sun, 2006-09-10 at 22:03 +0200, David Madore wrote:
> On Sun, Sep 10, 2006 at 01:56:43PM -0400, Joshua Brindle wrote:
> > To expand on this a little, some of the capabilities you are looking to 
> > add are of very little if any use without being able to specify objects. 
> > For example, CAP_REG_OPEN is whether the process can open any file 
> > instead of specific ones. How many applications open no files whatsoever 
> > in practice? Even if there are some as soon as they change and need to 
> > open a file they'll need this capability and will be able to open any. 
> > CAP_REG_WRITE has the same problem. For a description of why 
> > CAP_REG_EXEC is meaningless see the digsig thread on the LSM list from 
> > earlier this year.
> 
> CAP_REG_OPEN and CAP_REG_EXEC might be useful only for demonstration
> purposes, but I've *often* wished I could run a program without
> CAP_REG_WRITE because I wasn't root and I wanted to make *sure* it
> didn't write any file anywhere.  Instead I had to run them from a
> user-mode-linux, which is horribly messy and doesn't work well (and,
> at best, with a noticeable slowdown).
> 
> Again, I ask: is SElinux useable if you aren't root?  (Assuming it's
> activated, of course: I mean, can you create new policies to make
> certain programs run with restricted privileges?)  I thought it
> wasn't, but maybe I'm wrong.

At present, you can't load new policy into the kernel without being
privileged (where privileged == root + SELinux load_policy permission),
but there is ongoing work on a policy management daemon that will enable
delegation of control of portions of the policy to others, including the
ability to enable a user to define subtypes of his own authorized types
with more limited permissions via the already existing hierarchical type
support in the policy language.

In any event, I didn't see anything in your patches to allow SELinux to
continue working with your 64-bit capabilities, and I'm not sure why you
are implementing your changes as a direct patch vs. a new security
module (with additional LSM hooks if truly required, but trying to reuse
existing hooks whenever possible), so that your changes remain optional
at least until proven useful.

I also have to question whether it is a good idea to keep these new
unprivileged "regular" capabilities in the same vectors as the existing
privileged ones, given that they have rather different semantics.  Also,
if you want capabilities to be more useful, you likely want to expand
the set of privileged capabilities in the future (e.g. to partition some
of the more coarse-grained ones), and you aren't leaving room for such
expansion.  At least for SELinux, we would split them into a separate
security class altogether rather than expanding all access vectors to 64
bits.  If you implement your changes in your own security module, then
you can store your regular capability bits in your own security
structure referenced via the security fields, and not have to touch the
base capability fields.

-- 
Stephen Smalley
National Security Agency


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-11 12:03         ` Joshua Brindle
@ 2006-09-11 16:22           ` Casey Schaufler
  2006-09-17 18:06           ` Pavel Machek
  1 sibling, 0 replies; 29+ messages in thread
From: Casey Schaufler @ 2006-09-11 16:22 UTC (permalink / raw)
  To: Joshua Brindle; +Cc: Linux Kernel mailing-list, LSM mailing-list



--- Joshua Brindle <method@gentoo.org> wrote:

> These 
> capabilities are so course grained I just can't see
> anyone ever using them.

The granularity of the capabilities in the POSIX
DRAFT is targeted at the security policy enforced
by the POSIX P1003.1 interface standard. Anywhere
that P1003.1 says "appropriate privilege" P1003.1e
identifies what that privilege ought to be. The
capability specification also addresses the audit,
MAC and INF portions of P1003.1e. Interfaces
that were outside the scope of P1003.1 at the
time (including, alas, sockets and SVIPC) could
not be included in P1003.1e by rule. Devices
and filesystems, where most of the granularity
issues arise, were excluded.

The 1e DRAFT specifies a granularity that is
appropriate to the kernel and the policies that
the kernel enforces. This is because the
capability mechanism is supposed to be a kernel
protection scheme for kernel objects.
It does not enforce a granularity that is
appropriate to a python based web interface
for financial management systems. That is an
application issue that is much better suited
to application controls like RBAC.



Casey Schaufler
casey@schaufler-ca.com

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-11 12:03         ` Joshua Brindle
  2006-09-11 16:22           ` Casey Schaufler
@ 2006-09-17 18:06           ` Pavel Machek
  1 sibling, 0 replies; 29+ messages in thread
From: Pavel Machek @ 2006-09-17 18:06 UTC (permalink / raw)
  To: Joshua Brindle
  Cc: James Morris, David Madore, Alan Cox, Linux Kernel mailing-list,
	LSM mailing-list

Hi!

> >>Can a non-root user create limited-rights processes without assistance
> >>from the sysadmin, under SElinux?
> >
> >SELinux uses a restrictive model, where privileges can only be removed, 
> >not added.
> >
> >  
> I think he was asking if a non-admin user can create processes of less 
> privilege without becoming root. The answer is yes, however, it is 
> policy driven. Users will have numerous 'derived' types that are less 
> privilege than, for example, their interactive shell. For example, 
> user_irc_t or user_evolution_t. The transitions will happen when the 
> user runs irc or evolution and those apps will be limited to the rights 
> they require. These are fine grained though, and mandatory. These 
> capabilities are so course grained I just can't see anyone ever using them.

Andrea already has his "seccomp" thing in kernel.... which is
basically "running without _any_ rights". So yes, this is useful.

								Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-10 17:56     ` Joshua Brindle
  2006-09-10 20:03       ` David Madore
@ 2006-09-17 18:14       ` Pavel Machek
  2006-09-17 20:39         ` Joshua Brindle
  1 sibling, 1 reply; 29+ messages in thread
From: Pavel Machek @ 2006-09-17 18:14 UTC (permalink / raw)
  To: Joshua Brindle
  Cc: Alan Cox, David Madore, Linux Kernel mailing-list, LSM mailing-list

Hi!

> >>Introduce six new "regular" (=on-by-default) capabilities:
> >>
> >> * CAP_REG_FORK, CAP_REG_OPEN, CAP_REG_EXEC allow access to the
> >>   fork(), open() and exec() syscalls,
> >>    
> >
> >CAP_REG_EXEC seems meaningless, I can do the same with mmap by hand for
> >most types of binary execution except setuid (which is separate it
> >seems)
> >
> >Given the capability model is accepted as inferior to things like
> >SELinux policies why do we actually want to fix this anyway. It's
> >unfortunate we can't discard the existing capabilities model (which has
> >flaws) as well really.

> To expand on this a little, some of the capabilities you are looking to 
> add are of very little if any use without being able to specify objects. 
> For example, CAP_REG_OPEN is whether the process can open any file 
> instead of specific ones. How many applications open no files whatsoever 
> in practice? 

Filters, for example. gzip -9 - and such stuff does not need to open
any files. These should be easy to lock down, and still very useful.

More applications could be made lock-down-aware, and for example ask
master daemon to open files for them over a (already opened) socket.

								Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-17 18:14       ` Pavel Machek
@ 2006-09-17 20:39         ` Joshua Brindle
  2006-09-17 21:16           ` David Madore
  0 siblings, 1 reply; 29+ messages in thread
From: Joshua Brindle @ 2006-09-17 20:39 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Alan Cox, David Madore, Linux Kernel mailing-list, LSM mailing-list

Pavel Machek wrote:
> Hi!
>
>   
>>>> Introduce six new "regular" (=on-by-default) capabilities:
>>>>
>>>> * CAP_REG_FORK, CAP_REG_OPEN, CAP_REG_EXEC allow access to the
>>>>   fork(), open() and exec() syscalls,
>>>>    
>>>>         
>>> CAP_REG_EXEC seems meaningless, I can do the same with mmap by hand for
>>> most types of binary execution except setuid (which is separate it
>>> seems)
>>>
>>> Given the capability model is accepted as inferior to things like
>>> SELinux policies why do we actually want to fix this anyway. It's
>>> unfortunate we can't discard the existing capabilities model (which has
>>> flaws) as well really.
>>>       
>
>   
>> To expand on this a little, some of the capabilities you are looking to 
>> add are of very little if any use without being able to specify objects. 
>> For example, CAP_REG_OPEN is whether the process can open any file 
>> instead of specific ones. How many applications open no files whatsoever 
>> in practice? 
>>     
>
> Filters, for example. gzip -9 - and such stuff does not need to open
> any files. These should be easy to lock down, and still very useful.
>
> More applications could be made lock-down-aware, and for example ask
> master daemon to open files for them over a (already opened) socket.
>
>   
Unlikely.. As Jan pointed out in the last thread anything that links 
against glibc does a dozen opens on invocation:
[jbrindle@twoface ~]$ strace -eopen gzip -9 -   
open("/usr/lib64/fglrx/tls/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No 
such file or directory)
open("/usr/lib64/fglrx/tls/libc.so.6", O_RDONLY) = -1 ENOENT (No such 
file or directory)
open("/usr/lib64/fglrx/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such 
file or directory)
open("/usr/lib64/fglrx/libc.so.6", O_RDONLY) = -1 ENOENT (No such file 
or directory)
open("/usr/lib/fglrx/tls/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No 
such file or directory)
open("/usr/lib/fglrx/tls/libc.so.6", O_RDONLY) = -1 ENOENT (No such file 
or directory)
open("/usr/lib/fglrx/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such 
file or directory)
open("/usr/lib/fglrx/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or 
directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib64/libc.so.6", O_RDONLY)      = 3
gzip: compressed data not written to a terminal. Use -f to force 
compression.
For help, type: gzip -h
Process 17519 detached

this wouldn't be able to run if it couldn't open libc.so so you'd be 
limited to static binaries (with statically linked libs that don't do 
any open() calls) that don't do any kind of name resolution (ip, uid), 
have no config files, etc. very limited.. and my other point was that 
even if you did have said binary (the limitations make this very 
unlikely though) the binary could never be changed to open a file since 
it would then get all open access since capabilities are not fine grained.

The benefits of this are so minuscule and the cost is so high if you are 
ever to use it that it simply won't happen..

Joshua Brindle

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-17 20:39         ` Joshua Brindle
@ 2006-09-17 21:16           ` David Madore
  2006-09-18 11:46             ` Joshua Brindle
  0 siblings, 1 reply; 29+ messages in thread
From: David Madore @ 2006-09-17 21:16 UTC (permalink / raw)
  To: Joshua Brindle
  Cc: Pavel Machek, Alan Cox, Linux Kernel mailing-list, LSM mailing-list

On Sun, Sep 17, 2006 at 04:39:16PM -0400, Joshua Brindle wrote:
> The benefits of this are so minuscule and the cost is so high if you are 
> ever to use it that it simply won't happen..

I'm withdrawing that patch anyway, in favor of a LSM-style approach,
the "cuppabilities" module (cf. the patch I posted a couple of hours
ago with that word in the title, and I'll be posting a new version in
a day or so, or cf. <URL:
http://www.madore.org/~david/linux/cuppabilities/
 >).  In this case, the relative cost will be lower since the
security_ops->inode_permission() hook is called no matter what.

But I agree that the value of restricting open() is very dubious and
it was intended mostly as a demonstration.  So if there is strong
opposition to this sort of thing, I'll remove it.

Happy hacking,

-- 
     David A. Madore
    (david.madore@ens.fr,
     http://www.madore.org/~david/ )

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-17 21:16           ` David Madore
@ 2006-09-18 11:46             ` Joshua Brindle
  2006-09-18 11:58               ` David Madore
                                 ` (2 more replies)
  0 siblings, 3 replies; 29+ messages in thread
From: Joshua Brindle @ 2006-09-18 11:46 UTC (permalink / raw)
  To: David Madore
  Cc: Pavel Machek, Alan Cox, Linux Kernel mailing-list, LSM mailing-list

On Sun, 2006-09-17 at 23:16 +0200, David Madore wrote:
> On Sun, Sep 17, 2006 at 04:39:16PM -0400, Joshua Brindle wrote:
> > The benefits of this are so minuscule and the cost is so high if you are 
> > ever to use it that it simply won't happen..
> 
> I'm withdrawing that patch anyway, in favor of a LSM-style approach,
> the "cuppabilities" module (cf. the patch I posted a couple of hours
> ago with that word in the title, and I'll be posting a new version in
> a day or so, or cf. <URL:
> http://www.madore.org/~david/linux/cuppabilities/
>  >).  In this case, the relative cost will be lower since the
> security_ops->inode_permission() hook is called no matter what.
> 

You misunderstand. I don't mean the performance cost is high, I mean the
cost of an application to actually be able to run without open() (what I
was saying before, static built, no glibc, no conf files, no name
lookups, etc). I never see this being used in the real world because of
the extreme limitations.

And that is just practical stuff, there are still problems with
embedding policy into binaries all over the system in an entirely
non-analyzable way, and this extends to all capabilities, not just the
open() one.

> But I agree that the value of restricting open() is very dubious and
> it was intended mostly as a demonstration.  So if there is strong
> opposition to this sort of thing, I'll remove it.
> 
> Happy hacking,
> 


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-18 11:46             ` Joshua Brindle
@ 2006-09-18 11:58               ` David Madore
  2006-09-18 12:04               ` Pavel Machek
  2006-09-18 16:02               ` Casey Schaufler
  2 siblings, 0 replies; 29+ messages in thread
From: David Madore @ 2006-09-18 11:58 UTC (permalink / raw)
  To: Joshua Brindle
  Cc: Pavel Machek, Alan Cox, Linux Kernel mailing-list, LSM mailing-list

On Mon, Sep 18, 2006 at 07:46:06AM -0400, Joshua Brindle wrote:
> And that is just practical stuff, there are still problems with
> embedding policy into binaries all over the system in an entirely
> non-analyzable way, and this extends to all capabilities, not just the
> open() one.

Some people prefer the policy to be embedded into binaries all over
the system rather than centralized in one place.  I think it's just a
question of choice: if you don't like this way of doing things, you
don't have to use it, of course (my "cuppabilities" module would be
entirely optional).

Happy hacking,

-- 
     David A. Madore
    (david.madore@ens.fr,
     http://www.madore.org/~david/ )

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-18 11:46             ` Joshua Brindle
  2006-09-18 11:58               ` David Madore
@ 2006-09-18 12:04               ` Pavel Machek
  2006-09-18 12:12                 ` Joshua Brindle
  2006-09-18 16:02               ` Casey Schaufler
  2 siblings, 1 reply; 29+ messages in thread
From: Pavel Machek @ 2006-09-18 12:04 UTC (permalink / raw)
  To: Joshua Brindle
  Cc: David Madore, Alan Cox, Linux Kernel mailing-list, LSM mailing-list

Hi!

> > > The benefits of this are so minuscule and the cost is so high if you are 
> > > ever to use it that it simply won't happen..
> > 
> > I'm withdrawing that patch anyway, in favor of a LSM-style approach,
> > the "cuppabilities" module (cf. the patch I posted a couple of hours
> > ago with that word in the title, and I'll be posting a new version in
> > a day or so, or cf. <URL:
> > http://www.madore.org/~david/linux/cuppabilities/
> >  >).  In this case, the relative cost will be lower since the
> > security_ops->inode_permission() hook is called no matter what.
> > 
> 
> You misunderstand. I don't mean the performance cost is high, I mean the
> cost of an application to actually be able to run without open() (what I
> was saying before, static built, no glibc, no conf files, no name
> lookups, etc). I never see this being used in the real world because of
> the extreme limitations.

It is already being used. See config_seccomp.
								Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-18 12:04               ` Pavel Machek
@ 2006-09-18 12:12                 ` Joshua Brindle
  0 siblings, 0 replies; 29+ messages in thread
From: Joshua Brindle @ 2006-09-18 12:12 UTC (permalink / raw)
  To: Pavel Machek
  Cc: David Madore, Alan Cox, Linux Kernel mailing-list, LSM mailing-list

On Mon, 2006-09-18 at 14:04 +0200, Pavel Machek wrote:
> Hi!
> 
> > > > The benefits of this are so minuscule and the cost is so high if you are 
> > > > ever to use it that it simply won't happen..
> > > 
> > > I'm withdrawing that patch anyway, in favor of a LSM-style approach,
> > > the "cuppabilities" module (cf. the patch I posted a couple of hours
> > > ago with that word in the title, and I'll be posting a new version in
> > > a day or so, or cf. <URL:
> > > http://www.madore.org/~david/linux/cuppabilities/
> > >  >).  In this case, the relative cost will be lower since the
> > > security_ops->inode_permission() hook is called no matter what.
> > > 
> > 
> > You misunderstand. I don't mean the performance cost is high, I mean the
> > cost of an application to actually be able to run without open() (what I
> > was saying before, static built, no glibc, no conf files, no name
> > lookups, etc). I never see this being used in the real world because of
> > the extreme limitations.
> 
> It is already being used. See config_seccomp.

Where are the users?


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-18 11:46             ` Joshua Brindle
  2006-09-18 11:58               ` David Madore
  2006-09-18 12:04               ` Pavel Machek
@ 2006-09-18 16:02               ` Casey Schaufler
  2006-09-19  0:25                 ` Joshua Brindle
  2 siblings, 1 reply; 29+ messages in thread
From: Casey Schaufler @ 2006-09-18 16:02 UTC (permalink / raw)
  To: Joshua Brindle, David Madore
  Cc: Pavel Machek, Alan Cox, Linux Kernel mailing-list, LSM mailing-list


--- Joshua Brindle <method@gentoo.org> wrote:

> And that is just practical stuff, there are still
> problems with
> embedding policy into binaries all over the system
> in an entirely
> non-analyzable way, and this extends to all
> capabilities, not just the
> open() one.

Your assertion that directly associating
the capabilities with the binary cannot
be analysed is demonstrably incorrect,
reference Common Criteria validation
reports CCEVS-VR-02-0019 and CCEVS-VR-02-0020.
 
The first system I took through evaluation
(that is, independent 3rd party analysis) stored
security attributes in a file while the second
and third systems attached the attributes
directly (XFS). The 1st evaluation required
5 years, the 2nd 1 year. It is possible that
I just got a lot smarter with age, but I
ascribe a significant amount of the improvement
to the direct association of the attributes
to the file.



Casey Schaufler
casey@schaufler-ca.com

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-18 16:02               ` Casey Schaufler
@ 2006-09-19  0:25                 ` Joshua Brindle
  2006-09-19  3:46                   ` Casey Schaufler
  2006-09-19 18:27                   ` Pavel Machek
  0 siblings, 2 replies; 29+ messages in thread
From: Joshua Brindle @ 2006-09-19  0:25 UTC (permalink / raw)
  To: casey
  Cc: David Madore, Pavel Machek, Alan Cox, Linux Kernel mailing-list,
	LSM mailing-list

Casey Schaufler wrote:
> --- Joshua Brindle <method@gentoo.org> wrote:
>
>   
>> And that is just practical stuff, there are still
>> problems with
>> embedding policy into binaries all over the system
>> in an entirely
>> non-analyzable way, and this extends to all
>> capabilities, not just the
>> open() one.
>>     
>
> Your assertion that directly associating
> the capabilities with the binary cannot
> be analysed is demonstrably incorrect,
> reference Common Criteria validation
> reports CCEVS-VR-02-0019 and CCEVS-VR-02-0020.
>  
> The first system I took through evaluation
> (that is, independent 3rd party analysis) stored
> security attributes in a file while the second
> and third systems attached the attributes
> directly (XFS). The 1st evaluation required
> 5 years, the 2nd 1 year. It is possible that
> I just got a lot smarter with age, but I
> ascribe a significant amount of the improvement
> to the direct association of the attributes
> to the file.
Thats great but entirely irrelevant in this context. The patch and caps 
in question are not attached to the file via some externally observable 
property (eg., xattr) but instead are embedded in the source code so 
that it can drop caps at certain points during the execution or before 
executing another app, thus unanalyzable.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-19  0:25                 ` Joshua Brindle
@ 2006-09-19  3:46                   ` Casey Schaufler
  2006-09-19  4:09                     ` Joshua Brindle
  2006-09-19 18:27                   ` Pavel Machek
  1 sibling, 1 reply; 29+ messages in thread
From: Casey Schaufler @ 2006-09-19  3:46 UTC (permalink / raw)
  To: Joshua Brindle; +Cc: David Madore, Linux Kernel mailing-list, LSM mailing-list



--- Joshua Brindle <method@gentoo.org> wrote:


> > The first system I took through evaluation
> > (that is, independent 3rd party analysis) stored
> > security attributes in a file while the second
> > and third systems attached the attributes
> > directly (XFS). The 1st evaluation required
> > 5 years, the 2nd 1 year. It is possible that
> > I just got a lot smarter with age, but I
> > ascribe a significant amount of the improvement
> > to the direct association of the attributes
> > to the file.
> Thats great but entirely irrelevant in this context.
> The patch and caps 
> in question are not attached to the file via some
> externally observable 
> property (eg., xattr) but instead are embedded in
> the source code so 
> that it can drop caps at certain points during the
> execution or before 
> executing another app, thus unanalyzable.

Oh that. Sure, we used capability bracketing
in the code, too. That makes it easy to
determine when a capability is active. What,
you don't think that it's possible to analyze
source code? Of course it is. Refer to the
evaluation reports if you don't believe me.


Casey Schaufler
casey@schaufler-ca.com

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-19  3:46                   ` Casey Schaufler
@ 2006-09-19  4:09                     ` Joshua Brindle
  2006-09-19 15:54                       ` Casey Schaufler
  0 siblings, 1 reply; 29+ messages in thread
From: Joshua Brindle @ 2006-09-19  4:09 UTC (permalink / raw)
  To: casey; +Cc: David Madore, Linux Kernel mailing-list, LSM mailing-list

Casey Schaufler wrote:
> --- Joshua Brindle <method@gentoo.org> wrote:
>   
>>> The first system I took through evaluation
>>> (that is, independent 3rd party analysis) stored
>>> security attributes in a file while the second
>>> and third systems attached the attributes
>>> directly (XFS). The 1st evaluation required
>>> 5 years, the 2nd 1 year. It is possible that
>>> I just got a lot smarter with age, but I
>>> ascribe a significant amount of the improvement
>>> to the direct association of the attributes
>>> to the file.
>>>       
>> Thats great but entirely irrelevant in this context.
>> The patch and caps 
>> in question are not attached to the file via some
>> externally observable 
>> property (eg., xattr) but instead are embedded in
>> the source code so 
>> that it can drop caps at certain points during the
>> execution or before 
>> executing another app, thus unanalyzable.
>>     
>
> Oh that. Sure, we used capability bracketing
> in the code, too. That makes it easy to
> determine when a capability is active. What,
> you don't think that it's possible to analyze
> source code? Of course it is. Refer to the
> evaluation reports if you don't believe me.
>
>   
When I see an analysis of every line of source code on an average Linux 
machine then I might believe you (if you'll grant that no software can 
ever be installed on it afterward without being analyzed) but until then 
I'll stick with a centralized policy. I doubt many others will be 
satisfied with that limitation.

Bracketing hardly makes it analyzable, how can you possibly know if the 
bracketing happened? You *believe* it will and therefore you say that 
the bracketed code is safe but in reality this is a discretionary 
mechanism and you have zero assurance that there is any security 
whatsoever, no thanks, I'll pass.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-19  4:09                     ` Joshua Brindle
@ 2006-09-19 15:54                       ` Casey Schaufler
  0 siblings, 0 replies; 29+ messages in thread
From: Casey Schaufler @ 2006-09-19 15:54 UTC (permalink / raw)
  To: Joshua Brindle; +Cc: David Madore, Linux Kernel mailing-list, LSM mailing-list



--- Joshua Brindle <method@gentoo.org> wrote:

> Casey Schaufler wrote:
> > --- Joshua Brindle <method@gentoo.org> wrote:
> >   
> >>> The first system I took through evaluation
> >>> (that is, independent 3rd party analysis) stored
> >>> security attributes in a file while the second
> >>> and third systems attached the attributes
> >>> directly (XFS). The 1st evaluation required
> >>> 5 years, the 2nd 1 year. It is possible that
> >>> I just got a lot smarter with age, but I
> >>> ascribe a significant amount of the improvement
> >>> to the direct association of the attributes
> >>> to the file.
> >>>       
> >> Thats great but entirely irrelevant in this
> context.
> >> The patch and caps 
> >> in question are not attached to the file via some
> >> externally observable 
> >> property (eg., xattr) but instead are embedded in
> >> the source code so 
> >> that it can drop caps at certain points during
> the
> >> execution or before 
> >> executing another app, thus unanalyzable.
> >>     
> >
> > Oh that. Sure, we used capability bracketing
> > in the code, too. That makes it easy to
> > determine when a capability is active. What,
> > you don't think that it's possible to analyze
> > source code? Of course it is. Refer to the
> > evaluation reports if you don't believe me.
> >
> >   
> When I see an analysis of every line of source code
> on an average Linux 
> machine then I might believe you

Would an above average Unix system suffice?
How about MULTICS?

It's been done for:
    Irix and Trusted Irix
    Solaris and Trusted Solaris
    UNICOS
    HP/UX
    AIX
    SystemV
    Xenix

> (if you'll grant
> that no software can 
> ever be installed on it afterward without being
> analyzed)

Rubbish. No privileged software can be installed.
Software that runs as a user without capabilities
can be installed freely. It only requires analysis
if it violates policy, which on a system with
POSIX capabilities means running in possession
of capabilities. 

> but until then 
> I'll stick with a centralized policy.

OK. There is value in containment.

> I doubt many others will be 
> satisfied with that limitation.

It's been selling in the marketplace for
the past 20 years.

> Bracketing hardly makes it analyzable, how can you
> possibly know if the 
> bracketing happened?

Err, read the code?

> You *believe* it will and
> therefore you say that 
> the bracketed code is safe but in reality this is a
> discretionary 
> mechanism and you have zero assurance that there is
> any security whatsoever,

Ah, no. You don't seem to understand the concept.

> no thanks, I'll pass.

Probably just as well, all things considered.


Casey Schaufler
casey@schaufler-ca.com

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities
  2006-09-19  0:25                 ` Joshua Brindle
  2006-09-19  3:46                   ` Casey Schaufler
@ 2006-09-19 18:27                   ` Pavel Machek
  1 sibling, 0 replies; 29+ messages in thread
From: Pavel Machek @ 2006-09-19 18:27 UTC (permalink / raw)
  To: Joshua Brindle
  Cc: casey, David Madore, Alan Cox, Linux Kernel mailing-list,
	LSM mailing-list

Hi!

> >The first system I took through evaluation
> >(that is, independent 3rd party analysis) stored
> >security attributes in a file while the second
> >and third systems attached the attributes
> >directly (XFS). The 1st evaluation required
> >5 years, the 2nd 1 year. It is possible that
> >I just got a lot smarter with age, but I
> >ascribe a significant amount of the improvement
> >to the direct association of the attributes
> >to the file.
> Thats great but entirely irrelevant in this context. The patch and caps 
> in question are not attached to the file via some externally observable 
> property (eg., xattr) but instead are embedded in the source code so 
> that it can drop caps at certain points during the execution or before 
> executing another app, thus unanalyzable.

I do not know why this is unanalyzable... It seems very analyzable
when reading the source code... and actually priviledge
operations in source code mean that you can't get them wrong with
wrong xattrs.

Plus systems like qmail already use setuid() in source this way.

								Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2006-09-19 18:27 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-09-10 13:37 [PATCH 1/4] security: capabilities patch (version 0.4.4), part 1/4: enlarge capability sets David Madore
2006-09-10 13:41 ` [PATCH 2/4] security: capabilities patch (version 0.4.4), part 2/4: change inheritance semantics David Madore
2006-09-10 13:42 ` [PATCH 3/4] security: capabilities patch (version 0.4.4), part 3/4: introduce new capabilities David Madore
2006-09-10 16:23   ` Alan Cox
2006-09-10 16:09     ` David Madore
2006-09-11  8:06       ` James Morris
2006-09-11 12:03         ` Joshua Brindle
2006-09-11 16:22           ` Casey Schaufler
2006-09-17 18:06           ` Pavel Machek
2006-09-10 17:56     ` Joshua Brindle
2006-09-10 20:03       ` David Madore
2006-09-11  6:10         ` Jan Engelhardt
2006-09-11  6:51           ` David Madore
2006-09-11 13:42         ` Stephen Smalley
2006-09-17 18:14       ` Pavel Machek
2006-09-17 20:39         ` Joshua Brindle
2006-09-17 21:16           ` David Madore
2006-09-18 11:46             ` Joshua Brindle
2006-09-18 11:58               ` David Madore
2006-09-18 12:04               ` Pavel Machek
2006-09-18 12:12                 ` Joshua Brindle
2006-09-18 16:02               ` Casey Schaufler
2006-09-19  0:25                 ` Joshua Brindle
2006-09-19  3:46                   ` Casey Schaufler
2006-09-19  4:09                     ` Joshua Brindle
2006-09-19 15:54                       ` Casey Schaufler
2006-09-19 18:27                   ` Pavel Machek
2006-09-10 13:44 ` David Madore
2006-09-10 13:46 ` [PATCH 4/4] security: capabilities patch (version 0.4.4), part 4/4: add filesystem support David Madore

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).