Re: [RFC] [PATCH] file posix capabilities

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Quoting Serge E. Hallyn ([email protected]):
> This patch implements file (posix) capabilities.  This allows
> a binary to gain a subset of root's capabilities without having
> the file actually be setuid root.
> 
> There are some other implementations out there taking various
> approaches.  This patch keeps all the changes within the
> capability LSM, and stores the file capabilities in xattrs
> named "security.capability".  First question is, do we want
> this in the kernel?  Second is, is this sort of implementation
> we'd want?
> 
> Some userspace tools to manipulate the fscaps are at
> www.sr71.net/~hallyn/fscaps/.  For instance,
> 
> 	setcap writeroot "cap_dac_read_search,cap_dac_override+eip"
> 
> allows the 'writeroot' testcase to write to /root/ab when
> run as a normal user.
> 
> This patch doesn't address the need to update
> cap_bprm_secureexec().
> 
> Signed-off-by: Serge E. Hallyn <[email protected]>
> ---
>  include/linux/security.h |   10 +++-
>  security/Kconfig         |   11 ++++
>  security/capability.c    |    5 ++
>  security/commoncap.c     |  127 ++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 152 insertions(+), 1 deletions(-)

Here is a different version which sticks closer to the original
version by Simmonds, in that it simply calls getxattr at
bprm_set_security.  Very inadequate perftesting showed no
overhead, and this makes the patch much smaller and compatible
with SELinux.  Note that this patch changes nothing if
CONFIG_FS_CAPABILITIES is not enabled, which is the default, and
should therefore be safe to include in -mm.

(Also CC:ing lsm list which I forgot to do last time)

Signed-off-by: Serge E. Hallyn <[email protected]>
---
 security/Kconfig     |   10 ++++++++++
 security/commoncap.c |   48 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 57 insertions(+), 1 deletions(-)

diff --git a/security/Kconfig b/security/Kconfig
index 67785df..aa3558f 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/commoncap.c b/security/commoncap.c
index f50fc29..064fbb0 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -109,11 +109,17 @@ 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
 int cap_bprm_set_security (struct linux_binprm *bprm)
 {
+	ssize_t (*bprm_getxattr)(struct dentry *,const char *,void *,size_t);
+	struct dentry *bprm_dentry;
+	ssize_t rc;
+	u32 fscaps[3];
+
 	/* 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,6 +140,46 @@ int cap_bprm_set_security (struct linux_
 		if (bprm->e_uid == 0)
 			cap_set_full (bprm->cap_effective);
 	}
+
+#ifdef CONFIG_SECURITY_FS_CAPABILITIES
+	/* Locate any VFS capabilities: */
+
+	bprm_dentry = dget(bprm->file->f_dentry);
+	if(!(bprm_dentry->d_inode->i_op &&
+			bprm_dentry->d_inode->i_op->getxattr)) {
+		dput(bprm_dentry);
+		return 0;
+	}
+	bprm_getxattr = bprm_dentry->d_inode->i_op->getxattr;
+
+	rc = bprm_getxattr(bprm_dentry, XATTR_NAME_CAPS, &fscaps,
+						sizeof(fscaps));
+	dput(bprm_dentry);
+
+	/*
+	 * serge: not sure about the return values...
+	 * think about them some more, maybe some should
+	 * return rc.
+	 */
+	if (rc < 0 && rc != -ENODATA) {
+		printk(KERN_NOTICE "%s: Error (%d) getting xattr\n",
+				__FUNCTION__, rc);
+		return 0;
+	}
+	if (rc < 0)
+		return 0;
+
+	if (rc != sizeof(fscaps)) {
+		printk(KERN_NOTICE "%s: got wrong size for getxattr (%d)\n",
+					__FUNCTION__, rc);
+		return 0;
+	}
+
+	bprm->cap_effective = fscaps[0];
+	bprm->cap_inheritable = fscaps[1];
+	bprm->cap_permitted = fscaps[2];
+
+#endif
 	return 0;
 }
 
-- 
1.4.1.1

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux