VFS: Factor out part of vfs_setxattr so it can be called from the SELinux hook for inode_setsecctx.
This factors out the part of the vfs_setxattr function that performs the setting of the xattr and its notification. This is needed so the SELinux implementation of inode_setsecctx can handle the setting of the xattr while maintaining the proper separation of layers. Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
Родитель
733e5e4b4e
Коммит
b1ab7e4b2a
55
fs/xattr.c
55
fs/xattr.c
|
@ -66,22 +66,28 @@ xattr_permission(struct inode *inode, const char *name, int mask)
|
|||
return inode_permission(inode, mask);
|
||||
}
|
||||
|
||||
int
|
||||
vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
|
||||
size_t size, int flags)
|
||||
/**
|
||||
* __vfs_setxattr_noperm - perform setxattr operation without performing
|
||||
* permission checks.
|
||||
*
|
||||
* @dentry - object to perform setxattr on
|
||||
* @name - xattr name to set
|
||||
* @value - value to set @name to
|
||||
* @size - size of @value
|
||||
* @flags - flags to pass into filesystem operations
|
||||
*
|
||||
* 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_setxattr_noperm(struct dentry *dentry, const char *name,
|
||||
const void *value, size_t size, int flags)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
int error = -EOPNOTSUPP;
|
||||
|
||||
error = xattr_permission(inode, name, MAY_WRITE);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
error = security_inode_setxattr(dentry, name, value, size, flags);
|
||||
if (error)
|
||||
goto out;
|
||||
error = -EOPNOTSUPP;
|
||||
if (inode->i_op->setxattr) {
|
||||
error = inode->i_op->setxattr(dentry, name, value, size, flags);
|
||||
if (!error) {
|
||||
|
@ -97,6 +103,29 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
|
|||
if (!error)
|
||||
fsnotify_xattr(dentry);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
|
||||
size_t size, int flags)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
|
||||
error = xattr_permission(inode, name, MAY_WRITE);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
error = security_inode_setxattr(dentry, name, value, size, flags);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
error = __vfs_setxattr_noperm(dentry, name, value, size, flags);
|
||||
|
||||
out:
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return error;
|
||||
|
|
|
@ -49,6 +49,7 @@ struct xattr_handler {
|
|||
ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
|
||||
ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
|
||||
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
|
||||
int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int);
|
||||
int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int);
|
||||
int vfs_removexattr(struct dentry *, const char *);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче