All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nicolas Belouin <nicolas@belouin.fr>
To: Jan Kara <jack@suse.com>, Theodore Ts'o <tytso@mit.edu>,
	Andreas Dilger <adilger.kernel@dilger.ca>,
	Jaegeuk Kim <jaegeuk@kernel.org>, Chao Yu <yuchao0@huawei.com>,
	David Woodhouse <dwmw2@infradead.org>,
	Dave Kleikamp <shaggy@kernel.org>,
	Mark Fasheh <mfasheh@versity.com>,
	Joel Becker <jlbec@evilplan.org>,
	Miklos Szeredi <miklos@szeredi.hu>,
	Phillip Lougher <phillip@squashfs.org.uk>,
	Richard Weinberger <richard@nod.at>,
	Artem Bityutskiy <dedekind1@gmail.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	Serge Hallyn <serge@hallyn.com>, Paul Moore <paul@paul-moore.com>,
	Stephen Smalley <sds@tycho.nsa.gov>,
	Eric Paris <eparis@parisplace.org>,
	James Morris <james.l.morris@oracle.com>,
	linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net,
	linux-fsdevel@vger.kernel.org, linux-mtd@lists.infradead.org,
	jfs-discussion@lists.sourceforge.net, ocfs2-devel@oss.oracle.com,
	linux-unionfs@vger.kernel.org, reiserfs-devel@vger.kernel.org,
	linux-security-module@vger.kernel.org, selinux@tycho.nsa.gov,
	linux-api@vger.kernel.org, kernel-hardening@lists.openwall.com
Cc: Nicolas Belouin <nicolas@belouin.fr>
Subject: [RFC PATCH 2/2] fs: Grant CAP_TRUSTED rw access to trusted xattrs
Date: Sat, 21 Oct 2017 15:45:58 +0200	[thread overview]
Message-ID: <20171021134558.21195-2-nicolas@belouin.fr> (raw)
In-Reply-To: <20171021134558.21195-1-nicolas@belouin.fr>

The trusted xattrs read/write access is the perfect use case for
CAP_TRUSTED.

Signed-off-by: Nicolas Belouin <nicolas@belouin.fr>
---
 fs/ext2/xattr_trusted.c     |  2 +-
 fs/ext4/xattr_trusted.c     |  2 +-
 fs/f2fs/xattr.c             |  6 +++---
 fs/hfsplus/xattr.c          |  2 +-
 fs/jffs2/xattr_trusted.c    |  2 +-
 fs/jfs/xattr.c              |  3 ++-
 fs/ocfs2/xattr.c            |  2 +-
 fs/overlayfs/inode.c        |  3 ++-
 fs/reiserfs/xattr_trusted.c | 11 ++++++++---
 fs/squashfs/xattr.c         |  2 +-
 fs/ubifs/xattr.c            |  3 ++-
 fs/xattr.c                  |  4 ++--
 12 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c
index 65049b71af13..8006c24f8ee0 100644
--- a/fs/ext2/xattr_trusted.c
+++ b/fs/ext2/xattr_trusted.c
@@ -11,7 +11,7 @@
 static bool
 ext2_xattr_trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static int
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c
index c7765c735714..9849d1e0ebb9 100644
--- a/fs/ext4/xattr_trusted.c
+++ b/fs/ext4/xattr_trusted.c
@@ -15,7 +15,7 @@
 static bool
 ext4_xattr_trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static int
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 7c65540148f8..ef572464deca 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -37,7 +37,7 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
 			return -EOPNOTSUPP;
 		break;
 	case F2FS_XATTR_INDEX_TRUSTED:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return -EPERM;
 		break;
 	case F2FS_XATTR_INDEX_SECURITY:
@@ -62,7 +62,7 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
 			return -EOPNOTSUPP;
 		break;
 	case F2FS_XATTR_INDEX_TRUSTED:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return -EPERM;
 		break;
 	case F2FS_XATTR_INDEX_SECURITY:
@@ -83,7 +83,7 @@ static bool f2fs_xattr_user_list(struct dentry *dentry)
 
 static bool f2fs_xattr_trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index ae03a19196ef..0ec6d02ee7e9 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -606,7 +606,7 @@ static inline int can_list(const char *xattr_name)
 
 	return !strncmp(xattr_name, XATTR_TRUSTED_PREFIX,
 			XATTR_TRUSTED_PREFIX_LEN) ||
-				capable(CAP_SYS_ADMIN);
+				capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static ssize_t hfsplus_listxattr_finder_info(struct dentry *dentry,
diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c
index 5d6030826c52..3c7ae98e4525 100644
--- a/fs/jffs2/xattr_trusted.c
+++ b/fs/jffs2/xattr_trusted.c
@@ -35,7 +35,7 @@ static int jffs2_trusted_setxattr(const struct xattr_handler *handler,
 
 static bool jffs2_trusted_listxattr(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 const struct xattr_handler jffs2_trusted_xattr_handler = {
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 1c46573a96ed..e4f44f5133a1 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -859,7 +859,8 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
 static inline int can_list(struct jfs_ea *ea)
 {
 	return (!strncmp(ea->name, XATTR_TRUSTED_PREFIX,
-			 XATTR_TRUSTED_PREFIX_LEN) || capable(CAP_SYS_ADMIN));
+			 XATTR_TRUSTED_PREFIX_LEN) ||
+		capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED));
 }
 
 ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 5fdf269ba82e..2b3994d192c6 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -906,7 +906,7 @@ static int ocfs2_xattr_list_entry(struct super_block *sb,
 		break;
 
 	case OCFS2_XATTR_INDEX_TRUSTED:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return 0;
 		break;
 	}
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index a619addecafc..c627003d3a74 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -264,7 +264,8 @@ static bool ovl_can_list(const char *s)
 		return true;
 
 	/* Never list trusted.overlay, list other trusted for superuser only */
-	return !ovl_is_private_xattr(s) && capable(CAP_SYS_ADMIN);
+	return !ovl_is_private_xattr(s) &&
+		(capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED));
 }
 
 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c
index f15a5f9e84ce..6f3fa0db8272 100644
--- a/fs/reiserfs/xattr_trusted.c
+++ b/fs/reiserfs/xattr_trusted.c
@@ -7,11 +7,16 @@
 #include "xattr.h"
 #include <linux/uaccess.h>
 
+inline bool trusted_capable(void)
+{
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
+}
+
 static int
 trusted_get(const struct xattr_handler *handler, struct dentry *unused,
 	    struct inode *inode, const char *name, void *buffer, size_t size)
 {
-	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
+	if (!trusted_capable() || IS_PRIVATE(inode))
 		return -EPERM;
 
 	return reiserfs_xattr_get(inode, xattr_full_name(handler, name),
@@ -23,7 +28,7 @@ trusted_set(const struct xattr_handler *handler, struct dentry *unused,
 	    struct inode *inode, const char *name, const void *buffer,
 	    size_t size, int flags)
 {
-	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
+	if (!trusted_capable() || IS_PRIVATE(inode))
 		return -EPERM;
 
 	return reiserfs_xattr_set(inode,
@@ -33,7 +38,7 @@ trusted_set(const struct xattr_handler *handler, struct dentry *unused,
 
 static bool trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN) && !IS_PRIVATE(d_inode(dentry));
+	return trusted_capable() && !IS_PRIVATE(d_inode(dentry));
 }
 
 const struct xattr_handler reiserfs_xattr_trusted_handler = {
diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c
index 1548b3784548..e0a285ab1f7e 100644
--- a/fs/squashfs/xattr.c
+++ b/fs/squashfs/xattr.c
@@ -237,7 +237,7 @@ static const struct xattr_handler squashfs_xattr_user_handler = {
  */
 static bool squashfs_trusted_xattr_handler_list(struct dentry *d)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static const struct xattr_handler squashfs_xattr_trusted_handler = {
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index c13eae819cbc..f3aa8be72a66 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -406,7 +406,8 @@ static bool xattr_visible(const char *name)
 
 	/* Show trusted namespace only for "power" users */
 	if (strncmp(name, XATTR_TRUSTED_PREFIX,
-		    XATTR_TRUSTED_PREFIX_LEN) == 0 && !capable(CAP_SYS_ADMIN))
+		    XATTR_TRUSTED_PREFIX_LEN) == 0 &&
+	    !capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 		return false;
 
 	return true;
diff --git a/fs/xattr.c b/fs/xattr.c
index 61cd28ba25f3..d9e9a0083dbb 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -113,7 +113,7 @@ xattr_permission(struct inode *inode, const char *name, int mask)
 	 * The trusted.* namespace can only be accessed by privileged users.
 	 */
 	if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
 		return 0;
 	}
@@ -945,7 +945,7 @@ static int xattr_list_one(char **buffer, ssize_t *remaining_size,
 ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
 			  char *buffer, size_t size)
 {
-	bool trusted = capable(CAP_SYS_ADMIN);
+	bool trusted = capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 	struct simple_xattr *xattr;
 	ssize_t remaining_size = size;
 	int err = 0;
-- 
2.14.2

WARNING: multiple messages have this Message-ID (diff)
From: Nicolas Belouin <nicolas@belouin.fr>
To: Jan Kara <jack@suse.com>, "Theodore Ts'o" <tytso@mit.edu>,
	Andreas Dilger <adilger.kernel@dilger.ca>,
	Jaegeuk Kim <jaegeuk@kernel.org>, Chao Yu <yuchao0@huawei.com>,
	David Woodhouse <dwmw2@infradead.org>,
	Dave Kleikamp <shaggy@kernel.org>,
	Mark Fasheh <mfasheh@versity.com>,
	Joel Becker <jlbec@evilplan.org>,
	Miklos Szeredi <miklos@szeredi.hu>,
	Phillip Lougher <phillip@squashfs.org.uk>,
	Richard Weinberger <richard@nod.at>,
	Artem Bityutskiy <dedekind1@gmail.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	Serge Hallyn <serge@hallyn.com>, Paul Moore <paul@paul-moore.com>,
	Stephen Smalley <sds@tycho.nsa.gov>,
	Eric Paris <eparis@parisplace.org>,
	James Morris <james.l.morris@oracle.com>,
	linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net,
	linux-fsdevel@vger.kernel.org, linux-mtd@lists.infrad
Cc: Nicolas Belouin <nicolas@belouin.fr>
Subject: [RFC PATCH 2/2] fs: Grant CAP_TRUSTED rw access to trusted xattrs
Date: Sat, 21 Oct 2017 15:45:58 +0200	[thread overview]
Message-ID: <20171021134558.21195-2-nicolas@belouin.fr> (raw)
In-Reply-To: <20171021134558.21195-1-nicolas@belouin.fr>

The trusted xattrs read/write access is the perfect use case for
CAP_TRUSTED.

Signed-off-by: Nicolas Belouin <nicolas@belouin.fr>
---
 fs/ext2/xattr_trusted.c     |  2 +-
 fs/ext4/xattr_trusted.c     |  2 +-
 fs/f2fs/xattr.c             |  6 +++---
 fs/hfsplus/xattr.c          |  2 +-
 fs/jffs2/xattr_trusted.c    |  2 +-
 fs/jfs/xattr.c              |  3 ++-
 fs/ocfs2/xattr.c            |  2 +-
 fs/overlayfs/inode.c        |  3 ++-
 fs/reiserfs/xattr_trusted.c | 11 ++++++++---
 fs/squashfs/xattr.c         |  2 +-
 fs/ubifs/xattr.c            |  3 ++-
 fs/xattr.c                  |  4 ++--
 12 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c
index 65049b71af13..8006c24f8ee0 100644
--- a/fs/ext2/xattr_trusted.c
+++ b/fs/ext2/xattr_trusted.c
@@ -11,7 +11,7 @@
 static bool
 ext2_xattr_trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static int
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c
index c7765c735714..9849d1e0ebb9 100644
--- a/fs/ext4/xattr_trusted.c
+++ b/fs/ext4/xattr_trusted.c
@@ -15,7 +15,7 @@
 static bool
 ext4_xattr_trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static int
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 7c65540148f8..ef572464deca 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -37,7 +37,7 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
 			return -EOPNOTSUPP;
 		break;
 	case F2FS_XATTR_INDEX_TRUSTED:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return -EPERM;
 		break;
 	case F2FS_XATTR_INDEX_SECURITY:
@@ -62,7 +62,7 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
 			return -EOPNOTSUPP;
 		break;
 	case F2FS_XATTR_INDEX_TRUSTED:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return -EPERM;
 		break;
 	case F2FS_XATTR_INDEX_SECURITY:
@@ -83,7 +83,7 @@ static bool f2fs_xattr_user_list(struct dentry *dentry)
 
 static bool f2fs_xattr_trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index ae03a19196ef..0ec6d02ee7e9 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -606,7 +606,7 @@ static inline int can_list(const char *xattr_name)
 
 	return !strncmp(xattr_name, XATTR_TRUSTED_PREFIX,
 			XATTR_TRUSTED_PREFIX_LEN) ||
-				capable(CAP_SYS_ADMIN);
+				capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static ssize_t hfsplus_listxattr_finder_info(struct dentry *dentry,
diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c
index 5d6030826c52..3c7ae98e4525 100644
--- a/fs/jffs2/xattr_trusted.c
+++ b/fs/jffs2/xattr_trusted.c
@@ -35,7 +35,7 @@ static int jffs2_trusted_setxattr(const struct xattr_handler *handler,
 
 static bool jffs2_trusted_listxattr(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 const struct xattr_handler jffs2_trusted_xattr_handler = {
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 1c46573a96ed..e4f44f5133a1 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -859,7 +859,8 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
 static inline int can_list(struct jfs_ea *ea)
 {
 	return (!strncmp(ea->name, XATTR_TRUSTED_PREFIX,
-			 XATTR_TRUSTED_PREFIX_LEN) || capable(CAP_SYS_ADMIN));
+			 XATTR_TRUSTED_PREFIX_LEN) ||
+		capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED));
 }
 
 ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 5fdf269ba82e..2b3994d192c6 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -906,7 +906,7 @@ static int ocfs2_xattr_list_entry(struct super_block *sb,
 		break;
 
 	case OCFS2_XATTR_INDEX_TRUSTED:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return 0;
 		break;
 	}
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index a619addecafc..c627003d3a74 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -264,7 +264,8 @@ static bool ovl_can_list(const char *s)
 		return true;
 
 	/* Never list trusted.overlay, list other trusted for superuser only */
-	return !ovl_is_private_xattr(s) && capable(CAP_SYS_ADMIN);
+	return !ovl_is_private_xattr(s) &&
+		(capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED));
 }
 
 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c
index f15a5f9e84ce..6f3fa0db8272 100644
--- a/fs/reiserfs/xattr_trusted.c
+++ b/fs/reiserfs/xattr_trusted.c
@@ -7,11 +7,16 @@
 #include "xattr.h"
 #include <linux/uaccess.h>
 
+inline bool trusted_capable(void)
+{
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
+}
+
 static int
 trusted_get(const struct xattr_handler *handler, struct dentry *unused,
 	    struct inode *inode, const char *name, void *buffer, size_t size)
 {
-	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
+	if (!trusted_capable() || IS_PRIVATE(inode))
 		return -EPERM;
 
 	return reiserfs_xattr_get(inode, xattr_full_name(handler, name),
@@ -23,7 +28,7 @@ trusted_set(const struct xattr_handler *handler, struct dentry *unused,
 	    struct inode *inode, const char *name, const void *buffer,
 	    size_t size, int flags)
 {
-	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
+	if (!trusted_capable() || IS_PRIVATE(inode))
 		return -EPERM;
 
 	return reiserfs_xattr_set(inode,
@@ -33,7 +38,7 @@ trusted_set(const struct xattr_handler *handler, struct dentry *unused,
 
 static bool trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN) && !IS_PRIVATE(d_inode(dentry));
+	return trusted_capable() && !IS_PRIVATE(d_inode(dentry));
 }
 
 const struct xattr_handler reiserfs_xattr_trusted_handler = {
diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c
index 1548b3784548..e0a285ab1f7e 100644
--- a/fs/squashfs/xattr.c
+++ b/fs/squashfs/xattr.c
@@ -237,7 +237,7 @@ static const struct xattr_handler squashfs_xattr_user_handler = {
  */
 static bool squashfs_trusted_xattr_handler_list(struct dentry *d)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static const struct xattr_handler squashfs_xattr_trusted_handler = {
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index c13eae819cbc..f3aa8be72a66 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -406,7 +406,8 @@ static bool xattr_visible(const char *name)
 
 	/* Show trusted namespace only for "power" users */
 	if (strncmp(name, XATTR_TRUSTED_PREFIX,
-		    XATTR_TRUSTED_PREFIX_LEN) == 0 && !capable(CAP_SYS_ADMIN))
+		    XATTR_TRUSTED_PREFIX_LEN) == 0 &&
+	    !capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 		return false;
 
 	return true;
diff --git a/fs/xattr.c b/fs/xattr.c
index 61cd28ba25f3..d9e9a0083dbb 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -113,7 +113,7 @@ xattr_permission(struct inode *inode, const char *name, int mask)
 	 * The trusted.* namespace can only be accessed by privileged users.
 	 */
 	if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
 		return 0;
 	}
@@ -945,7 +945,7 @@ static int xattr_list_one(char **buffer, ssize_t *remaining_size,
 ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
 			  char *buffer, size_t size)
 {
-	bool trusted = capable(CAP_SYS_ADMIN);
+	bool trusted = capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 	struct simple_xattr *xattr;
 	ssize_t remaining_size = size;
 	int err = 0;
-- 
2.14.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

WARNING: multiple messages have this Message-ID (diff)
From: nicolas@belouin.fr (Nicolas Belouin)
To: linux-security-module@vger.kernel.org
Subject: [RFC PATCH 2/2] fs: Grant CAP_TRUSTED rw access to trusted xattrs
Date: Sat, 21 Oct 2017 15:45:58 +0200	[thread overview]
Message-ID: <20171021134558.21195-2-nicolas@belouin.fr> (raw)
In-Reply-To: <20171021134558.21195-1-nicolas@belouin.fr>

The trusted xattrs read/write access is the perfect use case for
CAP_TRUSTED.

Signed-off-by: Nicolas Belouin <nicolas@belouin.fr>
---
 fs/ext2/xattr_trusted.c     |  2 +-
 fs/ext4/xattr_trusted.c     |  2 +-
 fs/f2fs/xattr.c             |  6 +++---
 fs/hfsplus/xattr.c          |  2 +-
 fs/jffs2/xattr_trusted.c    |  2 +-
 fs/jfs/xattr.c              |  3 ++-
 fs/ocfs2/xattr.c            |  2 +-
 fs/overlayfs/inode.c        |  3 ++-
 fs/reiserfs/xattr_trusted.c | 11 ++++++++---
 fs/squashfs/xattr.c         |  2 +-
 fs/ubifs/xattr.c            |  3 ++-
 fs/xattr.c                  |  4 ++--
 12 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c
index 65049b71af13..8006c24f8ee0 100644
--- a/fs/ext2/xattr_trusted.c
+++ b/fs/ext2/xattr_trusted.c
@@ -11,7 +11,7 @@
 static bool
 ext2_xattr_trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static int
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c
index c7765c735714..9849d1e0ebb9 100644
--- a/fs/ext4/xattr_trusted.c
+++ b/fs/ext4/xattr_trusted.c
@@ -15,7 +15,7 @@
 static bool
 ext4_xattr_trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static int
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 7c65540148f8..ef572464deca 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -37,7 +37,7 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
 			return -EOPNOTSUPP;
 		break;
 	case F2FS_XATTR_INDEX_TRUSTED:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return -EPERM;
 		break;
 	case F2FS_XATTR_INDEX_SECURITY:
@@ -62,7 +62,7 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
 			return -EOPNOTSUPP;
 		break;
 	case F2FS_XATTR_INDEX_TRUSTED:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return -EPERM;
 		break;
 	case F2FS_XATTR_INDEX_SECURITY:
@@ -83,7 +83,7 @@ static bool f2fs_xattr_user_list(struct dentry *dentry)
 
 static bool f2fs_xattr_trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index ae03a19196ef..0ec6d02ee7e9 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -606,7 +606,7 @@ static inline int can_list(const char *xattr_name)
 
 	return !strncmp(xattr_name, XATTR_TRUSTED_PREFIX,
 			XATTR_TRUSTED_PREFIX_LEN) ||
-				capable(CAP_SYS_ADMIN);
+				capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static ssize_t hfsplus_listxattr_finder_info(struct dentry *dentry,
diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c
index 5d6030826c52..3c7ae98e4525 100644
--- a/fs/jffs2/xattr_trusted.c
+++ b/fs/jffs2/xattr_trusted.c
@@ -35,7 +35,7 @@ static int jffs2_trusted_setxattr(const struct xattr_handler *handler,
 
 static bool jffs2_trusted_listxattr(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 const struct xattr_handler jffs2_trusted_xattr_handler = {
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 1c46573a96ed..e4f44f5133a1 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -859,7 +859,8 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
 static inline int can_list(struct jfs_ea *ea)
 {
 	return (!strncmp(ea->name, XATTR_TRUSTED_PREFIX,
-			 XATTR_TRUSTED_PREFIX_LEN) || capable(CAP_SYS_ADMIN));
+			 XATTR_TRUSTED_PREFIX_LEN) ||
+		capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED));
 }
 
 ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 5fdf269ba82e..2b3994d192c6 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -906,7 +906,7 @@ static int ocfs2_xattr_list_entry(struct super_block *sb,
 		break;
 
 	case OCFS2_XATTR_INDEX_TRUSTED:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return 0;
 		break;
 	}
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index a619addecafc..c627003d3a74 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -264,7 +264,8 @@ static bool ovl_can_list(const char *s)
 		return true;
 
 	/* Never list trusted.overlay, list other trusted for superuser only */
-	return !ovl_is_private_xattr(s) && capable(CAP_SYS_ADMIN);
+	return !ovl_is_private_xattr(s) &&
+		(capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED));
 }
 
 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c
index f15a5f9e84ce..6f3fa0db8272 100644
--- a/fs/reiserfs/xattr_trusted.c
+++ b/fs/reiserfs/xattr_trusted.c
@@ -7,11 +7,16 @@
 #include "xattr.h"
 #include <linux/uaccess.h>
 
+inline bool trusted_capable(void)
+{
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
+}
+
 static int
 trusted_get(const struct xattr_handler *handler, struct dentry *unused,
 	    struct inode *inode, const char *name, void *buffer, size_t size)
 {
-	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
+	if (!trusted_capable() || IS_PRIVATE(inode))
 		return -EPERM;
 
 	return reiserfs_xattr_get(inode, xattr_full_name(handler, name),
@@ -23,7 +28,7 @@ trusted_set(const struct xattr_handler *handler, struct dentry *unused,
 	    struct inode *inode, const char *name, const void *buffer,
 	    size_t size, int flags)
 {
-	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
+	if (!trusted_capable() || IS_PRIVATE(inode))
 		return -EPERM;
 
 	return reiserfs_xattr_set(inode,
@@ -33,7 +38,7 @@ trusted_set(const struct xattr_handler *handler, struct dentry *unused,
 
 static bool trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN) && !IS_PRIVATE(d_inode(dentry));
+	return trusted_capable() && !IS_PRIVATE(d_inode(dentry));
 }
 
 const struct xattr_handler reiserfs_xattr_trusted_handler = {
diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c
index 1548b3784548..e0a285ab1f7e 100644
--- a/fs/squashfs/xattr.c
+++ b/fs/squashfs/xattr.c
@@ -237,7 +237,7 @@ static const struct xattr_handler squashfs_xattr_user_handler = {
  */
 static bool squashfs_trusted_xattr_handler_list(struct dentry *d)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static const struct xattr_handler squashfs_xattr_trusted_handler = {
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index c13eae819cbc..f3aa8be72a66 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -406,7 +406,8 @@ static bool xattr_visible(const char *name)
 
 	/* Show trusted namespace only for "power" users */
 	if (strncmp(name, XATTR_TRUSTED_PREFIX,
-		    XATTR_TRUSTED_PREFIX_LEN) == 0 && !capable(CAP_SYS_ADMIN))
+		    XATTR_TRUSTED_PREFIX_LEN) == 0 &&
+	    !capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 		return false;
 
 	return true;
diff --git a/fs/xattr.c b/fs/xattr.c
index 61cd28ba25f3..d9e9a0083dbb 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -113,7 +113,7 @@ xattr_permission(struct inode *inode, const char *name, int mask)
 	 * The trusted.* namespace can only be accessed by privileged users.
 	 */
 	if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
 		return 0;
 	}
@@ -945,7 +945,7 @@ static int xattr_list_one(char **buffer, ssize_t *remaining_size,
 ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
 			  char *buffer, size_t size)
 {
-	bool trusted = capable(CAP_SYS_ADMIN);
+	bool trusted = capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 	struct simple_xattr *xattr;
 	ssize_t remaining_size = size;
 	int err = 0;
-- 
2.14.2

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

WARNING: multiple messages have this Message-ID (diff)
From: Nicolas Belouin <nicolas@belouin.fr>
To: Jan Kara <jack@suse.com>, Theodore Ts'o <tytso@mit.edu>,
	Andreas Dilger <adilger.kernel@dilger.ca>,
	Jaegeuk Kim <jaegeuk@kernel.org>, Chao Yu <yuchao0@huawei.com>,
	David Woodhouse <dwmw2@infradead.org>,
	Dave Kleikamp <shaggy@kernel.org>,
	Mark Fasheh <mfasheh@versity.com>,
	Joel Becker <jlbec@evilplan.org>,
	Miklos Szeredi <miklos@szeredi.hu>,
	Phillip Lougher <phillip@squashfs.org.uk>,
	Richard Weinberger <richard@nod.at>,
	Artem Bityutskiy <dedekind1@gmail.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	Serge Hallyn <serge@hallyn.com>, Paul Moore <paul@paul-moore.com>,
	Stephen Smalley <sds@tycho.nsa.gov>,
	Eric Paris <eparis@parisplace.org>,
	James Morris <james.l.morris@oracle.com>,
	linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net,
	linux-fsdevel@vger.kernel.org, linux-mtd@lists.infradead.org,
	jfs-discussion@lists.sourceforge.net, ocfs2-devel@oss.oracle.com,
	linux-unionfs@vger.kernel.org, reiserfs-devel@vger.kernel.org,
	linux-security-module@vger.kernel.org, selinux@tycho.nsa.gov,
	linux-api@vger.kernel.org, kernel-hardening@lists.openwall.com
Cc: Nicolas Belouin <nicolas@belouin.fr>
Subject: [kernel-hardening] [RFC PATCH 2/2] fs: Grant CAP_TRUSTED rw access to trusted xattrs
Date: Sat, 21 Oct 2017 15:45:58 +0200	[thread overview]
Message-ID: <20171021134558.21195-2-nicolas@belouin.fr> (raw)
In-Reply-To: <20171021134558.21195-1-nicolas@belouin.fr>

The trusted xattrs read/write access is the perfect use case for
CAP_TRUSTED.

Signed-off-by: Nicolas Belouin <nicolas@belouin.fr>
---
 fs/ext2/xattr_trusted.c     |  2 +-
 fs/ext4/xattr_trusted.c     |  2 +-
 fs/f2fs/xattr.c             |  6 +++---
 fs/hfsplus/xattr.c          |  2 +-
 fs/jffs2/xattr_trusted.c    |  2 +-
 fs/jfs/xattr.c              |  3 ++-
 fs/ocfs2/xattr.c            |  2 +-
 fs/overlayfs/inode.c        |  3 ++-
 fs/reiserfs/xattr_trusted.c | 11 ++++++++---
 fs/squashfs/xattr.c         |  2 +-
 fs/ubifs/xattr.c            |  3 ++-
 fs/xattr.c                  |  4 ++--
 12 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c
index 65049b71af13..8006c24f8ee0 100644
--- a/fs/ext2/xattr_trusted.c
+++ b/fs/ext2/xattr_trusted.c
@@ -11,7 +11,7 @@
 static bool
 ext2_xattr_trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static int
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c
index c7765c735714..9849d1e0ebb9 100644
--- a/fs/ext4/xattr_trusted.c
+++ b/fs/ext4/xattr_trusted.c
@@ -15,7 +15,7 @@
 static bool
 ext4_xattr_trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static int
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 7c65540148f8..ef572464deca 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -37,7 +37,7 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
 			return -EOPNOTSUPP;
 		break;
 	case F2FS_XATTR_INDEX_TRUSTED:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return -EPERM;
 		break;
 	case F2FS_XATTR_INDEX_SECURITY:
@@ -62,7 +62,7 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
 			return -EOPNOTSUPP;
 		break;
 	case F2FS_XATTR_INDEX_TRUSTED:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return -EPERM;
 		break;
 	case F2FS_XATTR_INDEX_SECURITY:
@@ -83,7 +83,7 @@ static bool f2fs_xattr_user_list(struct dentry *dentry)
 
 static bool f2fs_xattr_trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index ae03a19196ef..0ec6d02ee7e9 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -606,7 +606,7 @@ static inline int can_list(const char *xattr_name)
 
 	return !strncmp(xattr_name, XATTR_TRUSTED_PREFIX,
 			XATTR_TRUSTED_PREFIX_LEN) ||
-				capable(CAP_SYS_ADMIN);
+				capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static ssize_t hfsplus_listxattr_finder_info(struct dentry *dentry,
diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c
index 5d6030826c52..3c7ae98e4525 100644
--- a/fs/jffs2/xattr_trusted.c
+++ b/fs/jffs2/xattr_trusted.c
@@ -35,7 +35,7 @@ static int jffs2_trusted_setxattr(const struct xattr_handler *handler,
 
 static bool jffs2_trusted_listxattr(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 const struct xattr_handler jffs2_trusted_xattr_handler = {
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 1c46573a96ed..e4f44f5133a1 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -859,7 +859,8 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
 static inline int can_list(struct jfs_ea *ea)
 {
 	return (!strncmp(ea->name, XATTR_TRUSTED_PREFIX,
-			 XATTR_TRUSTED_PREFIX_LEN) || capable(CAP_SYS_ADMIN));
+			 XATTR_TRUSTED_PREFIX_LEN) ||
+		capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED));
 }
 
 ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 5fdf269ba82e..2b3994d192c6 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -906,7 +906,7 @@ static int ocfs2_xattr_list_entry(struct super_block *sb,
 		break;
 
 	case OCFS2_XATTR_INDEX_TRUSTED:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return 0;
 		break;
 	}
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index a619addecafc..c627003d3a74 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -264,7 +264,8 @@ static bool ovl_can_list(const char *s)
 		return true;
 
 	/* Never list trusted.overlay, list other trusted for superuser only */
-	return !ovl_is_private_xattr(s) && capable(CAP_SYS_ADMIN);
+	return !ovl_is_private_xattr(s) &&
+		(capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED));
 }
 
 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c
index f15a5f9e84ce..6f3fa0db8272 100644
--- a/fs/reiserfs/xattr_trusted.c
+++ b/fs/reiserfs/xattr_trusted.c
@@ -7,11 +7,16 @@
 #include "xattr.h"
 #include <linux/uaccess.h>
 
+inline bool trusted_capable(void)
+{
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
+}
+
 static int
 trusted_get(const struct xattr_handler *handler, struct dentry *unused,
 	    struct inode *inode, const char *name, void *buffer, size_t size)
 {
-	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
+	if (!trusted_capable() || IS_PRIVATE(inode))
 		return -EPERM;
 
 	return reiserfs_xattr_get(inode, xattr_full_name(handler, name),
@@ -23,7 +28,7 @@ trusted_set(const struct xattr_handler *handler, struct dentry *unused,
 	    struct inode *inode, const char *name, const void *buffer,
 	    size_t size, int flags)
 {
-	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
+	if (!trusted_capable() || IS_PRIVATE(inode))
 		return -EPERM;
 
 	return reiserfs_xattr_set(inode,
@@ -33,7 +38,7 @@ trusted_set(const struct xattr_handler *handler, struct dentry *unused,
 
 static bool trusted_list(struct dentry *dentry)
 {
-	return capable(CAP_SYS_ADMIN) && !IS_PRIVATE(d_inode(dentry));
+	return trusted_capable() && !IS_PRIVATE(d_inode(dentry));
 }
 
 const struct xattr_handler reiserfs_xattr_trusted_handler = {
diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c
index 1548b3784548..e0a285ab1f7e 100644
--- a/fs/squashfs/xattr.c
+++ b/fs/squashfs/xattr.c
@@ -237,7 +237,7 @@ static const struct xattr_handler squashfs_xattr_user_handler = {
  */
 static bool squashfs_trusted_xattr_handler_list(struct dentry *d)
 {
-	return capable(CAP_SYS_ADMIN);
+	return capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 }
 
 static const struct xattr_handler squashfs_xattr_trusted_handler = {
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index c13eae819cbc..f3aa8be72a66 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -406,7 +406,8 @@ static bool xattr_visible(const char *name)
 
 	/* Show trusted namespace only for "power" users */
 	if (strncmp(name, XATTR_TRUSTED_PREFIX,
-		    XATTR_TRUSTED_PREFIX_LEN) == 0 && !capable(CAP_SYS_ADMIN))
+		    XATTR_TRUSTED_PREFIX_LEN) == 0 &&
+	    !capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 		return false;
 
 	return true;
diff --git a/fs/xattr.c b/fs/xattr.c
index 61cd28ba25f3..d9e9a0083dbb 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -113,7 +113,7 @@ xattr_permission(struct inode *inode, const char *name, int mask)
 	 * The trusted.* namespace can only be accessed by privileged users.
 	 */
 	if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
-		if (!capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_TRUSTED))
 			return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
 		return 0;
 	}
@@ -945,7 +945,7 @@ static int xattr_list_one(char **buffer, ssize_t *remaining_size,
 ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
 			  char *buffer, size_t size)
 {
-	bool trusted = capable(CAP_SYS_ADMIN);
+	bool trusted = capable(CAP_SYS_ADMIN) || capable(CAP_TRUSTED);
 	struct simple_xattr *xattr;
 	ssize_t remaining_size = size;
 	int err = 0;
-- 
2.14.2

  parent reply	other threads:[~2017-10-21 13:45 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-21 13:45 [RFC PATCH 1/2] security, capabilities: create CAP_TRUSTED Nicolas Belouin
2017-10-21 13:45 ` [kernel-hardening] " Nicolas Belouin
2017-10-21 13:45 ` Nicolas Belouin
2017-10-21 13:45 ` Nicolas Belouin
2017-10-21 13:45 ` [RFC PATCH 2/2] fs: Grant CAP_TRUSTED rw access to trusted xattrs Nicolas Belouin
2017-10-21 13:45 ` Nicolas Belouin [this message]
2017-10-21 13:45   ` [kernel-hardening] " Nicolas Belouin
2017-10-21 13:45   ` Nicolas Belouin
2017-10-21 13:45   ` Nicolas Belouin
2017-10-21 13:45 ` Nicolas Belouin
2017-10-21 16:03 ` [RFC PATCH 1/2] security, capabilities: create CAP_TRUSTED Serge E. Hallyn
2017-10-21 16:03   ` [kernel-hardening] " Serge E. Hallyn
2017-10-21 16:03   ` Serge E. Hallyn
2017-10-21 16:03   ` Serge E. Hallyn
2017-10-21 19:09   ` nicolas
2017-10-21 19:09     ` nicolas at belouin.fr
2017-10-21 19:09   ` nicolas
2017-10-21 19:09   ` nicolas
2017-10-21 19:09   ` nicolas
     [not found]   ` <20171021160302.GA2842-7LNsyQBKDXoIagZqoN9o3w@public.gmane.org>
2017-10-21 19:09     ` nicolas-6zwZCx3K5ONGWvitb5QawA
2017-10-21 19:09   ` nicolas
2017-10-21 17:25 ` [kernel-hardening] " Casey Schaufler
2017-10-21 17:25 ` Casey Schaufler
2017-10-21 17:25 ` Casey Schaufler
2017-10-21 17:25 ` [kernel-hardening] " Casey Schaufler
2017-10-21 17:25 ` Casey Schaufler
     [not found] ` <20171021134558.21195-1-nicolas-6zwZCx3K5ONGWvitb5QawA@public.gmane.org>
2017-10-21 13:45   ` [RFC PATCH 2/2] fs: Grant CAP_TRUSTED rw access to trusted xattrs Nicolas Belouin
2017-10-21 17:25   ` [kernel-hardening] [RFC PATCH 1/2] security, capabilities: create CAP_TRUSTED Casey Schaufler
2017-10-21 17:25   ` Casey Schaufler
2017-10-21 17:25 ` Casey Schaufler
2017-10-21 17:25   ` Casey Schaufler
2017-10-21 17:25   ` Casey Schaufler
2017-10-21 17:25   ` Casey Schaufler
     [not found]   ` <d3e1c911-138d-082a-b941-651217d0faf8-iSGtlc1asvQWG2LlvL+J4A@public.gmane.org>
2017-10-21 19:04     ` nicolas-6zwZCx3K5ONGWvitb5QawA
2017-10-21 19:04   ` nicolas
2017-10-21 19:04   ` nicolas
2017-10-21 19:04     ` nicolas
2017-10-21 19:04     ` nicolas at belouin.fr
2017-10-21 19:04   ` nicolas
2017-10-21 19:04   ` nicolas
2017-10-21 19:04   ` nicolas
2017-10-21 17:25 ` Casey Schaufler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171021134558.21195-2-nicolas@belouin.fr \
    --to=nicolas@belouin.fr \
    --cc=adilger.kernel@dilger.ca \
    --cc=adrian.hunter@intel.com \
    --cc=dedekind1@gmail.com \
    --cc=dwmw2@infradead.org \
    --cc=eparis@parisplace.org \
    --cc=jack@suse.com \
    --cc=jaegeuk@kernel.org \
    --cc=james.l.morris@oracle.com \
    --cc=jfs-discussion@lists.sourceforge.net \
    --cc=jlbec@evilplan.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=mfasheh@versity.com \
    --cc=miklos@szeredi.hu \
    --cc=ocfs2-devel@oss.oracle.com \
    --cc=paul@paul-moore.com \
    --cc=phillip@squashfs.org.uk \
    --cc=reiserfs-devel@vger.kernel.org \
    --cc=richard@nod.at \
    --cc=sds@tycho.nsa.gov \
    --cc=selinux@tycho.nsa.gov \
    --cc=serge@hallyn.com \
    --cc=shaggy@kernel.org \
    --cc=tytso@mit.edu \
    --cc=viro@zeniv.linux.org.uk \
    --cc=yuchao0@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.