X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=fs%2Fxattr.c;h=3c0e19b443b67c1b0aed68817abf493299770159;hb=1ba5e15cc8d4b7fc850c14939e8d48393c40ef13;hp=464c94bf65f9e55339ec9d4bc515ec990691deb7;hpb=8c5c25067044b7bcb2201e761483ef4cacc970d8;p=mirror_ubuntu-artful-kernel.git diff --git a/fs/xattr.c b/fs/xattr.c index 464c94bf65f9..3c0e19b443b6 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -202,6 +202,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, return error; } +EXPORT_SYMBOL_GPL(__vfs_setxattr_noperm); int @@ -249,7 +250,7 @@ xattr_getsecurity(struct inode *inode, const char *name, void *value, } memcpy(value, buffer, len); out: - security_release_secctx(buffer, len); + kfree(buffer); out_noalloc: return len; } @@ -296,6 +297,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, *xattr_value = value; return error; } +EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); ssize_t __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, @@ -379,6 +381,33 @@ __vfs_removexattr(struct dentry *dentry, const char *name) } EXPORT_SYMBOL(__vfs_removexattr); +/** + * __vfs_removexattr_noperm - perform removexattr operation without + * performing permission checks. + * + * @dentry - object to perform setxattr on + * @name - xattr name to set + * + * returns the result of the internal setxattr or setsecurity operations. + * + * This function requires the caller to lock the inode's i_mutex before it + * is executed. It also assumes that the caller will make the appropriate + * permission checks. + */ +int +__vfs_removexattr_noperm(struct dentry *dentry, const char *name) +{ + int error; + + error =__vfs_removexattr(dentry, name); + if (!error) { + fsnotify_xattr(dentry); + evm_inode_post_removexattr(dentry, name); + } + return error; +} +EXPORT_SYMBOL_GPL(__vfs_removexattr_noperm); + int vfs_removexattr(struct dentry *dentry, const char *name) { @@ -394,12 +423,7 @@ vfs_removexattr(struct dentry *dentry, const char *name) if (error) goto out; - error = __vfs_removexattr(dentry, name); - - if (!error) { - fsnotify_xattr(dentry); - evm_inode_post_removexattr(dentry, name); - } + error = __vfs_removexattr_noperm(dentry, name); out: inode_unlock(inode); @@ -441,6 +465,12 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) posix_acl_fix_xattr_from_user(kvalue, size); + else if (strcmp(kname, XATTR_NAME_CAPS) == 0) { + error = cap_convert_nscap(d, &kvalue, size); + if (error < 0) + goto out; + size = error; + } } error = vfs_setxattr(d, kname, kvalue, size, flags);