Messages in this thread Patch in this message | | | Date | Mon, 23 Aug 2004 14:20:58 -0400 (EDT) | From | James Morris <> | Subject | [PATCH][6/7] add xattr support to tmpfs |
| |
This patch adds xattr support to tmpfs, and a security xattr handler. Original patch from: Luke Kenneth Casson Leighton <lkcl@lkcl.net>
fs/Kconfig | 22 +++++++++++ mm/Makefile | 2 + mm/shmem.c | 57 +++++++++++++++++++++++++++--- mm/shmem_xattr.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++ mm/shmem_xattr.h | 39 ++++++++++++++++++++ mm/shmem_xattr_security.c | 43 +++++++++++++++++++++++ 6 files changed, 243 insertions(+), 6 deletions(-)
Signed-off-by: James Morris <jmorris@redhat.com> Signed-off-by: Stephen Smalley <sds@epoch.ncsc.mil> diff -purN -X dontdiff linux-2.6.8.1-mm2.p/fs/Kconfig linux-2.6.8.1-mm2.w/fs/Kconfig --- linux-2.6.8.1-mm2.p/fs/Kconfig 2004-08-19 10:32:52.000000000 -0400 +++ linux-2.6.8.1-mm2.w/fs/Kconfig 2004-08-23 01:28:04.582841048 -0400 @@ -918,6 +918,28 @@ config TMPFS See <file:Documentation/filesystems/tmpfs.txt> for details. +config TMPFS_XATTR + bool "tmpfs Extended Attributes" + depends on TMPFS + help + Extended attributes are name:value pairs associated with inodes by + the kernel or by users (see the attr(5) manual page, or visit + <http://acl.bestbits.at/> for details). + + If unsure, say N. + +config TMPFS_SECURITY + bool "tmpfs Security Labels" + depends on TMPFS_XATTR + 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 tmpfs filesystem. + + If you are not using a security module that requires using + extended attributes for file security labels, say N. + config HUGETLBFS bool "HugeTLB file system support" depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || X86_64 || BROKEN diff -purN -X dontdiff linux-2.6.8.1-mm2.p/mm/Makefile linux-2.6.8.1-mm2.w/mm/Makefile --- linux-2.6.8.1-mm2.p/mm/Makefile 2004-08-19 10:32:55.000000000 -0400 +++ linux-2.6.8.1-mm2.w/mm/Makefile 2004-08-23 01:28:04.583840896 -0400 @@ -15,3 +15,5 @@ obj-y := bootmem.o filemap.o mempool.o obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o obj-$(CONFIG_HUGETLBFS) += hugetlb.o obj-$(CONFIG_NUMA) += mempolicy.o +obj-$(CONFIG_TMPFS_XATTR) += shmem_xattr.o +obj-$(CONFIG_TMPFS_SECURITY) += shmem_xattr_security.o diff -purN -X dontdiff linux-2.6.8.1-mm2.p/mm/shmem.c linux-2.6.8.1-mm2.w/mm/shmem.c --- linux-2.6.8.1-mm2.p/mm/shmem.c 2004-08-19 10:32:55.000000000 -0400 +++ linux-2.6.8.1-mm2.w/mm/shmem.c 2004-08-23 01:28:04.585840592 -0400 @@ -10,6 +10,10 @@ * Copyright (C) 2002-2003 VERITAS Software Corporation. * Copyright (C) 2004 Andi Kleen, SuSE Labs * + * Extended attribute support for tmpfs: + * Copyright (c) 2004, Luke Kenneth Casson Leighton <lkcl@lkcl.net> + * Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com> + * * This file is released under the GPL. */ @@ -45,6 +49,8 @@ #include <asm/div64.h> #include <asm/pgtable.h> +#include "shmem_xattr.h" + /* This magic number is used in glibc for posix shared memory */ #define TMPFS_MAGIC 0x01021994 @@ -171,6 +177,7 @@ static struct address_space_operations s static struct file_operations shmem_file_operations; static struct inode_operations shmem_inode_operations; static struct inode_operations shmem_dir_inode_operations; +static struct inode_operations shmem_special_inode_operations; static struct vm_operations_struct shmem_vm_ops; static struct backing_dev_info shmem_backing_dev_info = { @@ -1211,6 +1218,7 @@ shmem_get_inode(struct super_block *sb, mpol_shared_policy_init(&info->policy); switch (mode & S_IFMT) { default: + inode->i_op = &shmem_special_inode_operations; init_special_inode(inode, mode, dev); break; case S_IFREG: @@ -1708,6 +1716,12 @@ static void shmem_put_link(struct dentry static struct inode_operations shmem_symlink_inline_operations = { .readlink = generic_readlink, .follow_link = shmem_follow_link_inline, +#ifdef CONFIG_TMPFS + .setxattr = shmem_setxattr, + .getxattr = shmem_getxattr, + .listxattr = shmem_listxattr, + .removexattr = shmem_removexattr, +#endif }; static struct inode_operations shmem_symlink_inode_operations = { @@ -1715,6 +1729,12 @@ static struct inode_operations shmem_sym .readlink = generic_readlink, .follow_link = shmem_follow_link, .put_link = shmem_put_link, +#ifdef CONFIG_TMPFS + .setxattr = shmem_setxattr, + .getxattr = shmem_getxattr, + .listxattr = shmem_listxattr, + .removexattr = shmem_removexattr, +#endif }; static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, unsigned long *blocks, unsigned long *inodes) @@ -1933,6 +1953,12 @@ static struct file_operations shmem_file static struct inode_operations shmem_inode_operations = { .truncate = shmem_truncate, .setattr = shmem_notify_change, +#ifdef CONFIG_TMPFS + .setxattr = shmem_setxattr, + .getxattr = shmem_getxattr, + .listxattr = shmem_listxattr, + .removexattr = shmem_removexattr, +#endif }; static struct inode_operations shmem_dir_inode_operations = { @@ -1946,6 +1972,19 @@ static struct inode_operations shmem_dir .rmdir = shmem_rmdir, .mknod = shmem_mknod, .rename = shmem_rename, + .setxattr = shmem_setxattr, + .getxattr = shmem_getxattr, + .listxattr = shmem_listxattr, + .removexattr = shmem_removexattr, +#endif +}; + +static struct inode_operations shmem_special_inode_operations = { +#ifdef CONFIG_TMPFS + .setxattr = shmem_setxattr, + .getxattr = shmem_getxattr, + .listxattr = shmem_listxattr, + .removexattr = shmem_removexattr, #endif }; @@ -1990,12 +2029,16 @@ static int __init init_tmpfs(void) error = init_inodecache(); if (error) - goto out3; + goto out_error; + + error = init_shmem_xattr(); + if (error) + goto out_destroy_inodecache; error = register_filesystem(&tmpfs_fs_type); if (error) { printk(KERN_ERR "Could not register tmpfs\n"); - goto out2; + goto out_exit_shmem_xattr; } #ifdef CONFIG_TMPFS devfs_mk_dir("shm"); @@ -2004,18 +2047,20 @@ static int __init init_tmpfs(void) if (IS_ERR(shm_mnt)) { error = PTR_ERR(shm_mnt); printk(KERN_ERR "Could not kern_mount tmpfs\n"); - goto out1; + goto out_unregister; } /* The internal instance should not do size checking */ shmem_set_size(SHMEM_SB(shm_mnt->mnt_sb), ULONG_MAX, ULONG_MAX); return 0; -out1: +out_unregister: unregister_filesystem(&tmpfs_fs_type); -out2: +out_exit_shmem_xattr: + exit_shmem_xattr(); +out_destroy_inodecache: destroy_inodecache(); -out3: +out_error: shm_mnt = ERR_PTR(error); return error; } diff -purN -X dontdiff linux-2.6.8.1-mm2.p/mm/shmem_xattr.c linux-2.6.8.1-mm2.w/mm/shmem_xattr.c --- linux-2.6.8.1-mm2.p/mm/shmem_xattr.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.6.8.1-mm2.w/mm/shmem_xattr.c 2004-08-23 01:28:54.336277376 -0400 @@ -0,0 +1,86 @@ +/* + * Pseudo xattr support for tmpfs. + * + * Based on fs/devpts/xattr.c by Stephen Smalley <sds@epoch.ncsc.mil> + * + * Copyright (c) 2004, Luke Kenneth Casson Leighton <lkcl@lkcl.net> + * Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ +#include <linux/init.h> +#include <linux/fs.h> +#include "shmem_xattr.h" + +static struct simple_xattr_handler *shmem_xattr_handlers[SIMPLE_XATTR_MAX]; +static struct simple_xattr_info shmem_xattr_info; + +ssize_t shmem_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size) +{ + struct simple_xattr_handler *handler; + struct inode *inode = dentry->d_inode; + + handler = simple_xattr_resolve_name(&shmem_xattr_info, &name); + if (!handler) + return -EOPNOTSUPP; + return handler->get(inode, name, buffer, size); +} + +ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size) +{ + return simple_xattr_list(&shmem_xattr_info, dentry, buffer, size); +} + +int shmem_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) +{ + struct simple_xattr_handler *handler; + struct inode *inode = dentry->d_inode; + + if (size == 0) + value = ""; /* empty EA, do not remove */ + handler = simple_xattr_resolve_name(&shmem_xattr_info, &name); + if (!handler) + return -EOPNOTSUPP; + return handler->set(inode, name, value, size, flags); +} + +int shmem_removexattr(struct dentry *dentry, const char *name) +{ + struct simple_xattr_handler *handler; + struct inode *inode = dentry->d_inode; + + handler = simple_xattr_resolve_name(&shmem_xattr_info, &name); + if (!handler) + return -EOPNOTSUPP; + return handler->set(inode, name, NULL, 0, XATTR_REPLACE); +} + +int __init init_shmem_xattr(void) +{ +#ifdef CONFIG_TMPFS_SECURITY + int err; + + shmem_xattr_info.lock = RW_LOCK_UNLOCKED; + shmem_xattr_info.handlers = shmem_xattr_handlers; + + err = simple_xattr_register(&shmem_xattr_info, + SHMEM_XATTR_INDEX_SECURITY, + &shmem_xattr_security_handler); + if (err) + return err; +#endif + return 0; +} + +void exit_shmem_xattr(void) +{ +#ifdef CONFIG_TMPFS_SECURITY + simple_xattr_unregister(&shmem_xattr_info, + SHMEM_XATTR_INDEX_SECURITY, + &shmem_xattr_security_handler); +#endif + +} diff -purN -X dontdiff linux-2.6.8.1-mm2.p/mm/shmem_xattr.h linux-2.6.8.1-mm2.w/mm/shmem_xattr.h --- linux-2.6.8.1-mm2.p/mm/shmem_xattr.h 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.6.8.1-mm2.w/mm/shmem_xattr.h 2004-08-23 01:28:04.587840288 -0400 @@ -0,0 +1,39 @@ +/* + * Pseudo xattr support for tmpfs. + */ +#include <linux/config.h> +#include <linux/xattr.h> + +/* Name indexes */ +#define SHMEM_XATTR_INDEX_SECURITY 1 + +#ifdef CONFIG_TMPFS_XATTR + +int shmem_setxattr(struct dentry *, const char *, const void *, size_t, int); +ssize_t shmem_getxattr(struct dentry *, const char *, void *, size_t); +ssize_t shmem_listxattr(struct dentry *, char *, size_t); +int shmem_removexattr(struct dentry *, const char *); + +int init_shmem_xattr(void); +void exit_shmem_xattr(void); + +#else /* !CONFIG_TMPFS_XATTR */ + +#define shmem_setxattr NULL +#define shmem_getxattr NULL +#define shmem_listxattr NULL +#define shmem_removexattr NULL + +static inline int init_shmem_xattr(void) +{ + return 0; +} + +static inline void exit_shmem_xattr(void) +{ +} + +#endif /* CONFIG_TMPFS_XATTR */ + +extern struct simple_xattr_handler shmem_xattr_security_handler; + diff -purN -X dontdiff linux-2.6.8.1-mm2.p/mm/shmem_xattr_security.c linux-2.6.8.1-mm2.w/mm/shmem_xattr_security.c --- linux-2.6.8.1-mm2.p/mm/shmem_xattr_security.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.6.8.1-mm2.w/mm/shmem_xattr_security.c 2004-08-23 01:28:50.042930064 -0400 @@ -0,0 +1,43 @@ +/* + * Security xattr support for tmpfs. + * + * Based on fs/devpts/xattr_security.c by Stephen Smalley <sds@epoch.ncsc.mil> + * + * Copyright (c) 2004, Luke Kenneth Casson Leighton <lkcl@lkcl.net> + * Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/security.h> +#include "shmem_xattr.h" + +static size_t shmem_xattr_security_list(struct inode *inode, char *list, const char *name, int name_len) +{ + return security_inode_listsecurity(inode, list); +} + +static int shmem_xattr_security_get(struct inode *inode, const char *name, void *buffer, size_t size) +{ + if (strcmp(name, "") == 0) + return -EINVAL; + return security_inode_getsecurity(inode, name, buffer, size); +} + +static int shmem_xattr_security_set(struct inode *inode, const char *name, const void *value, size_t size, int flags) +{ + if (strcmp(name, "") == 0) + return -EINVAL; + return security_inode_setsecurity(inode, name, value, size, flags); +} + +struct simple_xattr_handler shmem_xattr_security_handler = { + .prefix = XATTR_SECURITY_PREFIX, + .list = shmem_xattr_security_list, + .get = shmem_xattr_security_get, + .set = shmem_xattr_security_set, +}; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |