linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/3] initxattr callback update for mqueue xattr support
@ 2017-01-05 22:03 David Graziano
  2017-01-05 22:03 ` [PATCH v4 1/3] xattr: add simple initxattrs function David Graziano
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: David Graziano @ 2017-01-05 22:03 UTC (permalink / raw)
  To: linux-security-module, paul
  Cc: agruenba, hch, linux-mm, sds, linux-kernel, David Graziano

This patchset is for implementing extended attribute support within the 
POSIX message queue (mqueue) file system. This is needed so that the 
security.selinux extended attribute can be set via a SELinux named type 
transition on file inodes created within the filesystem. I needed to 
write a selinux policy for a set of custom applications that use mqueues 
for their IPC. The mqueues are created by one application and we needed 
a way for selinux to enforce which of the other application are able to 
read/write to each individual queue. Uniquely labelling them based on the 
application that created them and the filename seemed to be our best 
solution as it’s an embedded system and we don’t have restorecond to 
handle any relabeling.

This series is a result of feedback from the v2 mqueue patch 
( http://marc.info/?l=linux-kernel&m=147855351826081&w=2 ) which 
duplicated the shmem_initxattrs() function for the mqueue file system. 
This patcheset creates a common simple_xattr_initxattrs() function that 
can be used by multiple virtual file systems to handle extended attribute 
initialization via LSM callback. simple_xattr_initxattrs() is an updated 
version of shmem_initxattrs(). As part of the this series both shmem and 
mqueue are updated to use the new common initxattrs function. 

Changes v3 -> v4:
 - fix uninitialized variable in mqueue patch (3/3)

Changes v2 -> v3:
 - creates new simple_xattr_initxattrs() function
 - updates shmem to use new callback function
 - updates mqueue to use new callback function

Changes v1 -> v2:
 - formatting/commit message


David Graziano (3):
  xattr: add simple initxattrs function
  shmem: use simple initxattrs callback
  mqueue: Implement generic xattr support

 fs/xattr.c            | 39 +++++++++++++++++++++++++++++++++++++
 include/linux/xattr.h |  3 +++
 ipc/mqueue.c          | 16 ++++++++++++++++
 mm/shmem.c            | 53 ++++++++++++---------------------------------------
 4 files changed, 70 insertions(+), 41 deletions(-)

-- 
1.9.1

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

* [PATCH v4 1/3] xattr: add simple initxattrs function
  2017-01-05 22:03 [PATCH v4 0/3] initxattr callback update for mqueue xattr support David Graziano
@ 2017-01-05 22:03 ` David Graziano
  2017-01-08  9:55   ` Christoph Hellwig
  2017-01-05 22:03 ` [PATCH v4 2/3] shmem: use simple initxattrs callback David Graziano
  2017-01-05 22:03 ` [PATCH v4 3/3] mqueue: Implement generic xattr support David Graziano
  2 siblings, 1 reply; 6+ messages in thread
From: David Graziano @ 2017-01-05 22:03 UTC (permalink / raw)
  To: linux-security-module, paul
  Cc: agruenba, hch, linux-mm, sds, linux-kernel, David Graziano

Adds new simple_xattr_initxattrs() initialization function for
initializing the extended attributes via LSM callback. Based
on callback function used by tmpfs/shmem. This is allows for
consolidation and avoiding code duplication when other filesystem
need to implement a simple initxattrs LSM callback function.

Signed-off-by: David Graziano <david.graziano@rockwellcollins.com>
---
 fs/xattr.c            | 39 +++++++++++++++++++++++++++++++++++++++
 include/linux/xattr.h |  3 +++
 2 files changed, 42 insertions(+)

diff --git a/fs/xattr.c b/fs/xattr.c
index c243905..69dd142 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -994,3 +994,42 @@ void simple_xattr_list_add(struct simple_xattrs *xattrs,
 	list_add(&new_xattr->list, &xattrs->head);
 	spin_unlock(&xattrs->lock);
 }
+
+/*
+ * Callback for security_inode_init_security() for acquiring xattrs.
+ */
+int simple_xattr_initxattrs(struct inode *inode,
+			    const struct xattr *xattr_array,
+			    void *fs_info)
+{
+	struct simple_xattrs *xattrs;
+	const struct xattr *xattr;
+	struct simple_xattr *new_xattr;
+	size_t len;
+
+	if (!fs_info)
+		return -ENOMEM;
+	xattrs = (struct simple_xattrs *) fs_info;
+
+	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
+		new_xattr = simple_xattr_alloc(xattr->value, xattr->value_len);
+		if (!new_xattr)
+			return -ENOMEM;
+		len = strlen(xattr->name) + 1;
+		new_xattr->name = kmalloc(XATTR_SECURITY_PREFIX_LEN + len,
+					  GFP_KERNEL);
+		if (!new_xattr->name) {
+			kfree(new_xattr);
+			return -ENOMEM;
+		}
+
+		memcpy(new_xattr->name, XATTR_SECURITY_PREFIX,
+		       XATTR_SECURITY_PREFIX_LEN);
+		memcpy(new_xattr->name + XATTR_SECURITY_PREFIX_LEN,
+		       xattr->name, len);
+
+		simple_xattr_list_add(xattrs, new_xattr);
+	}
+
+	return 0;
+}
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 94079ba..a787d1a 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -108,5 +108,8 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs, cha
 			  size_t size);
 void simple_xattr_list_add(struct simple_xattrs *xattrs,
 			   struct simple_xattr *new_xattr);
+int simple_xattr_initxattrs(struct inode *inode,
+			    const struct xattr *xattr_array,
+			    void *fs_info);
 
 #endif	/* _LINUX_XATTR_H */
-- 
1.9.1

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

* [PATCH v4 2/3] shmem: use simple initxattrs callback
  2017-01-05 22:03 [PATCH v4 0/3] initxattr callback update for mqueue xattr support David Graziano
  2017-01-05 22:03 ` [PATCH v4 1/3] xattr: add simple initxattrs function David Graziano
@ 2017-01-05 22:03 ` David Graziano
  2017-01-05 22:03 ` [PATCH v4 3/3] mqueue: Implement generic xattr support David Graziano
  2 siblings, 0 replies; 6+ messages in thread
From: David Graziano @ 2017-01-05 22:03 UTC (permalink / raw)
  To: linux-security-module, paul
  Cc: agruenba, hch, linux-mm, sds, linux-kernel, David Graziano

Updates shmem to use the newly created simple_xattr_initxattrs()
function to minimize code duplication with other LSM callback
functions.

Signed-off-by: David Graziano <david.graziano@rockwellcollins.com>
---
 mm/shmem.c | 53 ++++++++++++-----------------------------------------
 1 file changed, 12 insertions(+), 41 deletions(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index 971fc83..ef4bd52 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -33,6 +33,7 @@
 #include <linux/swap.h>
 #include <linux/uio.h>
 #include <linux/khugepaged.h>
+#include <linux/xattr.h>
 
 static struct vfsmount *shm_mnt;
 
@@ -2140,7 +2141,7 @@ static const struct inode_operations shmem_symlink_inode_operations;
 static const struct inode_operations shmem_short_symlink_operations;
 
 #ifdef CONFIG_TMPFS_XATTR
-static int shmem_initxattrs(struct inode *, const struct xattr *, void *);
+#define shmem_initxattrs simple_xattr_initxattrs
 #else
 #define shmem_initxattrs NULL
 #endif
@@ -2892,6 +2893,7 @@ static int
 shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
 {
 	struct inode *inode;
+	struct shmem_inode_info *info;
 	int error = -ENOSPC;
 
 	inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
@@ -2899,9 +2901,11 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
 		error = simple_acl_create(dir, inode);
 		if (error)
 			goto out_iput;
+		info = SHMEM_I(inode);
 		error = security_inode_init_security(inode, dir,
 						     &dentry->d_name,
-						     shmem_initxattrs, NULL);
+						     shmem_initxattrs,
+						     &info->xattrs);
 		if (error && error != -EOPNOTSUPP)
 			goto out_iput;
 
@@ -2921,13 +2925,16 @@ static int
 shmem_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
 	struct inode *inode;
+	struct shmem_inode_info *info;
 	int error = -ENOSPC;
 
 	inode = shmem_get_inode(dir->i_sb, dir, mode, 0, VM_NORESERVE);
 	if (inode) {
+		info = SHMEM_I(inode);
 		error = security_inode_init_security(inode, dir,
 						     NULL,
-						     shmem_initxattrs, NULL);
+						     shmem_initxattrs,
+						     &info->xattrs);
 		if (error && error != -EOPNOTSUPP)
 			goto out_iput;
 		error = simple_acl_create(dir, inode);
@@ -3119,8 +3126,9 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
 	if (!inode)
 		return -ENOSPC;
 
+	info = SHMEM_I(inode);
 	error = security_inode_init_security(inode, dir, &dentry->d_name,
-					     shmem_initxattrs, NULL);
+					     shmem_initxattrs, &info->xattrs);
 	if (error) {
 		if (error != -EOPNOTSUPP) {
 			iput(inode);
@@ -3129,7 +3137,6 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
 		error = 0;
 	}
 
-	info = SHMEM_I(inode);
 	inode->i_size = len-1;
 	if (len <= SHORT_SYMLINK_LEN) {
 		inode->i_link = kmemdup(symname, len, GFP_KERNEL);
@@ -3198,42 +3205,6 @@ static const char *shmem_get_link(struct dentry *dentry,
  * filesystem level, though.
  */
 
-/*
- * Callback for security_inode_init_security() for acquiring xattrs.
- */
-static int shmem_initxattrs(struct inode *inode,
-			    const struct xattr *xattr_array,
-			    void *fs_info)
-{
-	struct shmem_inode_info *info = SHMEM_I(inode);
-	const struct xattr *xattr;
-	struct simple_xattr *new_xattr;
-	size_t len;
-
-	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
-		new_xattr = simple_xattr_alloc(xattr->value, xattr->value_len);
-		if (!new_xattr)
-			return -ENOMEM;
-
-		len = strlen(xattr->name) + 1;
-		new_xattr->name = kmalloc(XATTR_SECURITY_PREFIX_LEN + len,
-					  GFP_KERNEL);
-		if (!new_xattr->name) {
-			kfree(new_xattr);
-			return -ENOMEM;
-		}
-
-		memcpy(new_xattr->name, XATTR_SECURITY_PREFIX,
-		       XATTR_SECURITY_PREFIX_LEN);
-		memcpy(new_xattr->name + XATTR_SECURITY_PREFIX_LEN,
-		       xattr->name, len);
-
-		simple_xattr_list_add(&info->xattrs, new_xattr);
-	}
-
-	return 0;
-}
-
 static int shmem_xattr_handler_get(const struct xattr_handler *handler,
 				   struct dentry *unused, struct inode *inode,
 				   const char *name, void *buffer, size_t size)
-- 
1.9.1

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

* [PATCH v4 3/3] mqueue: Implement generic xattr support
  2017-01-05 22:03 [PATCH v4 0/3] initxattr callback update for mqueue xattr support David Graziano
  2017-01-05 22:03 ` [PATCH v4 1/3] xattr: add simple initxattrs function David Graziano
  2017-01-05 22:03 ` [PATCH v4 2/3] shmem: use simple initxattrs callback David Graziano
@ 2017-01-05 22:03 ` David Graziano
  2 siblings, 0 replies; 6+ messages in thread
From: David Graziano @ 2017-01-05 22:03 UTC (permalink / raw)
  To: linux-security-module, paul
  Cc: agruenba, hch, linux-mm, sds, linux-kernel, David Graziano

Adds support for generic extended attributes within the POSIX message
queues filesystem and setting them by consulting the LSM. This is
needed so that the security.selinux extended attribute can be set via
a SELinux named type transition on file inodes created within the
filesystem. It allows a selinux policy to be created  for a set of
custom applications that use POSIX message queues for their IPC and
uniquely labeling them based on the application that creates the mqueue
eliminating the need for relabeling after the mqueue file is created.
The implementation is based on tmpfs/shmem and uses the newly created
simple_xattr_initxattrs() LSM callback function.

Signed-off-by: David Graziano <david.graziano@rockwellcollins.com>
---
 ipc/mqueue.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 0b13ace..32271a0 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -35,6 +35,7 @@
 #include <linux/ipc_namespace.h>
 #include <linux/user_namespace.h>
 #include <linux/slab.h>
+#include <linux/xattr.h>
 
 #include <net/sock.h>
 #include "util.h"
@@ -70,6 +71,7 @@ struct mqueue_inode_info {
 	struct rb_root msg_tree;
 	struct posix_msg_tree_node *node_cache;
 	struct mq_attr attr;
+	struct simple_xattrs xattrs;	/* list of xattrs */
 
 	struct sigevent notify;
 	struct pid *notify_owner;
@@ -254,6 +256,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
 			info->attr.mq_maxmsg = attr->mq_maxmsg;
 			info->attr.mq_msgsize = attr->mq_msgsize;
 		}
+		simple_xattrs_init(&info->xattrs);
 		/*
 		 * We used to allocate a static array of pointers and account
 		 * the size of that array as well as one msg_msg struct per
@@ -418,7 +421,8 @@ static int mqueue_create(struct inode *dir, struct dentry *dentry,
 {
 	struct inode *inode;
 	struct mq_attr *attr = dentry->d_fsdata;
-	int error;
+	struct mqueue_inode_info *info;
+	int error = 0;
 	struct ipc_namespace *ipc_ns;
 
 	spin_lock(&mq_lock);
@@ -443,6 +447,18 @@ static int mqueue_create(struct inode *dir, struct dentry *dentry,
 		ipc_ns->mq_queues_count--;
 		goto out_unlock;
 	}
+	info = MQUEUE_I(inode);
+	if (info){
+		error = security_inode_init_security(inode, dir,
+						     &dentry->d_name,
+						     simple_xattr_initxattrs,
+						     &info->xattrs);
+	}
+	if (error && error != -EOPNOTSUPP) {
+		spin_lock(&mq_lock);
+		ipc_ns->mq_queues_count--;
+		goto out_unlock;
+	}
 
 	put_ipc_ns(ipc_ns);
 	dir->i_size += DIRENT_SIZE;
-- 
1.9.1

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

* Re: [PATCH v4 1/3] xattr: add simple initxattrs function
  2017-01-05 22:03 ` [PATCH v4 1/3] xattr: add simple initxattrs function David Graziano
@ 2017-01-08  9:55   ` Christoph Hellwig
  2017-01-09 15:41     ` David Graziano
  0 siblings, 1 reply; 6+ messages in thread
From: Christoph Hellwig @ 2017-01-08  9:55 UTC (permalink / raw)
  To: David Graziano
  Cc: linux-security-module, paul, agruenba, hch, linux-mm, sds, linux-kernel

> +/*
> + * Callback for security_inode_init_security() for acquiring xattrs.
> + */
> +int simple_xattr_initxattrs(struct inode *inode,
> +			    const struct xattr *xattr_array,
> +			    void *fs_info)
> +{
> +	struct simple_xattrs *xattrs;
> +	const struct xattr *xattr;
> +	struct simple_xattr *new_xattr;
> +	size_t len;
> +
> +	if (!fs_info)
> +		return -ENOMEM;

This probablt should be an EINVAL, and also a WARN_ON_ONCE.

> +	xattrs = (struct simple_xattrs *) fs_info;

No need for the cast.  In fact we should probably just declarate it
as struct simple_xattrs *xattrs in the protoype and thus be type safe.

> +
> +	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
> +		new_xattr = simple_xattr_alloc(xattr->value, xattr->value_len);
> +		if (!new_xattr)
> +			return -ENOMEM;

We'll need to unwind the previous allocations here.

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

* Re: [PATCH v4 1/3] xattr: add simple initxattrs function
  2017-01-08  9:55   ` Christoph Hellwig
@ 2017-01-09 15:41     ` David Graziano
  0 siblings, 0 replies; 6+ messages in thread
From: David Graziano @ 2017-01-09 15:41 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-security-module, Paul Moore, agruenba, linux-mm,
	Stephen Smalley, linux-kernel

On Sun, Jan 8, 2017 at 3:55 AM, Christoph Hellwig <hch@infradead.org> wrote:
>> +/*
>> + * Callback for security_inode_init_security() for acquiring xattrs.
>> + */
>> +int simple_xattr_initxattrs(struct inode *inode,
>> +                         const struct xattr *xattr_array,
>> +                         void *fs_info)
>> +{
>> +     struct simple_xattrs *xattrs;
>> +     const struct xattr *xattr;
>> +     struct simple_xattr *new_xattr;
>> +     size_t len;
>> +
>> +     if (!fs_info)
>> +             return -ENOMEM;
>
> This probablt should be an EINVAL, and also a WARN_ON_ONCE.

I will change the return value to -EINVAL and add the WARN_ON_ONCE.
In the next version of the patchset.

>
>> +     xattrs = (struct simple_xattrs *) fs_info;
>
> No need for the cast.  In fact we should probably just declarate it
> as struct simple_xattrs *xattrs in the protoype and thus be type safe.

I don't think the prototype can be changed to "struct simple_xattrs" as the
security_inode_init_security() function in security/security.c which calls
this is asumming an initxattrs function with following prototype
int (*initxattrs)  (struct inode *inode, const struct xattr
*xattr_array, void *fs_data)

>
>> +
>> +     for (xattr = xattr_array; xattr->name != NULL; xattr++) {
>> +             new_xattr = simple_xattr_alloc(xattr->value, xattr->value_len);
>> +             if (!new_xattr)
>> +                     return -ENOMEM;
>
> We'll need to unwind the previous allocations here.

This patchset essentially relocates the shmem_initxattrs() function from
mm/shmem.c and uses the relocated function for both tmpfs and mqueuefs.
That inital function didn't attempt to unwind the previous allocations. If the
consensus is to unwind any allocations made by this function I can look
at adding it.

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

end of thread, other threads:[~2017-01-09 15:41 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-05 22:03 [PATCH v4 0/3] initxattr callback update for mqueue xattr support David Graziano
2017-01-05 22:03 ` [PATCH v4 1/3] xattr: add simple initxattrs function David Graziano
2017-01-08  9:55   ` Christoph Hellwig
2017-01-09 15:41     ` David Graziano
2017-01-05 22:03 ` [PATCH v4 2/3] shmem: use simple initxattrs callback David Graziano
2017-01-05 22:03 ` [PATCH v4 3/3] mqueue: Implement generic xattr support David Graziano

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