mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* security: introduce file caps
@ 2006-11-14  3:06 Serge E. Hallyn
  2006-11-15  8:55 ` Chris Friedhoff
  2006-11-23  8:14 ` Andrew Morton
  0 siblings, 2 replies; 10+ messages in thread
From: Serge E. Hallyn @ 2006-11-14  3:06 UTC (permalink / raw)
  To: linux-kernel, linux-security-module
  Cc: Stephen Smalley, James Morris, Chris Wright, Andrew Morton,
	KaiGai Kohei, Chris Friedhoff, Alexey Dobriyan

From: Serge E. Hallyn <serue@us.ibm.com>
Subject: [PATCH 1/1] security: introduce file caps

Implement file posix capabilities.  This allows programs to be given
a subset of root's powers regardless of who runs them, without
having to use setuid and giving the binary all of root's powers.

This version works with Kaigai Kohei's userspace tools, found at
http://www.kaigai.gr.jp/index.php.  For more information on how to
use this patch, Chris Friedhoff has posted a nice page at
http://www.friedhoff.org/fscaps.html.

Changelog:
	Nov 13:
	Integrate comments from Alexey: Remove CONFIG_ ifdef from
	capability.h, and use %zd for printing a size_t.

	Nov 13:
	Fix endianness warnings by sparse as suggested by Alexey
	Dobriyan.

	Nov 09:
	Address warnings of unused variables at cap_bprm_set_security
	when file capabilities are disabled, and simultaneously clean
	up the code a little, by pulling the new code into a helper
	function.

	Nov 08:
	For pointers to required userspace tools and how to use
	them, see http://www.friedhoff.org/fscaps.html.

	Nov 07:
	Fix the calculation of the highest bit checked in
	check_cap_sanity().

	Nov 07:
	Allow file caps to be enabled without CONFIG_SECURITY, since
	capabilities are the default.
	Hook cap_task_setscheduler when !CONFIG_SECURITY.
	Move capable(TASK_KILL) to end of cap_task_kill to reduce
	audit messages.

	Nov 05:
	Add secondary calls in selinux/hooks.c to task_setioprio and
	task_setscheduler so that selinux and capabilities with file
	cap support can be stacked.

	Sep 05:
	As Seth Arnold points out, uid checks are out of place
	for capability code.

	Sep 01:
	Define task_setscheduler, task_setioprio, cap_task_kill, and
	task_setnice to make sure a user cannot affect a process in which
	they called a program with some fscaps.

	One remaining question is the note under task_setscheduler: are we
	ok with CAP_SYS_NICE being sufficient to confine a process to a
	cpuset?

	It is a semantic change, as without fsccaps, attach_task doesn't
	allow CAP_SYS_NICE to override the uid equivalence check.  But since
	it uses security_task_setscheduler, which elsewhere is used where
	CAP_SYS_NICE can be used to override the uid equivalence check,
	fixing it might be tough.

	     task_setscheduler
		 note: this also controls cpuset:attach_task.  Are we ok with
		     CAP_SYS_NICE being used to confine to a cpuset?
	     task_setioprio
	     task_setnice
		 sys_setpriority uses this (through set_one_prio) for another
		 process.  Need same checks as setrlimit

	Aug 21:
	Updated secureexec implementation to reflect the fact that
	euid and uid might be the same and nonzero, but the process
	might still have elevated caps.

	Aug 15:
	Handle endianness of xattrs.
	Enforce capability version match between kernel and disk.
	Enforce that no bits beyond the known max capability are
	set, else return -EPERM.
	With this extra processing, it may be worth reconsidering
	doing all the work at bprm_set_security rather than
	d_instantiate.

	Aug 10:
	Always call getxattr at bprm_set_security, rather than
	caching it at d_instantiate.

Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
 include/linux/capability.h |   19 +++++
 include/linux/security.h   |   12 ++-
 security/Kconfig           |    9 ++
 security/capability.c      |    4 +
 security/commoncap.c       |  163 ++++++++++++++++++++++++++++++++++++++++++--
 security/selinux/hooks.c   |   12 +++
 6 files changed, 208 insertions(+), 11 deletions(-)

diff --git a/include/linux/capability.h b/include/linux/capability.h
index 6548b35..9797eee 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -39,12 +39,29 @@ typedef struct __user_cap_data_struct {
         __u32 permitted;
         __u32 inheritable;
 } __user *cap_user_data_t;
+
+
+#define XATTR_CAPS_SUFFIX "capability"
+#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
+struct vfs_cap_data_disk {
+	__le32 version;
+	__le32 effective;
+	__le32 permitted;
+	__le32 inheritable;
+};
   
 #ifdef __KERNEL__
 
 #include <linux/spinlock.h>
 #include <asm/current.h>
 
+struct vfs_cap_data {
+	__u32 version;
+	__u32 effective;
+	__u32 permitted;
+	__u32 inheritable;
+};
+
 /* #define STRICT_CAP_T_TYPECHECKS */
 
 #ifdef STRICT_CAP_T_TYPECHECKS
@@ -288,6 +305,8 @@ #define CAP_AUDIT_WRITE      29
 
 #define CAP_AUDIT_CONTROL    30
 
+#define CAP_NUMCAPS	     31
+
 #ifdef __KERNEL__
 /* 
  * Bounding set
diff --git a/include/linux/security.h b/include/linux/security.h
index b200b98..2718aeb 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -53,6 +53,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);
 
@@ -2594,12 +2598,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)
@@ -2617,7 +2621,7 @@ static inline int security_task_setsched
 					      int policy,
 					      struct sched_param *lp)
 {
-	return 0;
+	return cap_task_setscheduler(p, policy, lp);
 }
 
 static inline int security_task_getscheduler (struct task_struct *p)
@@ -2634,7 +2638,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 460e5c9..6c9d69e 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -80,6 +80,15 @@ 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 "File POSIX 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 5a5ef5c..0e89f1b 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -109,11 +109,95 @@ void cap_capset_set (struct task_struct 
 	target->cap_permitted = *permitted;
 }
 
+#ifdef CONFIG_SECURITY_FS_CAPABILITIES
+static inline void cap_from_disk(struct vfs_cap_data_disk *dcap,
+					struct vfs_cap_data *cap)
+{
+	cap->version = le32_to_cpu(dcap->version);
+	cap->effective = le32_to_cpu(dcap->effective);
+	cap->permitted = le32_to_cpu(dcap->permitted);
+	cap->inheritable = le32_to_cpu(dcap->inheritable);
+}
+
+static int check_cap_sanity(struct vfs_cap_data *cap)
+{
+	int i;
+
+	if (cap->version != _LINUX_CAPABILITY_VERSION)
+		return -EPERM;
+
+	for (i=CAP_NUMCAPS; i<8*sizeof(cap->effective); i++) {
+		if (cap->effective & CAP_TO_MASK(i))
+			return -EPERM;
+	}
+	for (i=CAP_NUMCAPS; i<8*sizeof(cap->permitted); i++) {
+		if (cap->permitted & CAP_TO_MASK(i))
+			return -EPERM;
+	}
+	for (i=CAP_NUMCAPS; i<8*sizeof(cap->inheritable); i++) {
+		if (cap->inheritable & CAP_TO_MASK(i))
+			return -EPERM;
+	}
+
+	return 0;
+}
+
+/* Locate any VFS capabilities: */
+static int set_file_caps(struct linux_binprm *bprm)
+{
+	struct dentry *dentry;
+	ssize_t rc;
+	struct vfs_cap_data_disk dcaps;
+	struct vfs_cap_data caps;
+	struct inode *inode;
+
+	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, &dcaps,
+						sizeof(dcaps));
+	dput(dentry);
+
+	if (rc == -ENODATA)
+		return 0;
+
+	if (rc < 0) {
+		printk(KERN_NOTICE "%s: Error (%d) getting xattr\n",
+				__FUNCTION__, rc);
+		return rc;
+	}
+
+	if (rc != sizeof(dcaps)) {
+		printk(KERN_NOTICE "%s: got wrong size for getxattr (%zd)\n",
+					__FUNCTION__, rc);
+		return -EPERM;
+	}
+	
+	cap_from_disk(&dcaps, &caps);
+	if (check_cap_sanity(&caps))
+		return -EPERM;
+
+	bprm->cap_effective = caps.effective;
+	bprm->cap_permitted = caps.permitted;
+	bprm->cap_inheritable = caps.inheritable;
+
+	return 0;
+}
+#else
+static int set_file_caps(struct linux_binprm *bprm)
+{
+	return 0;
+}
+#endif
+
 int cap_bprm_set_security (struct linux_binprm *bprm)
 {
 	/* Copied from fs/exec.c:prepare_binprm. */
 
-	/* We don't have VFS support for capabilities yet */
 	cap_clear (bprm->cap_inheritable);
 	cap_clear (bprm->cap_permitted);
 	cap_clear (bprm->cap_effective);
@@ -134,7 +218,8 @@ int cap_bprm_set_security (struct linux_
 		if (bprm->e_uid == 0)
 			cap_set_full (bprm->cap_effective);
 	}
-	return 0;
+
+	return set_file_caps(bprm);
 }
 
 void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
@@ -182,11 +267,15 @@ void cap_bprm_apply_creds (struct linux_
 
 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. */
+	if (current->uid != 0) {
+		if (!cap_isclear(bprm->cap_effective))
+			return 1;
+		if (!cap_isclear(bprm->cap_permitted))
+			return 1;
+		if (!cap_isclear(bprm->cap_inheritable))
+			return 1;
+	}
+
 	return (current->euid != current->uid ||
 		current->egid != current->gid);
 }
@@ -300,6 +389,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 (cap_issubset(p->cap_permitted, current->cap_permitted))
+		return 0;
+	if (capable(CAP_KILL))
+		return 0;
+
+	return -EPERM;
+}
+
 void cap_task_reparent_to_init (struct task_struct *p)
 {
 	p->cap_effective = CAP_INIT_EFF_SET;
@@ -337,6 +482,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);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8ab5679..2fcc60f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2775,6 +2775,12 @@ static int selinux_task_setnice(struct t
 
 static int selinux_task_setioprio(struct task_struct *p, int ioprio)
 {
+	int rc;
+
+	rc = secondary_ops->task_setioprio(p, ioprio);
+	if (rc)
+		return rc;
+
 	return task_has_perm(current, p, PROCESS__SETSCHED);
 }
 
@@ -2804,6 +2810,12 @@ static int selinux_task_setrlimit(unsign
 
 static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp)
 {
+	int rc;
+
+	rc = secondary_ops->task_setscheduler(p, policy, lp);
+	if (rc)
+		return rc;
+
 	return task_has_perm(current, p, PROCESS__SETSCHED);
 }
 
-- 
1.4.1


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

* Re: security: introduce file caps
  2006-11-14  3:06 security: introduce file caps Serge E. Hallyn
@ 2006-11-15  8:55 ` Chris Friedhoff
  2006-11-23  8:14 ` Andrew Morton
  1 sibling, 0 replies; 10+ messages in thread
From: Chris Friedhoff @ 2006-11-15  8:55 UTC (permalink / raw)
  To: Serge E. Hallyn
  Cc: linux-kernel, linux-security-module, Stephen Smalley,
	James Morris, Chris Wright, Andrew Morton, KaiGai Kohei,
	Alexey Dobriyan

Integrates, compiles and runs successfully on 2.6.18.2 ...
so the System keeps on humming ...
the page http://www.friedhoff.org/fscaps.html is updated ...
congratulations for the acceptance in the 2.6.19-rc5-mm2 tree ...

Chris


On Mon, 13 Nov 2006 21:06:55 -0600
"Serge E. Hallyn" <serue@us.ibm.com> wrote:

> From: Serge E. Hallyn <serue@us.ibm.com>
> Subject: [PATCH 1/1] security: introduce file caps
> 
> Implement file posix capabilities.  This allows programs to be given
> a subset of root's powers regardless of who runs them, without
> having to use setuid and giving the binary all of root's powers.
> 
> This version works with Kaigai Kohei's userspace tools, found at
> http://www.kaigai.gr.jp/index.php.  For more information on how to
> use this patch, Chris Friedhoff has posted a nice page at
> http://www.friedhoff.org/fscaps.html.
> 
> Changelog:
> 	Nov 13:
> 	Integrate comments from Alexey: Remove CONFIG_ ifdef from
> 	capability.h, and use %zd for printing a size_t.
> 
> 	Nov 13:
> 	Fix endianness warnings by sparse as suggested by Alexey
> 	Dobriyan.
> 
> 	Nov 09:
> 	Address warnings of unused variables at cap_bprm_set_security
> 	when file capabilities are disabled, and simultaneously clean
> 	up the code a little, by pulling the new code into a helper
> 	function.
> 
> 	Nov 08:
> 	For pointers to required userspace tools and how to use
> 	them, see http://www.friedhoff.org/fscaps.html.
> 
> 	Nov 07:
> 	Fix the calculation of the highest bit checked in
> 	check_cap_sanity().
> 
> 	Nov 07:
> 	Allow file caps to be enabled without CONFIG_SECURITY, since
> 	capabilities are the default.
> 	Hook cap_task_setscheduler when !CONFIG_SECURITY.
> 	Move capable(TASK_KILL) to end of cap_task_kill to reduce
> 	audit messages.
> 
> 	Nov 05:
> 	Add secondary calls in selinux/hooks.c to task_setioprio and
> 	task_setscheduler so that selinux and capabilities with file
> 	cap support can be stacked.
> 
> 	Sep 05:
> 	As Seth Arnold points out, uid checks are out of place
> 	for capability code.
> 
> 	Sep 01:
> 	Define task_setscheduler, task_setioprio, cap_task_kill, and
> 	task_setnice to make sure a user cannot affect a process in which
> 	they called a program with some fscaps.
> 
> 	One remaining question is the note under task_setscheduler: are we
> 	ok with CAP_SYS_NICE being sufficient to confine a process to a
> 	cpuset?
> 
> 	It is a semantic change, as without fsccaps, attach_task doesn't
> 	allow CAP_SYS_NICE to override the uid equivalence check.  But since
> 	it uses security_task_setscheduler, which elsewhere is used where
> 	CAP_SYS_NICE can be used to override the uid equivalence check,
> 	fixing it might be tough.
> 
> 	     task_setscheduler
> 		 note: this also controls cpuset:attach_task.  Are we ok with
> 		     CAP_SYS_NICE being used to confine to a cpuset?
> 	     task_setioprio
> 	     task_setnice
> 		 sys_setpriority uses this (through set_one_prio) for another
> 		 process.  Need same checks as setrlimit
> 
> 	Aug 21:
> 	Updated secureexec implementation to reflect the fact that
> 	euid and uid might be the same and nonzero, but the process
> 	might still have elevated caps.
> 
> 	Aug 15:
> 	Handle endianness of xattrs.
> 	Enforce capability version match between kernel and disk.
> 	Enforce that no bits beyond the known max capability are
> 	set, else return -EPERM.
> 	With this extra processing, it may be worth reconsidering
> 	doing all the work at bprm_set_security rather than
> 	d_instantiate.
> 
> 	Aug 10:
> 	Always call getxattr at bprm_set_security, rather than
> 	caching it at d_instantiate.
> 
> Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
> ---
>  include/linux/capability.h |   19 +++++
>  include/linux/security.h   |   12 ++-
>  security/Kconfig           |    9 ++
>  security/capability.c      |    4 +
>  security/commoncap.c       |  163 ++++++++++++++++++++++++++++++++++++++++++--
>  security/selinux/hooks.c   |   12 +++
>  6 files changed, 208 insertions(+), 11 deletions(-)
> 
> diff --git a/include/linux/capability.h b/include/linux/capability.h
> index 6548b35..9797eee 100644
> --- a/include/linux/capability.h
> +++ b/include/linux/capability.h
> @@ -39,12 +39,29 @@ typedef struct __user_cap_data_struct {
>          __u32 permitted;
>          __u32 inheritable;
>  } __user *cap_user_data_t;
> +
> +
> +#define XATTR_CAPS_SUFFIX "capability"
> +#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
> +struct vfs_cap_data_disk {
> +	__le32 version;
> +	__le32 effective;
> +	__le32 permitted;
> +	__le32 inheritable;
> +};
>    
>  #ifdef __KERNEL__
>  
>  #include <linux/spinlock.h>
>  #include <asm/current.h>
>  
> +struct vfs_cap_data {
> +	__u32 version;
> +	__u32 effective;
> +	__u32 permitted;
> +	__u32 inheritable;
> +};
> +
>  /* #define STRICT_CAP_T_TYPECHECKS */
>  
>  #ifdef STRICT_CAP_T_TYPECHECKS
> @@ -288,6 +305,8 @@ #define CAP_AUDIT_WRITE      29
>  
>  #define CAP_AUDIT_CONTROL    30
>  
> +#define CAP_NUMCAPS	     31
> +
>  #ifdef __KERNEL__
>  /* 
>   * Bounding set
> diff --git a/include/linux/security.h b/include/linux/security.h
> index b200b98..2718aeb 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -53,6 +53,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);
>  
> @@ -2594,12 +2598,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)
> @@ -2617,7 +2621,7 @@ static inline int security_task_setsched
>  					      int policy,
>  					      struct sched_param *lp)
>  {
> -	return 0;
> +	return cap_task_setscheduler(p, policy, lp);
>  }
>  
>  static inline int security_task_getscheduler (struct task_struct *p)
> @@ -2634,7 +2638,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 460e5c9..6c9d69e 100644
> --- a/security/Kconfig
> +++ b/security/Kconfig
> @@ -80,6 +80,15 @@ 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 "File POSIX 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 5a5ef5c..0e89f1b 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -109,11 +109,95 @@ void cap_capset_set (struct task_struct 
>  	target->cap_permitted = *permitted;
>  }
>  
> +#ifdef CONFIG_SECURITY_FS_CAPABILITIES
> +static inline void cap_from_disk(struct vfs_cap_data_disk *dcap,
> +					struct vfs_cap_data *cap)
> +{
> +	cap->version = le32_to_cpu(dcap->version);
> +	cap->effective = le32_to_cpu(dcap->effective);
> +	cap->permitted = le32_to_cpu(dcap->permitted);
> +	cap->inheritable = le32_to_cpu(dcap->inheritable);
> +}
> +
> +static int check_cap_sanity(struct vfs_cap_data *cap)
> +{
> +	int i;
> +
> +	if (cap->version != _LINUX_CAPABILITY_VERSION)
> +		return -EPERM;
> +
> +	for (i=CAP_NUMCAPS; i<8*sizeof(cap->effective); i++) {
> +		if (cap->effective & CAP_TO_MASK(i))
> +			return -EPERM;
> +	}
> +	for (i=CAP_NUMCAPS; i<8*sizeof(cap->permitted); i++) {
> +		if (cap->permitted & CAP_TO_MASK(i))
> +			return -EPERM;
> +	}
> +	for (i=CAP_NUMCAPS; i<8*sizeof(cap->inheritable); i++) {
> +		if (cap->inheritable & CAP_TO_MASK(i))
> +			return -EPERM;
> +	}
> +
> +	return 0;
> +}
> +
> +/* Locate any VFS capabilities: */
> +static int set_file_caps(struct linux_binprm *bprm)
> +{
> +	struct dentry *dentry;
> +	ssize_t rc;
> +	struct vfs_cap_data_disk dcaps;
> +	struct vfs_cap_data caps;
> +	struct inode *inode;
> +
> +	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, &dcaps,
> +						sizeof(dcaps));
> +	dput(dentry);
> +
> +	if (rc == -ENODATA)
> +		return 0;
> +
> +	if (rc < 0) {
> +		printk(KERN_NOTICE "%s: Error (%d) getting xattr\n",
> +				__FUNCTION__, rc);
> +		return rc;
> +	}
> +
> +	if (rc != sizeof(dcaps)) {
> +		printk(KERN_NOTICE "%s: got wrong size for getxattr (%zd)\n",
> +					__FUNCTION__, rc);
> +		return -EPERM;
> +	}
> +	
> +	cap_from_disk(&dcaps, &caps);
> +	if (check_cap_sanity(&caps))
> +		return -EPERM;
> +
> +	bprm->cap_effective = caps.effective;
> +	bprm->cap_permitted = caps.permitted;
> +	bprm->cap_inheritable = caps.inheritable;
> +
> +	return 0;
> +}
> +#else
> +static int set_file_caps(struct linux_binprm *bprm)
> +{
> +	return 0;
> +}
> +#endif
> +
>  int cap_bprm_set_security (struct linux_binprm *bprm)
>  {
>  	/* Copied from fs/exec.c:prepare_binprm. */
>  
> -	/* We don't have VFS support for capabilities yet */
>  	cap_clear (bprm->cap_inheritable);
>  	cap_clear (bprm->cap_permitted);
>  	cap_clear (bprm->cap_effective);
> @@ -134,7 +218,8 @@ int cap_bprm_set_security (struct linux_
>  		if (bprm->e_uid == 0)
>  			cap_set_full (bprm->cap_effective);
>  	}
> -	return 0;
> +
> +	return set_file_caps(bprm);
>  }
>  
>  void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
> @@ -182,11 +267,15 @@ void cap_bprm_apply_creds (struct linux_
>  
>  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. */
> +	if (current->uid != 0) {
> +		if (!cap_isclear(bprm->cap_effective))
> +			return 1;
> +		if (!cap_isclear(bprm->cap_permitted))
> +			return 1;
> +		if (!cap_isclear(bprm->cap_inheritable))
> +			return 1;
> +	}
> +
>  	return (current->euid != current->uid ||
>  		current->egid != current->gid);
>  }
> @@ -300,6 +389,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 (cap_issubset(p->cap_permitted, current->cap_permitted))
> +		return 0;
> +	if (capable(CAP_KILL))
> +		return 0;
> +
> +	return -EPERM;
> +}
> +
>  void cap_task_reparent_to_init (struct task_struct *p)
>  {
>  	p->cap_effective = CAP_INIT_EFF_SET;
> @@ -337,6 +482,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);
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 8ab5679..2fcc60f 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2775,6 +2775,12 @@ static int selinux_task_setnice(struct t
>  
>  static int selinux_task_setioprio(struct task_struct *p, int ioprio)
>  {
> +	int rc;
> +
> +	rc = secondary_ops->task_setioprio(p, ioprio);
> +	if (rc)
> +		return rc;
> +
>  	return task_has_perm(current, p, PROCESS__SETSCHED);
>  }
>  
> @@ -2804,6 +2810,12 @@ static int selinux_task_setrlimit(unsign
>  
>  static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp)
>  {
> +	int rc;
> +
> +	rc = secondary_ops->task_setscheduler(p, policy, lp);
> +	if (rc)
> +		return rc;
> +
>  	return task_has_perm(current, p, PROCESS__SETSCHED);
>  }
>  
> -- 
> 1.4.1
> 


--------------------
Chris Friedhoff
chris@friedhoff.org

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

* Re: security: introduce file caps
  2006-11-14  3:06 security: introduce file caps Serge E. Hallyn
  2006-11-15  8:55 ` Chris Friedhoff
@ 2006-11-23  8:14 ` Andrew Morton
  2006-11-23  8:22   ` Andrew Morton
  1 sibling, 1 reply; 10+ messages in thread
From: Andrew Morton @ 2006-11-23  8:14 UTC (permalink / raw)
  To: Serge E. Hallyn
  Cc: linux-kernel, linux-security-module, Stephen Smalley,
	James Morris, Chris Wright, KaiGai Kohei, Chris Friedhoff,
	Alexey Dobriyan

On Mon, 13 Nov 2006 21:06:55 -0600
"Serge E. Hallyn" <serue@us.ibm.com> wrote:

> Implement file posix capabilities.  This allows programs to be given
> a subset of root's powers regardless of who runs them, without
> having to use setuid and giving the binary all of root's powers.

With this patch applied, my X server fails to exit when I do the normal
logout thing from the KDE menus.

The distro is FC5, SELinux is enabled.  I start X via `startx'.

All the X clients have gone away, but the server continues to run.  Black
screen with just a mouse pointer which still responds to movement.

This happens with CONFIG_SECURITY_FS_CAPABILITIES=n as well as =y.

ps auxfw says:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.1  0.0   2000   676 ?        Ss   01:04   0:00 init [3]                                                                                                                                                 
root         2  0.0  0.0      0     0 ?        SN   01:04   0:00 [ksoftirqd/0]
root         3  0.0  0.0      0     0 ?        S    01:04   0:00 [watchdog/0]
root         4  0.0  0.0      0     0 ?        S<   01:04   0:00 [events/0]
root         5  0.0  0.0      0     0 ?        S<   01:04   0:00 [khelper]
root         6  0.0  0.0      0     0 ?        S<   01:04   0:00 [kthread]
root        47  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [kblockd/0]
root        48  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [kacpid]
root       152  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [ata/0]
root       153  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [ata_aux]
root       154  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [ksuspend_usbd]
root       157  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [khubd]
root       159  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [kseriod]
root       179  0.0  0.0      0     0 ?        S    01:04   0:00  \_ [pdflush]
root       180  0.0  0.0      0     0 ?        S    01:04   0:00  \_ [pdflush]
root       181  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [kswapd0]
root       182  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [aio/0]
root       291  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [scsi_eh_0]
root       292  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [scsi_eh_1]
root       297  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [scsi_eh_2]
root       298  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [scsi_eh_3]
root       311  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [pccardd]
root       321  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [kpsmoused]
root       326  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [kedac]
root       354  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [kjournald]
root       740  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [hda_codec]
root       975  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [khpsbpkt]
root      1110  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [knodemgrd_0]
root      1680  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [kauditd]
root      2237  0.0  0.0      0     0 ?        S<   01:04   0:00  \_ [ipw2200/0]
root       421  0.0  0.0   2212   648 ?        S<s  01:04   0:00 /sbin/udevd -d
root      1427  0.0  0.0   1584   280 ?        Ss   01:04   0:00 cpuspeed -d -n
root      1624  0.0  0.0   1652   592 ?        Ss   01:04   0:00 syslogd -m 0
root      1627  0.0  0.0   1604   392 ?        Ss   01:04   0:00 klogd -x
rpc       1644  0.0  0.0   1736   552 ?        Ss   01:04   0:00 portmap
rpcuser   1663  0.0  0.0   1744   716 ?        Ss   01:04   0:00 rpc.statd
root      1678  0.0  0.0   9944   604 ?        S<sl 01:04   0:00 auditd
root      1707  0.0  0.0   4728   584 ?        Ss   01:04   0:00 rpc.idmapd
dbus      1721  0.0  0.1  11268  1104 ?        Ssl  01:04   0:00 dbus-daemon --system
root      1763  0.0  0.0   1820   460 ?        Ss   01:04   0:00 /usr/bin/hidd --server
root      1850  0.0  0.0   1872   748 ?        Ss   01:04   0:00 /usr/sbin/automount --timeout=60 --debug /net program /etc/auto.net
root      1863  0.0  0.0   1600   460 ?        Ss   01:04   0:00 /usr/sbin/acpid
root      1872  0.0  0.0   5008   488 ?        Ss   01:04   0:00 ./hpiod
root      1877  0.0  0.4  12572  4720 ?        S    01:04   0:00 python ./hpssd.py
root      1888  0.0  0.1   4984  1100 ?        Ss   01:04   0:00 /usr/sbin/sshd
root      2354  0.0  0.2   7800  2516 ?        Ss   01:04   0:00  \_ sshd: akpm [priv]
akpm      2408  0.0  0.1   7928  1964 ?        S    01:04   0:00  |   \_ sshd: akpm@pts/0 
akpm      2443  0.0  0.2   5872  2364 pts/0    Ss+  01:04   0:00  |       \_ -zsh
root      3198  0.0  0.2   7800  2512 ?        Ss   01:05   0:00  \_ sshd: akpm [priv]
akpm      3202  0.0  0.1   7928  2004 ?        S    01:05   0:00      \_ sshd: akpm@pts/1 
akpm      3209  0.0  0.2   6004  2568 pts/1    Ss   01:05   0:00          \_ -zsh
akpm      3264  0.0  0.0   2104   840 pts/1    R+   01:11   0:00              \_ ps auxfw
root      1900  0.0  0.0   2228   808 ?        Ss   01:04   0:00 xinetd -stayalive -pidfile /var/run/xinetd.pid
ntp       1912  0.0  0.4   4244  4244 ?        SLs  01:04   0:00 ntpd -u ntp:ntp -p /var/run/ntpd.pid -g
root      1957  0.0  0.0   1824   344 ?        Ss   01:04   0:00 gpm -m /dev/input/mice -t exps2
root      1966  0.0  0.1   5188  1192 ?        Ss   01:04   0:00 crond
xfs       2001  0.1  0.2   4204  2492 ?        Ss   01:04   0:00 xfs -droppriv -daemon
root      2010  0.0  0.0   1596   496 ?        SNs  01:04   0:00 anacron -s
root      2018  0.0  0.0   2164   444 ?        Ss   01:04   0:00 /usr/sbin/atd
root      2027  0.0  0.1   3136  1152 ?        Ss   01:04   0:00 cups-config-daemon
68        2037  0.6  0.3   5100  3436 ?        Ss   01:04   0:02 hald
root      2038  0.0  0.1   3136  1048 ?        S    01:04   0:00  \_ hald-runner
68        2044  0.0  0.0   2236   868 ?        S    01:04   0:00      \_ /usr/libexec/hald-addon-acpi
68        2052  0.0  0.0   2236   872 ?        S    01:04   0:00      \_ /usr/libexec/hald-addon-keyboard
root      2127  0.0  0.1   2744  1316 ?        Ss   01:04   0:00 login -- akpm     
akpm      2453  0.0  0.2   5968  2492 tty1     Ss+  01:04   0:00  \_ -zsh
root      2128  0.0  0.0   1588   408 tty2     Ss+  01:04   0:00 /sbin/mingetty tty2
root      2129  0.0  0.0   1588   408 tty3     Ss+  01:04   0:00 /sbin/mingetty tty3
root      2130  0.0  0.0   1584   404 tty4     Ss+  01:04   0:00 /sbin/mingetty tty4
root      2131  0.0  0.0   1584   404 tty5     Ss+  01:04   0:00 /sbin/mingetty tty5
root      2132  0.0  0.0   1584   404 tty6     Ss+  01:04   0:00 /sbin/mingetty tty6
root      2753  0.0  0.1   8364  1928 ?        Ss   01:05   0:00 sendmail: accepting connections
smmsp     2764  0.0  0.1   7344  1712 ?        Ss   01:05   0:00 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue
root      2784  0.7  0.8  13284  8428 tty7     Ss+  01:05   0:02 X :0 -auth /home/akpm/.serverauth.2767
akpm      2948  0.0  0.0   2864   264 ?        Ss   01:05   0:00 syndaemon -k -i 1 -d


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

* Re: security: introduce file caps
  2006-11-23  8:14 ` Andrew Morton
@ 2006-11-23  8:22   ` Andrew Morton
       [not found]     ` <20061123131203.f7b6972f.chris@friedhoff.org>
  0 siblings, 1 reply; 10+ messages in thread
From: Andrew Morton @ 2006-11-23  8:22 UTC (permalink / raw)
  To: Serge E. Hallyn, linux-kernel, linux-security-module,
	Stephen Smalley, James Morris, Chris Wright, KaiGai Kohei,
	Chris Friedhoff, Alexey Dobriyan

On Thu, 23 Nov 2006 00:14:58 -0800
Andrew Morton <akpm@osdl.org> wrote:

> On Mon, 13 Nov 2006 21:06:55 -0600
> "Serge E. Hallyn" <serue@us.ibm.com> wrote:
> 
> > Implement file posix capabilities.  This allows programs to be given
> > a subset of root's powers regardless of who runs them, without
> > having to use setuid and giving the binary all of root's powers.
> 
> With this patch applied, my X server fails to exit when I do the normal
> logout thing from the KDE menus.

After a manual kill of the X server I see on the VT:

xinit: Operation not permitted (errno 1): Can't kill X server


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

* Re: security: introduce file caps
       [not found]     ` <20061123131203.f7b6972f.chris@friedhoff.org>
@ 2006-11-23 18:39       ` Andrew Morton
  2006-11-23 21:41         ` Serge E. Hallyn
  2006-11-24 16:16         ` file caps: permit unsafe signaling when CONFIG_FS_CAPS=n Serge E. Hallyn
  0 siblings, 2 replies; 10+ messages in thread
From: Andrew Morton @ 2006-11-23 18:39 UTC (permalink / raw)
  To: Chris Friedhoff
  Cc: Serge E. Hallyn, linux-kernel, linux-security-module,
	Stephen Smalley, James Morris, Chris Wright, KaiGai Kohei,
	Alexey Dobriyan

On Thu, 23 Nov 2006 13:12:03 +0100
Chris Friedhoff <chris@friedhoff.org> wrote:

> xinit respects capabilities (at least i guess), so when the system has
> capability-support, the binary /usr/X11R6/bin/xinit neeeds the
> capability cap_kill even when no capability extended attribute exists
> for this binary.
> 
> setfcaps cap_kill=ep /usr/X11R6/bin/xinit
> 
> I documented this here:
> http://www.friedhoff.org/fscaps.html#Xorg,%20xinit,%20xfce,%20kde
> 
> and for more:
> http://www.friedhoff.org/fscaps.html
> 

Even when CONFIG_SECURITY_FS_CAPABILITIES=n?

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

* Re: security: introduce file caps
  2006-11-23 18:39       ` Andrew Morton
@ 2006-11-23 21:41         ` Serge E. Hallyn
  2006-11-23 23:21           ` Chris Friedhoff
  2006-11-24 16:16         ` file caps: permit unsafe signaling when CONFIG_FS_CAPS=n Serge E. Hallyn
  1 sibling, 1 reply; 10+ messages in thread
From: Serge E. Hallyn @ 2006-11-23 21:41 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Chris Friedhoff, Serge E. Hallyn, linux-kernel,
	linux-security-module, Stephen Smalley, James Morris,
	Chris Wright, KaiGai Kohei, Alexey Dobriyan

Quoting Andrew Morton (akpm@osdl.org):
> On Thu, 23 Nov 2006 13:12:03 +0100
> Chris Friedhoff <chris@friedhoff.org> wrote:
> 
> > xinit respects capabilities (at least i guess), so when the system has
> > capability-support, the binary /usr/X11R6/bin/xinit neeeds the
> > capability cap_kill even when no capability extended attribute exists
> > for this binary.
> >
> > setfcaps cap_kill=ep /usr/X11R6/bin/xinit
> >
> > I documented this here:
> > http://www.friedhoff.org/fscaps.html#Xorg,%20xinit,%20xfce,%20kde
> >
> > and for more:
> > http://www.friedhoff.org/fscaps.html
> >
> 
> Even when CONFIG_SECURITY_FS_CAPABILITIES=n?

No, the patch shouldn't change behavior when
CONFIG_SECURITY_FS_CAPABILITIES=n, though of course I see why it did.  I
will send a fixed patch tomorrow or this weekend.

sorry,
-serge

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

* Re: security: introduce file caps
  2006-11-23 21:41         ` Serge E. Hallyn
@ 2006-11-23 23:21           ` Chris Friedhoff
  0 siblings, 0 replies; 10+ messages in thread
From: Chris Friedhoff @ 2006-11-23 23:21 UTC (permalink / raw)
  To: Serge E. Hallyn
  Cc: Andrew Morton, Chris Friedhoff, linux-kernel,
	linux-security-module, Stephen Smalley, James Morris,
	Chris Wright, KaiGai Kohei, Alexey Dobriyan

I can confirm this behavior, but only in the interaction of xinit and X.
ping and ntpdate behave with a patched kernel but
CONFIG_SECURITY_FS_CAPABILITIES=n like expected, even with empty or
wrong capabilities. Tested with 2.6.18.3 kernel

Chris



 On Thu, 23 Nov 2006 15:41:59 -0600
"Serge E. Hallyn" <serue@us.ibm.com> wrote:

> Quoting Andrew Morton (akpm@osdl.org):
> > On Thu, 23 Nov 2006 13:12:03 +0100
> > Chris Friedhoff <chris@friedhoff.org> wrote:
> > 
> > > xinit respects capabilities (at least i guess), so when the system has
> > > capability-support, the binary /usr/X11R6/bin/xinit neeeds the
> > > capability cap_kill even when no capability extended attribute exists
> > > for this binary.
> > >
> > > setfcaps cap_kill=ep /usr/X11R6/bin/xinit
> > >
> > > I documented this here:
> > > http://www.friedhoff.org/fscaps.html#Xorg,%20xinit,%20xfce,%20kde
> > >
> > > and for more:
> > > http://www.friedhoff.org/fscaps.html
> > >
> > 
> > Even when CONFIG_SECURITY_FS_CAPABILITIES=n?
> 
> No, the patch shouldn't change behavior when
> CONFIG_SECURITY_FS_CAPABILITIES=n, though of course I see why it did.  I
> will send a fixed patch tomorrow or this weekend.
> 
> sorry,
> -serge


--------------------
Chris Friedhoff
chris@friedhoff.org

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

* file caps: permit unsafe signaling when CONFIG_FS_CAPS=n
  2006-11-23 18:39       ` Andrew Morton
  2006-11-23 21:41         ` Serge E. Hallyn
@ 2006-11-24 16:16         ` Serge E. Hallyn
  2006-11-24 18:17           ` Serge E. Hallyn
  1 sibling, 1 reply; 10+ messages in thread
From: Serge E. Hallyn @ 2006-11-24 16:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Chris Friedhoff, Serge E. Hallyn, linux-kernel,
	linux-security-module, Stephen Smalley, James Morris,
	Chris Wright, KaiGai Kohei, Alexey Dobriyan

Ok, the following patch restores the CONFIG_FS_CAPS=n signaling
behavior, but I'm having a config problem.  When
CONFIG_SECURITY_CAPABILITIES=n, and I toggle
CONFIG_SECURITY_FS_CAPABILITIES between y and n, security/commoncap.o
does not recompile.  However since capabilities are now the default
security module, commoncap.o is in fact included in the kernel build,
and therefore should be recompiled.

Looking into why, but maybe someone knows offhand what would be going
wrong?

thanks,
-serge

From: Serge E. Hallyn <serue@us.ibm.com>
Subject: [PATCH 1/1] file caps: permit unsafe signaling when CONFIG_FS_CAPS=n

In legacy behavior, when a user starts a setuid program, that user
can send signals to the running program.  The file capabilities
patch prevents that not only when file capabilities are enabled,
but in all cases where capabilities are used.

For instance, when starting the X server, which is setuid root, it
is expected that the user who started it be able to kill it.

Existing behavior should not be changed.  This patch should reenable
signaling setuid processes started by the signaling user.

Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
 security/commoncap.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/security/commoncap.c b/security/commoncap.c
index 0e89f1b..04b277f 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -389,6 +389,7 @@ int cap_task_post_setuid (uid_t old_ruid
 	return 0;
 }
 
+#ifdef CONFIG_SECURITY_FS_CAPABILITIES
 /*
  * Rationale: code calling task_setscheduler, task_setioprio, and
  * task_setnice, assumes that
@@ -444,6 +445,26 @@ int cap_task_kill(struct task_struct *p,
 
 	return -EPERM;
 }
+#else
+int cap_task_setscheduler (struct task_struct *p, int policy,
+			   struct sched_param *lp)
+{
+	return 0;
+}
+int cap_task_setioprio (struct task_struct *p, int ioprio)
+{
+	return 0;
+}
+int cap_task_setnice (struct task_struct *p, int nice)
+{
+	return 0;
+}
+int cap_task_kill(struct task_struct *p, struct siginfo *info,
+				int sig, u32 secid)
+{
+	return 0;
+}
+#endif
 
 void cap_task_reparent_to_init (struct task_struct *p)
 {
-- 
1.4.1


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

* Re: file caps: permit unsafe signaling when CONFIG_FS_CAPS=n
  2006-11-24 16:16         ` file caps: permit unsafe signaling when CONFIG_FS_CAPS=n Serge E. Hallyn
@ 2006-11-24 18:17           ` Serge E. Hallyn
  2006-11-25 21:19             ` Chris Friedhoff
  0 siblings, 1 reply; 10+ messages in thread
From: Serge E. Hallyn @ 2006-11-24 18:17 UTC (permalink / raw)
  To: Serge E. Hallyn
  Cc: Andrew Morton, Chris Friedhoff, linux-kernel,
	linux-security-module, Stephen Smalley, James Morris,
	Chris Wright, KaiGai Kohei, Alexey Dobriyan

Quoting Serge E. Hallyn (serue@us.ibm.com):
> Ok, the following patch restores the CONFIG_FS_CAPS=n signaling
> behavior, but I'm having a config problem.  When
> CONFIG_SECURITY_CAPABILITIES=n, and I toggle
> CONFIG_SECURITY_FS_CAPABILITIES between y and n, security/commoncap.o
> does not recompile.  However since capabilities are now the default
> security module, commoncap.o is in fact included in the kernel build,
> and therefore should be recompiled.
> 
> Looking into why, but maybe someone knows offhand what would be going
> wrong?

Uh, never mind.  It does the right thing.  CONFIG_SECURITY=n means we
use capabilities, but CONFIG_SECURITY=y and CONFIG_SECURITY_CAPABILITIES=n 
means we use dummy.  The following patch fixes the Kconfig accordingly.

From: Serge E. Hallyn <serue@us.ibm.com>
Subject: [PATCH 1/1] file caps: don't show FILE_CAPABILITIES option when not relevant

FILE_CAPABILITIES are relevant when CONFIG_SECURITY=n, but not when
CONFIG_SECURITY=y && CONFIG_SECURITY_CAPABILITIES=n.  So make
CONFIG_SECURITY_FS_CAPABILITIES depend on the right conditions.

Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
 security/Kconfig |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/security/Kconfig b/security/Kconfig
index 6c9d69e..1b47f01 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -82,6 +82,7 @@ config SECURITY_CAPABILITIES
 
 config SECURITY_FS_CAPABILITIES
 	bool "File POSIX Capabilities"
+	depends on SECURITY=n || SECURITY_CAPABILITIES=y
 	default n
 	help
 	  This enables filesystem capabilities, allowing you to give
-- 
1.4.1


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

* Re: file caps: permit unsafe signaling when CONFIG_FS_CAPS=n
  2006-11-24 18:17           ` Serge E. Hallyn
@ 2006-11-25 21:19             ` Chris Friedhoff
  0 siblings, 0 replies; 10+ messages in thread
From: Chris Friedhoff @ 2006-11-25 21:19 UTC (permalink / raw)
  To: Serge E. Hallyn
  Cc: Andrew Morton, Chris Friedhoff, linux-kernel,
	linux-security-module, Stephen Smalley, James Morris,
	Chris Wright, KaiGai Kohei, Alexey Dobriyan

Serge, may I ask you to send a new complete patch with Andrew Mortons
additions and this change and a new changelog entry.

Thanks
Chris


 On Fri, 24 Nov
2006 12:17:42 -0600 "Serge E. Hallyn" <serue@us.ibm.com> wrote:

> Quoting Serge E. Hallyn (serue@us.ibm.com):
> > Ok, the following patch restores the CONFIG_FS_CAPS=n signaling
> > behavior, but I'm having a config problem.  When
> > CONFIG_SECURITY_CAPABILITIES=n, and I toggle
> > CONFIG_SECURITY_FS_CAPABILITIES between y and n, security/commoncap.o
> > does not recompile.  However since capabilities are now the default
> > security module, commoncap.o is in fact included in the kernel build,
> > and therefore should be recompiled.
> > 
> > Looking into why, but maybe someone knows offhand what would be going
> > wrong?
> 
> Uh, never mind.  It does the right thing.  CONFIG_SECURITY=n means we
> use capabilities, but CONFIG_SECURITY=y and CONFIG_SECURITY_CAPABILITIES=n 
> means we use dummy.  The following patch fixes the Kconfig accordingly.
> 
> From: Serge E. Hallyn <serue@us.ibm.com>
> Subject: [PATCH 1/1] file caps: don't show FILE_CAPABILITIES option when not relevant
> 
> FILE_CAPABILITIES are relevant when CONFIG_SECURITY=n, but not when
> CONFIG_SECURITY=y && CONFIG_SECURITY_CAPABILITIES=n.  So make
> CONFIG_SECURITY_FS_CAPABILITIES depend on the right conditions.
> 
> Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
> ---
>  security/Kconfig |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/security/Kconfig b/security/Kconfig
> index 6c9d69e..1b47f01 100644
> --- a/security/Kconfig
> +++ b/security/Kconfig
> @@ -82,6 +82,7 @@ config SECURITY_CAPABILITIES
>  
>  config SECURITY_FS_CAPABILITIES
>  	bool "File POSIX Capabilities"
> +	depends on SECURITY=n || SECURITY_CAPABILITIES=y
>  	default n
>  	help
>  	  This enables filesystem capabilities, allowing you to give
> -- 
> 1.4.1
> 


--------------------
Chris Friedhoff
chris@friedhoff.org

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

end of thread, other threads:[~2006-11-25 21:21 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-11-14  3:06 security: introduce file caps Serge E. Hallyn
2006-11-15  8:55 ` Chris Friedhoff
2006-11-23  8:14 ` Andrew Morton
2006-11-23  8:22   ` Andrew Morton
     [not found]     ` <20061123131203.f7b6972f.chris@friedhoff.org>
2006-11-23 18:39       ` Andrew Morton
2006-11-23 21:41         ` Serge E. Hallyn
2006-11-23 23:21           ` Chris Friedhoff
2006-11-24 16:16         ` file caps: permit unsafe signaling when CONFIG_FS_CAPS=n Serge E. Hallyn
2006-11-24 18:17           ` Serge E. Hallyn
2006-11-25 21:19             ` Chris Friedhoff

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome