diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-10 17:11:50 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-10 17:11:50 -0700 |
commit | 97d2116708ca0fd6ad8b00811ee4349b7e19e96f (patch) | |
tree | 81f73fc1a6daee60737b591cf1be73cc4f79de37 /fs/kernfs/inode.c | |
parent | 30066ce675d3af350bc5a53858991c0b518dda00 (diff) | |
parent | fd50ecaddf8372a1d96e0daeaac0f93cf04e4d42 (diff) | |
download | linux-97d2116708ca0fd6ad8b00811ee4349b7e19e96f.tar.bz2 |
Merge branch 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs xattr updates from Al Viro:
"xattr stuff from Andreas
This completes the switch to xattr_handler ->get()/->set() from
->getxattr/->setxattr/->removexattr"
* 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
vfs: Remove {get,set,remove}xattr inode operations
xattr: Stop calling {get,set,remove}xattr inode operations
vfs: Check for the IOP_XATTR flag in listxattr
xattr: Add __vfs_{get,set,remove}xattr helpers
libfs: Use IOP_XATTR flag for empty directory handling
vfs: Use IOP_XATTR flag for bad-inode handling
vfs: Add IOP_XATTR inode operations flag
vfs: Move xattr_resolve_name to the front of fs/xattr.c
ecryptfs: Switch to generic xattr handlers
sockfs: Get rid of getxattr iop
sockfs: getxattr: Fail with -EOPNOTSUPP for invalid attribute names
kernfs: Switch to generic xattr handlers
hfs: Switch to generic xattr handlers
jffs2: Remove jffs2_{get,set,remove}xattr macros
xattr: Remove unnecessary NULL attribute name check
Diffstat (limited to 'fs/kernfs/inode.c')
-rw-r--r-- | fs/kernfs/inode.c | 155 |
1 files changed, 81 insertions, 74 deletions
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index df21f5b75549..102b6f0bc7af 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -28,9 +28,6 @@ static const struct inode_operations kernfs_iops = { .permission = kernfs_iop_permission, .setattr = kernfs_iop_setattr, .getattr = kernfs_iop_getattr, - .setxattr = kernfs_iop_setxattr, - .removexattr = kernfs_iop_removexattr, - .getxattr = kernfs_iop_getxattr, .listxattr = kernfs_iop_listxattr, }; @@ -138,17 +135,12 @@ out: return error; } -static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata, +static int kernfs_node_setsecdata(struct kernfs_iattrs *attrs, void **secdata, u32 *secdata_len) { - struct kernfs_iattrs *attrs; void *old_secdata; size_t old_secdata_len; - attrs = kernfs_iattrs(kn); - if (!attrs) - return -ENOMEM; - old_secdata = attrs->ia_secdata; old_secdata_len = attrs->ia_secdata_len; @@ -160,71 +152,6 @@ static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata, return 0; } -int kernfs_iop_setxattr(struct dentry *unused, struct inode *inode, - const char *name, const void *value, - size_t size, int flags) -{ - struct kernfs_node *kn = inode->i_private; - struct kernfs_iattrs *attrs; - void *secdata; - int error; - u32 secdata_len = 0; - - attrs = kernfs_iattrs(kn); - if (!attrs) - return -ENOMEM; - - if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) { - const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; - error = security_inode_setsecurity(inode, suffix, - value, size, flags); - if (error) - return error; - error = security_inode_getsecctx(inode, - &secdata, &secdata_len); - if (error) - return error; - - mutex_lock(&kernfs_mutex); - error = kernfs_node_setsecdata(kn, &secdata, &secdata_len); - mutex_unlock(&kernfs_mutex); - - if (secdata) - security_release_secctx(secdata, secdata_len); - return error; - } else if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) { - return simple_xattr_set(&attrs->xattrs, name, value, size, - flags); - } - - return -EINVAL; -} - -int kernfs_iop_removexattr(struct dentry *dentry, const char *name) -{ - struct kernfs_node *kn = dentry->d_fsdata; - struct kernfs_iattrs *attrs; - - attrs = kernfs_iattrs(kn); - if (!attrs) - return -ENOMEM; - - return simple_xattr_set(&attrs->xattrs, name, NULL, 0, XATTR_REPLACE); -} - -ssize_t kernfs_iop_getxattr(struct dentry *unused, struct inode *inode, - const char *name, void *buf, size_t size) -{ - struct kernfs_node *kn = inode->i_private; - struct kernfs_iattrs *attrs; - - attrs = kernfs_iattrs(kn); - if (!attrs) - return -ENOMEM; - - return simple_xattr_get(&attrs->xattrs, name, buf, size); -} - ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) { struct kernfs_node *kn = dentry->d_fsdata; @@ -376,3 +303,83 @@ int kernfs_iop_permission(struct inode *inode, int mask) return generic_permission(inode, mask); } + +static int kernfs_xattr_get(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *suffix, void *value, size_t size) +{ + const char *name = xattr_full_name(handler, suffix); + struct kernfs_node *kn = inode->i_private; + struct kernfs_iattrs *attrs; + + attrs = kernfs_iattrs(kn); + if (!attrs) + return -ENOMEM; + + return simple_xattr_get(&attrs->xattrs, name, value, size); +} + +static int kernfs_xattr_set(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *suffix, const void *value, + size_t size, int flags) +{ + const char *name = xattr_full_name(handler, suffix); + struct kernfs_node *kn = inode->i_private; + struct kernfs_iattrs *attrs; + + attrs = kernfs_iattrs(kn); + if (!attrs) + return -ENOMEM; + + return simple_xattr_set(&attrs->xattrs, name, value, size, flags); +} + +const struct xattr_handler kernfs_trusted_xattr_handler = { + .prefix = XATTR_TRUSTED_PREFIX, + .get = kernfs_xattr_get, + .set = kernfs_xattr_set, +}; + +static int kernfs_security_xattr_set(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *suffix, const void *value, + size_t size, int flags) +{ + struct kernfs_node *kn = inode->i_private; + struct kernfs_iattrs *attrs; + void *secdata; + u32 secdata_len = 0; + int error; + + attrs = kernfs_iattrs(kn); + if (!attrs) + return -ENOMEM; + + error = security_inode_setsecurity(inode, suffix, value, size, flags); + if (error) + return error; + error = security_inode_getsecctx(inode, &secdata, &secdata_len); + if (error) + return error; + + mutex_lock(&kernfs_mutex); + error = kernfs_node_setsecdata(attrs, &secdata, &secdata_len); + mutex_unlock(&kernfs_mutex); + + if (secdata) + security_release_secctx(secdata, secdata_len); + return error; +} + +const struct xattr_handler kernfs_security_xattr_handler = { + .prefix = XATTR_SECURITY_PREFIX, + .get = kernfs_xattr_get, + .set = kernfs_security_xattr_set, +}; + +const struct xattr_handler *kernfs_xattr_handlers[] = { + &kernfs_trusted_xattr_handler, + &kernfs_security_xattr_handler, + NULL +}; |