diff options
-rw-r--r-- | ima-allow-it-to-be-completely-disabled-and-default-off.patch | 145 | ||||
-rw-r--r-- | kernel.spec | 14 | ||||
-rw-r--r-- | tmpfs-implement-generic-xattr-support.patch | 557 |
3 files changed, 567 insertions, 149 deletions
diff --git a/ima-allow-it-to-be-completely-disabled-and-default-off.patch b/ima-allow-it-to-be-completely-disabled-and-default-off.patch deleted file mode 100644 index 4f8f1f180..000000000 --- a/ima-allow-it-to-be-completely-disabled-and-default-off.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 785465d9cffd65b5a69dd2f465d2f7c917713220 Mon Sep 17 00:00:00 2001 -From: Kyle McMartin <kyle@mcmartin.ca> -Date: Mon, 18 Oct 2010 13:30:39 -0400 -Subject: [PATCH] ima: provide a toggle to disable it entirely - -Signed-off-by: Kyle McMartin <kyle@redhat.com> ---- - security/integrity/ima/ima.h | 1 + - security/integrity/ima/ima_iint.c | 9 +++++++++ - security/integrity/ima/ima_main.c | 24 +++++++++++++++++++++--- - 3 files changed, 31 insertions(+), 3 deletions(-) - -diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h -index 3fbcd1d..65c3977 100644 ---- a/security/integrity/ima/ima.h -+++ b/security/integrity/ima/ima.h -@@ -37,6 +37,7 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; - /* set during initialization */ - extern int iint_initialized; - extern int ima_initialized; -+extern int ima_enabled; - extern int ima_used_chip; - extern char *ima_hash; - -diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c -index afba4ae..3d191ef 100644 ---- a/security/integrity/ima/ima_iint.c -+++ b/security/integrity/ima/ima_iint.c -@@ -54,6 +54,9 @@ int ima_inode_alloc(struct inode *inode) - struct ima_iint_cache *iint = NULL; - int rc = 0; - -+ if (!ima_enabled) -+ return 0; -+ - iint = kmem_cache_alloc(iint_cache, GFP_NOFS); - if (!iint) - return -ENOMEM; -@@ -116,6 +119,9 @@ void ima_inode_free(struct inode *inode) - { - struct ima_iint_cache *iint; - -+ if (!ima_enabled) -+ return; -+ - spin_lock(&ima_iint_lock); - iint = radix_tree_delete(&ima_iint_store, (unsigned long)inode); - spin_unlock(&ima_iint_lock); -@@ -139,6 +145,9 @@ static void init_once(void *foo) - - static int __init ima_iintcache_init(void) - { -+ if (!ima_enabled) -+ return 0; -+ - iint_cache = - kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0, - SLAB_PANIC, init_once); -diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c -index e662b89..6e91905 100644 ---- a/security/integrity/ima/ima_main.c -+++ b/security/integrity/ima/ima_main.c -@@ -26,6 +26,7 @@ - #include "ima.h" - - int ima_initialized; -+int ima_enabled; - - char *ima_hash = "sha1"; - static int __init hash_setup(char *str) -@@ -36,6 +37,14 @@ static int __init hash_setup(char *str) - } - __setup("ima_hash=", hash_setup); - -+static int __init ima_enable(char *str) -+{ -+ if (strncmp(str, "on", 2) == 0) -+ ima_enabled = 1; -+ return 1; -+} -+__setup("ima=", ima_enable); -+ - struct ima_imbalance { - struct hlist_node node; - unsigned long fsmagic; -@@ -148,7 +157,7 @@ void ima_counts_get(struct file *file) - struct ima_iint_cache *iint; - int rc; - -- if (!iint_initialized || !S_ISREG(inode->i_mode)) -+ if (!ima_enabled || !iint_initialized || !S_ISREG(inode->i_mode)) - return; - iint = ima_iint_find_get(inode); - if (!iint) -@@ -215,7 +224,7 @@ void ima_file_free(struct file *file) - struct inode *inode = file->f_dentry->d_inode; - struct ima_iint_cache *iint; - -- if (!iint_initialized || !S_ISREG(inode->i_mode)) -+ if (!ima_enabled || !iint_initialized || !S_ISREG(inode->i_mode)) - return; - iint = ima_iint_find_get(inode); - if (!iint) -@@ -269,7 +278,7 @@ int ima_file_mmap(struct file *file, unsigned long prot) - { - int rc; - -- if (!file) -+ if (!ima_enabled || !file) - return 0; - if (prot & PROT_EXEC) - rc = process_measurement(file, file->f_dentry->d_name.name, -@@ -294,6 +303,9 @@ int ima_bprm_check(struct linux_binprm *bprm) - { - int rc; - -+ if (!ima_enabled) -+ return 0; -+ - rc = process_measurement(bprm->file, bprm->filename, - MAY_EXEC, BPRM_CHECK); - return 0; -@@ -313,6 +325,9 @@ int ima_file_check(struct file *file, int mask) - { - int rc; - -+ if (!ima_enabled) -+ return 0; -+ - rc = process_measurement(file, file->f_dentry->d_name.name, - mask & (MAY_READ | MAY_WRITE | MAY_EXEC), - FILE_CHECK); -@@ -324,6 +339,9 @@ static int __init init_ima(void) - { - int error; - -+ if (!ima_enabled) -+ return 0; -+ - error = ima_init(); - ima_initialized = 1; - return error; --- -1.7.3.1 - diff --git a/kernel.spec b/kernel.spec index fad464436..7a84f4e1c 100644 --- a/kernel.spec +++ b/kernel.spec @@ -619,6 +619,8 @@ Patch150: linux-2.6.29-sparc-IOC_TYPECHECK.patch Patch160: linux-2.6-32bit-mmap-exec-randomization.patch Patch161: linux-2.6-i386-nx-emulation.patch +Patch170: tmpfs-implement-generic-xattr-support.patch + Patch200: linux-2.6-debug-sizeof-structs.patch Patch202: linux-2.6-debug-taint-vm.patch Patch203: linux-2.6-debug-vm-would-have-oomkilled.patch @@ -628,8 +630,6 @@ Patch380: linux-2.6-defaults-pci_no_msi.patch Patch381: linux-2.6-defaults-pci_use_crs.patch Patch383: linux-2.6-defaults-aspm.patch -Patch385: ima-allow-it-to-be-completely-disabled-and-default-off.patch - Patch390: linux-2.6-defaults-acpi-video.patch Patch391: linux-2.6-acpi-video-dos.patch Patch393: acpi-ec-add-delay-before-write.patch @@ -1181,6 +1181,7 @@ ApplyPatch linux-2.6-32bit-mmap-exec-randomization.patch # # bugfixes to drivers and filesystems # +ApplyPatch tmpfs-implement-generic-xattr-support.patch # ext4 @@ -1218,8 +1219,6 @@ ApplyPatch linux-2.6-defaults-pci_use_crs.patch # enable ASPM by default on hardware we expect to work ApplyPatch linux-2.6-defaults-aspm.patch -#ApplyPatch ima-allow-it-to-be-completely-disabled-and-default-off.patch - # # SCSI Bits. # @@ -1937,6 +1936,13 @@ fi # and build. %changelog +* Sat May 14 2011 Kyle McMartin <kmcmartin@redhat.com> 2.6.39-0.rc7.git6.1 +- tmpfs: implement generic xattr support + Merge Eric Paris' patch to add xattr support to tmpfs, so that it can be + used to host mockroots for mass rebuilds. +- Drop IMA disabling patch, which is no longer necessary since it's run time + (but unused) cost is now minimized. + * Sat May 14 2011 Kyle McMartin <kmcmartin@redhat.com> 2.6.39-0.rc7.git6.0 - Update to 2.6.39-rc7-git6 diff --git a/tmpfs-implement-generic-xattr-support.patch b/tmpfs-implement-generic-xattr-support.patch new file mode 100644 index 000000000..9ca97d1c7 --- /dev/null +++ b/tmpfs-implement-generic-xattr-support.patch @@ -0,0 +1,557 @@ +From linux-fsdevel-owner@vger.kernel.org Fri May 13 07:16:45 2011 +From: Miklos Szeredi <miklos@szeredi.hu> +To: Andrew Morton <akpm@linux-foundation.org>, + Hugh Dickins <hughd@google.com> +Subject: [PATCH v2] tmpfs: implement generic xattr support +CC: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, + Michal Suchanek <hramrach@centrum.cz>, + Serge Hallyn <serge.hallyn@ubuntu.com>, + Eric Paris <eparis@redhat.com>, + James Morris <jmorris@namei.org>, + Christoph Hellwig <hch@infradead.org> +Date: Fri, 13 May 2011 13:16:35 +0200 +Message-ID: <871v02lujw.fsf@tucsk.pomaz.szeredi.hu> +X-Mailing-List: linux-fsdevel@vger.kernel.org + +[This update addresses comments from Hugh and Andrew] + + +From: Eric Paris <eparis@redhat.com> + +This patch implements generic xattrs for tmpfs filesystems. The feodra +project, while trying to replace suid apps with file capabilities, +realized that tmpfs, which is used on the build systems, does not +support file capabilities and thus cannot be used to build packages +which use file capabilities. Xattrs are also needed for overlayfs. + +The xattr interface is a bit, odd. If a filesystem does not implement any +{get,set,list}xattr functions the VFS will call into some random LSM hooks and +the running LSM can then implement some method for handling xattrs. SELinux +for example provides a method to support security.selinux but no other +security.* xattrs. + +As it stands today when one enables CONFIG_TMPFS_POSIX_ACL tmpfs will have +xattr handler routines specifically to handle acls. Because of this tmpfs +would loose the VFS/LSM helpers to support the running LSM. To make up for +that tmpfs had stub functions that did nothing but call into the LSM hooks +which implement the helpers. + +This new patch does not use the LSM fallback functions and instead +just implements a native get/set/list xattr feature for the full +security.* and trusted.* namespace like a normal filesystem. This +means that tmpfs can now support both security.selinux and +security.capability, which was not previously possible. + +The basic implementation is that I attach a: + +struct shmem_xattr { + struct list_head list; /* anchored by shmem_inode_info->xattr_list */ + char *name; + size_t size; + char value[0]; +}; + +Into the struct shmem_inode_info for each xattr that is set. This +implementation could easily support the user.* namespace as well, +except some care needs to be taken to prevent large amounts of +unswappable memory being allocated for unprivileged users. + +[miklos: new config option, suport trusted.*, support symlinks] + +Signed-off-by: Eric Paris <eparis@redhat.com> +Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> +Acked-by: Serge Hallyn <serge.hallyn@ubuntu.com> +--- + fs/Kconfig | 18 ++ + include/linux/shmem_fs.h | 8 + + mm/shmem.c | 320 +++++++++++++++++++++++++++++++++++++++-------- + 3 files changed, 290 insertions(+), 56 deletions(-) + +Index: linux-2.6/fs/Kconfig +=================================================================== +--- linux-2.6.orig/fs/Kconfig 2011-05-13 12:26:31.000000000 +0200 ++++ linux-2.6/fs/Kconfig 2011-05-13 12:29:34.000000000 +0200 +@@ -121,9 +121,25 @@ config TMPFS + + See <file:Documentation/filesystems/tmpfs.txt> for details. + ++config TMPFS_XATTR ++ bool "Tmpfs extended attributes" ++ depends on TMPFS ++ default n ++ 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). ++ ++ Currently this enables support for the trusted.* and ++ security.* namespaces. ++ ++ If unsure, say N. ++ ++ You need this for POSIX ACL support on tmpfs. ++ + config TMPFS_POSIX_ACL + bool "Tmpfs POSIX Access Control Lists" +- depends on TMPFS ++ depends on TMPFS_XATTR + select GENERIC_ACL + help + POSIX Access Control Lists (ACLs) support permissions for users and +Index: linux-2.6/include/linux/shmem_fs.h +=================================================================== +--- linux-2.6.orig/include/linux/shmem_fs.h 2011-05-13 12:26:31.000000000 +0200 ++++ linux-2.6/include/linux/shmem_fs.h 2011-05-13 12:35:36.000000000 +0200 +@@ -9,6 +9,8 @@ + + #define SHMEM_NR_DIRECT 16 + ++#define SHMEM_SYMLINK_INLINE_LEN (SHMEM_NR_DIRECT * sizeof(swp_entry_t)) ++ + struct shmem_inode_info { + spinlock_t lock; + unsigned long flags; +@@ -17,8 +19,12 @@ struct shmem_inode_info { + unsigned long next_index; /* highest alloced index + 1 */ + struct shared_policy policy; /* NUMA memory alloc policy */ + struct page *i_indirect; /* top indirect blocks page */ +- swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* first blocks */ ++ union { ++ swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* first blocks */ ++ char inline_symlink[SHMEM_SYMLINK_INLINE_LEN]; ++ }; + struct list_head swaplist; /* chain of maybes on swap */ ++ struct list_head xattr_list; /* list of shmem_xattr */ + struct inode vfs_inode; + }; + +Index: linux-2.6/mm/shmem.c +=================================================================== +--- linux-2.6.orig/mm/shmem.c 2011-05-13 12:26:31.000000000 +0200 ++++ linux-2.6/mm/shmem.c 2011-05-13 12:36:08.000000000 +0200 +@@ -99,6 +99,13 @@ static struct vfsmount *shm_mnt; + /* Pretend that each entry is of this size in directory's i_size */ + #define BOGO_DIRENT_SIZE 20 + ++struct shmem_xattr { ++ struct list_head list; /* anchored by shmem_inode_info->xattr_list */ ++ char *name; /* xattr name */ ++ size_t size; ++ char value[0]; ++}; ++ + /* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */ + enum sgp_type { + SGP_READ, /* don't exceed i_size, don't allocate page */ +@@ -822,6 +829,7 @@ static int shmem_notify_change(struct de + static void shmem_evict_inode(struct inode *inode) + { + struct shmem_inode_info *info = SHMEM_I(inode); ++ struct shmem_xattr *xattr, *nxattr; + + if (inode->i_mapping->a_ops == &shmem_aops) { + truncate_inode_pages(inode->i_mapping, 0); +@@ -834,6 +842,11 @@ static void shmem_evict_inode(struct ino + mutex_unlock(&shmem_swaplist_mutex); + } + } ++ ++ list_for_each_entry_safe(xattr, nxattr, &info->xattr_list, list) { ++ kfree(xattr->name); ++ kfree(xattr); ++ } + BUG_ON(inode->i_blocks); + shmem_free_inode(inode->i_sb); + end_writeback(inode); +@@ -1616,6 +1629,7 @@ static struct inode *shmem_get_inode(str + spin_lock_init(&info->lock); + info->flags = flags & VM_NORESERVE; + INIT_LIST_HEAD(&info->swaplist); ++ INIT_LIST_HEAD(&info->xattr_list); + cache_no_acl(inode); + + switch (mode & S_IFMT) { +@@ -2015,9 +2029,9 @@ static int shmem_symlink(struct inode *d + + info = SHMEM_I(inode); + inode->i_size = len-1; +- if (len <= (char *)inode - (char *)info) { ++ if (len <= SHMEM_SYMLINK_INLINE_LEN) { + /* do it inline */ +- memcpy(info, symname, len); ++ memcpy(info->inline_symlink, symname, len); + inode->i_op = &shmem_symlink_inline_operations; + } else { + error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL); +@@ -2043,7 +2057,7 @@ static int shmem_symlink(struct inode *d + + static void *shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd) + { +- nd_set_link(nd, (char *)SHMEM_I(dentry->d_inode)); ++ nd_set_link(nd, SHMEM_I(dentry->d_inode)->inline_symlink); + return NULL; + } + +@@ -2067,63 +2081,253 @@ static void shmem_put_link(struct dentry + } + } + +-static const struct inode_operations shmem_symlink_inline_operations = { +- .readlink = generic_readlink, +- .follow_link = shmem_follow_link_inline, +-}; +- +-static const struct inode_operations shmem_symlink_inode_operations = { +- .readlink = generic_readlink, +- .follow_link = shmem_follow_link, +- .put_link = shmem_put_link, +-}; +- +-#ifdef CONFIG_TMPFS_POSIX_ACL ++#ifdef CONFIG_TMPFS_XATTR + /* +- * Superblocks without xattr inode operations will get security.* xattr +- * support from the VFS "for free". As soon as we have any other xattrs ++ * Superblocks without xattr inode operations may get some security.* xattr ++ * support from the LSM "for free". As soon as we have any other xattrs + * like ACLs, we also need to implement the security.* handlers at + * filesystem level, though. + */ + +-static size_t shmem_xattr_security_list(struct dentry *dentry, char *list, +- size_t list_len, const char *name, +- size_t name_len, int handler_flags) ++static int shmem_xattr_get(struct dentry *dentry, const char *name, ++ void *buffer, size_t size) + { +- return security_inode_listsecurity(dentry->d_inode, list, list_len); +-} ++ struct shmem_inode_info *info; ++ struct shmem_xattr *xattr; ++ int ret = -ENODATA; + +-static int shmem_xattr_security_get(struct dentry *dentry, const char *name, +- void *buffer, size_t size, int handler_flags) +-{ +- if (strcmp(name, "") == 0) +- return -EINVAL; +- return xattr_getsecurity(dentry->d_inode, name, buffer, size); ++ info = SHMEM_I(dentry->d_inode); ++ ++ spin_lock(&info->lock); ++ list_for_each_entry(xattr, &info->xattr_list, list) { ++ if (strcmp(name, xattr->name)) ++ continue; ++ ++ ret = xattr->size; ++ if (buffer) { ++ if (size < xattr->size) ++ ret = -ERANGE; ++ else ++ memcpy(buffer, xattr->value, xattr->size); ++ } ++ break; ++ } ++ spin_unlock(&info->lock); ++ return ret; + } + +-static int shmem_xattr_security_set(struct dentry *dentry, const char *name, +- const void *value, size_t size, int flags, int handler_flags) ++static int shmem_xattr_set(struct dentry *dentry, const char *name, ++ const void *value, size_t size, int flags) + { +- if (strcmp(name, "") == 0) +- return -EINVAL; +- return security_inode_setsecurity(dentry->d_inode, name, value, +- size, flags); ++ struct inode *inode = dentry->d_inode; ++ struct shmem_inode_info *info = SHMEM_I(inode); ++ struct shmem_xattr *xattr; ++ struct shmem_xattr *new_xattr = NULL; ++ size_t len; ++ int err = 0; ++ ++ /* value == NULL means remove */ ++ if (value) { ++ /* wrap around? */ ++ len = sizeof(*new_xattr) + size; ++ if (len <= sizeof(*new_xattr)) ++ return -ENOMEM; ++ ++ new_xattr = kmalloc(len, GFP_KERNEL); ++ if (!new_xattr) ++ return -ENOMEM; ++ ++ new_xattr->name = kstrdup(name, GFP_KERNEL); ++ if (!new_xattr->name) { ++ kfree(new_xattr); ++ return -ENOMEM; ++ } ++ ++ new_xattr->size = size; ++ memcpy(new_xattr->value, value, size); ++ } ++ ++ spin_lock(&info->lock); ++ list_for_each_entry(xattr, &info->xattr_list, list) { ++ if (!strcmp(name, xattr->name)) { ++ if (flags & XATTR_CREATE) { ++ xattr = new_xattr; ++ err = -EEXIST; ++ } else if (new_xattr) { ++ list_replace(&xattr->list, &new_xattr->list); ++ } else { ++ list_del(&xattr->list); ++ } ++ goto out; ++ } ++ } ++ if (flags & XATTR_REPLACE) { ++ xattr = new_xattr; ++ err = -ENODATA; ++ } else { ++ list_add(&new_xattr->list, &info->xattr_list); ++ xattr = NULL; ++ } ++out: ++ spin_unlock(&info->lock); ++ if (xattr) ++ kfree(xattr->name); ++ kfree(xattr); ++ return err; + } + +-static const struct 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, +-}; + + static const struct xattr_handler *shmem_xattr_handlers[] = { ++#ifdef CONFIG_TMPFS_POSIX_ACL + &generic_acl_access_handler, + &generic_acl_default_handler, +- &shmem_xattr_security_handler, ++#endif + NULL + }; ++ ++static int shmem_xattr_validate(const char *name) ++{ ++ struct { const char *prefix; size_t len; } arr[] = { ++ { XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN }, ++ { XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN } ++ }; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(arr); i++) { ++ size_t preflen = arr[i].len; ++ if (strncmp(name, arr[i].prefix, preflen) == 0) { ++ if (!name[preflen]) ++ return -EINVAL; ++ return 0; ++ } ++ } ++ return -EOPNOTSUPP; ++} ++ ++static ssize_t shmem_getxattr(struct dentry *dentry, const char *name, ++ void *buffer, size_t size) ++{ ++ int err; ++ ++ /* ++ * If this is a request for a synthetic attribute in the system.* ++ * namespace use the generic infrastructure to resolve a handler ++ * for it via sb->s_xattr. ++ */ ++ if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) ++ return generic_getxattr(dentry, name, buffer, size); ++ ++ err = shmem_xattr_validate(name); ++ if (err) ++ return err; ++ ++ return shmem_xattr_get(dentry, name, buffer, size); ++} ++ ++static int shmem_setxattr(struct dentry *dentry, const char *name, ++ const void *value, size_t size, int flags) ++{ ++ int err; ++ ++ /* ++ * If this is a request for a synthetic attribute in the system.* ++ * namespace use the generic infrastructure to resolve a handler ++ * for it via sb->s_xattr. ++ */ ++ if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) ++ return generic_setxattr(dentry, name, value, size, flags); ++ ++ err = shmem_xattr_validate(name); ++ if (err) ++ return err; ++ ++ if (size == 0) ++ value = ""; /* empty EA, do not remove */ ++ ++ return shmem_xattr_set(dentry, name, value, size, flags); ++ ++} ++ ++static int shmem_removexattr(struct dentry *dentry, const char *name) ++{ ++ int err; ++ ++ /* ++ * If this is a request for a synthetic attribute in the system.* ++ * namespace use the generic infrastructure to resolve a handler ++ * for it via sb->s_xattr. ++ */ ++ if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) ++ return generic_removexattr(dentry, name); ++ ++ err = shmem_xattr_validate(name); ++ if (err) ++ return err; ++ ++ return shmem_xattr_set(dentry, name, NULL, 0, XATTR_REPLACE); ++} ++ ++static bool xattr_is_trusted(const char *name) ++{ ++ return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN); ++} ++ ++static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size) ++{ ++ bool trusted = capable(CAP_SYS_ADMIN); ++ struct shmem_xattr *xattr; ++ struct shmem_inode_info *info; ++ size_t used = 0; ++ ++ info = SHMEM_I(dentry->d_inode); ++ ++ spin_lock(&info->lock); ++ list_for_each_entry(xattr, &info->xattr_list, list) { ++ size_t len; ++ ++ /* skip "trusted." attributes for unprivileged callers */ ++ if (!trusted && xattr_is_trusted(xattr->name)) ++ continue; ++ ++ len = strlen(xattr->name) + 1; ++ used += len; ++ if (buffer) { ++ if (size < used) { ++ used = -ERANGE; ++ break; ++ } ++ memcpy(buffer, xattr->name, len); ++ buffer += len; ++ } ++ } ++ spin_unlock(&info->lock); ++ ++ return used; ++} ++#endif /* CONFIG_TMPFS_XATTR */ ++ ++static const struct inode_operations shmem_symlink_inline_operations = { ++ .readlink = generic_readlink, ++ .follow_link = shmem_follow_link_inline, ++#ifdef CONFIG_TMPFS_XATTR ++ .setxattr = shmem_setxattr, ++ .getxattr = shmem_getxattr, ++ .listxattr = shmem_listxattr, ++ .removexattr = shmem_removexattr, ++#endif ++}; ++ ++static const struct inode_operations shmem_symlink_inode_operations = { ++ .readlink = generic_readlink, ++ .follow_link = shmem_follow_link, ++ .put_link = shmem_put_link, ++#ifdef CONFIG_TMPFS_XATTR ++ .setxattr = shmem_setxattr, ++ .getxattr = shmem_getxattr, ++ .listxattr = shmem_listxattr, ++ .removexattr = shmem_removexattr, + #endif ++}; + + static struct dentry *shmem_get_parent(struct dentry *child) + { +@@ -2403,8 +2607,10 @@ int shmem_fill_super(struct super_block + sb->s_magic = TMPFS_MAGIC; + sb->s_op = &shmem_ops; + sb->s_time_gran = 1; +-#ifdef CONFIG_TMPFS_POSIX_ACL ++#ifdef CONFIG_TMPFS_XATTR + sb->s_xattr = shmem_xattr_handlers; ++#endif ++#ifdef CONFIG_TMPFS_POSIX_ACL + sb->s_flags |= MS_POSIXACL; + #endif + +@@ -2502,11 +2708,13 @@ static const struct file_operations shme + static const struct inode_operations shmem_inode_operations = { + .setattr = shmem_notify_change, + .truncate_range = shmem_truncate_range, ++#ifdef CONFIG_TMPFS_XATTR ++ .setxattr = shmem_setxattr, ++ .getxattr = shmem_getxattr, ++ .listxattr = shmem_listxattr, ++ .removexattr = shmem_removexattr, ++#endif + #ifdef CONFIG_TMPFS_POSIX_ACL +- .setxattr = generic_setxattr, +- .getxattr = generic_getxattr, +- .listxattr = generic_listxattr, +- .removexattr = generic_removexattr, + .check_acl = generic_check_acl, + #endif + +@@ -2524,23 +2732,27 @@ static const struct inode_operations shm + .mknod = shmem_mknod, + .rename = shmem_rename, + #endif ++#ifdef CONFIG_TMPFS_XATTR ++ .setxattr = shmem_setxattr, ++ .getxattr = shmem_getxattr, ++ .listxattr = shmem_listxattr, ++ .removexattr = shmem_removexattr, ++#endif + #ifdef CONFIG_TMPFS_POSIX_ACL + .setattr = shmem_notify_change, +- .setxattr = generic_setxattr, +- .getxattr = generic_getxattr, +- .listxattr = generic_listxattr, +- .removexattr = generic_removexattr, + .check_acl = generic_check_acl, + #endif + }; + + static const struct inode_operations shmem_special_inode_operations = { ++#ifdef CONFIG_TMPFS_XATTR ++ .setxattr = shmem_setxattr, ++ .getxattr = shmem_getxattr, ++ .listxattr = shmem_listxattr, ++ .removexattr = shmem_removexattr, ++#endif + #ifdef CONFIG_TMPFS_POSIX_ACL + .setattr = shmem_notify_change, +- .setxattr = generic_setxattr, +- .getxattr = generic_getxattr, +- .listxattr = generic_listxattr, +- .removexattr = generic_removexattr, + .check_acl = generic_check_acl, + #endif + }; +-- +To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in +the body of a message to majordomo@vger.kernel.org +More majordomo info at http://vger.kernel.org/majordomo-info.html + |