fs/9p: xattr: add trusted and security namespaces

Allow requests for security.* and trusted.* xattr name spaces
to pass through to server.

The new files are 99% cut and paste from fs/9p/xattr_user.c with the
namespaces changed.  It has the intended effect in superficial testing.
I do not know much detail about how these namespaces are used, but passing
them through to the server, which can decide whether to handle them or not,
seems reasonable.

I want to support a use case where an ext4 file system is mounted via 9P,
then re-exported via samba to windows clients in a cluster.  Windows wants
to store xattrs such as security.NTACL.  This works when ext4 directly
backs samba, but not when 9P is inserted.  This use case is documented here:
   http://code.google.com/p/diod/issues/detail?id=95

Signed-off-by: Jim Garlick <garlick@llnl.gov>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
This commit is contained in:
Jim Garlick 2013-05-29 12:09:39 -07:00 committed by Eric Van Hensbergen
parent 2f28c8b31d
commit d9a738597f
6 changed files with 182 additions and 1 deletions

View File

@ -31,3 +31,16 @@ config 9P_FS_POSIX_ACL
If you don't know what Access Control Lists are, say N
endif
config 9P_FS_SECURITY
bool "9P Security Labels"
depends on 9P_FS
help
Security labels support alternative access control models
implemented by security modules like SELinux. This option
enables an extended attribute handler for file security
labels in the 9P filesystem.
If you are not using a security module that requires using
extended attributes for file security labels, say N.

View File

@ -11,7 +11,9 @@ obj-$(CONFIG_9P_FS) := 9p.o
v9fs.o \
fid.o \
xattr.o \
xattr_user.o
xattr_user.o \
xattr_trusted.o
9p-$(CONFIG_9P_FSCACHE) += cache.o
9p-$(CONFIG_9P_FS_POSIX_ACL) += acl.o
9p-$(CONFIG_9P_FS_SECURITY) += xattr_security.o

View File

@ -167,9 +167,13 @@ ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
const struct xattr_handler *v9fs_xattr_handlers[] = {
&v9fs_xattr_user_handler,
&v9fs_xattr_trusted_handler,
#ifdef CONFIG_9P_FS_POSIX_ACL
&v9fs_xattr_acl_access_handler,
&v9fs_xattr_acl_default_handler,
#endif
#ifdef CONFIG_9P_FS_SECURITY
&v9fs_xattr_security_handler,
#endif
NULL
};

View File

@ -20,6 +20,8 @@
extern const struct xattr_handler *v9fs_xattr_handlers[];
extern struct xattr_handler v9fs_xattr_user_handler;
extern struct xattr_handler v9fs_xattr_trusted_handler;
extern struct xattr_handler v9fs_xattr_security_handler;
extern const struct xattr_handler v9fs_xattr_acl_access_handler;
extern const struct xattr_handler v9fs_xattr_acl_default_handler;

80
fs/9p/xattr_security.c Normal file
View File

@ -0,0 +1,80 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include "xattr.h"
static int v9fs_xattr_security_get(struct dentry *dentry, const char *name,
void *buffer, size_t size, int type)
{
int retval;
char *full_name;
size_t name_len;
size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;
if (name == NULL)
return -EINVAL;
if (strcmp(name, "") == 0)
return -EINVAL;
name_len = strlen(name);
full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
if (!full_name)
return -ENOMEM;
memcpy(full_name, XATTR_SECURITY_PREFIX, prefix_len);
memcpy(full_name+prefix_len, name, name_len);
full_name[prefix_len + name_len] = '\0';
retval = v9fs_xattr_get(dentry, full_name, buffer, size);
kfree(full_name);
return retval;
}
static int v9fs_xattr_security_set(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags, int type)
{
int retval;
char *full_name;
size_t name_len;
size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;
if (name == NULL)
return -EINVAL;
if (strcmp(name, "") == 0)
return -EINVAL;
name_len = strlen(name);
full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
if (!full_name)
return -ENOMEM;
memcpy(full_name, XATTR_SECURITY_PREFIX, prefix_len);
memcpy(full_name + prefix_len, name, name_len);
full_name[prefix_len + name_len] = '\0';
retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
kfree(full_name);
return retval;
}
struct xattr_handler v9fs_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX,
.get = v9fs_xattr_security_get,
.set = v9fs_xattr_security_set,
};

80
fs/9p/xattr_trusted.c Normal file
View File

@ -0,0 +1,80 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include "xattr.h"
static int v9fs_xattr_trusted_get(struct dentry *dentry, const char *name,
void *buffer, size_t size, int type)
{
int retval;
char *full_name;
size_t name_len;
size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;
if (name == NULL)
return -EINVAL;
if (strcmp(name, "") == 0)
return -EINVAL;
name_len = strlen(name);
full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
if (!full_name)
return -ENOMEM;
memcpy(full_name, XATTR_TRUSTED_PREFIX, prefix_len);
memcpy(full_name+prefix_len, name, name_len);
full_name[prefix_len + name_len] = '\0';
retval = v9fs_xattr_get(dentry, full_name, buffer, size);
kfree(full_name);
return retval;
}
static int v9fs_xattr_trusted_set(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags, int type)
{
int retval;
char *full_name;
size_t name_len;
size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;
if (name == NULL)
return -EINVAL;
if (strcmp(name, "") == 0)
return -EINVAL;
name_len = strlen(name);
full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
if (!full_name)
return -ENOMEM;
memcpy(full_name, XATTR_TRUSTED_PREFIX, prefix_len);
memcpy(full_name + prefix_len, name, name_len);
full_name[prefix_len + name_len] = '\0';
retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
kfree(full_name);
return retval;
}
struct xattr_handler v9fs_xattr_trusted_handler = {
.prefix = XATTR_TRUSTED_PREFIX,
.get = v9fs_xattr_trusted_get,
.set = v9fs_xattr_trusted_set,
};