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);
|
return inode_permission(inode, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
/**
|
||||||
vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
|
* __vfs_setxattr_noperm - perform setxattr operation without performing
|
||||||
size_t size, int flags)
|
* 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;
|
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) {
|
if (inode->i_op->setxattr) {
|
||||||
error = inode->i_op->setxattr(dentry, name, value, size, flags);
|
error = inode->i_op->setxattr(dentry, name, value, size, flags);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
|
@ -97,6 +103,29 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
|
||||||
if (!error)
|
if (!error)
|
||||||
fsnotify_xattr(dentry);
|
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:
|
out:
|
||||||
mutex_unlock(&inode->i_mutex);
|
mutex_unlock(&inode->i_mutex);
|
||||||
return error;
|
return error;
|
||||||
|
|
|
@ -49,6 +49,7 @@ struct xattr_handler {
|
||||||
ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
|
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_getxattr(struct dentry *, const char *, void *, size_t);
|
||||||
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
|
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_setxattr(struct dentry *, const char *, const void *, size_t, int);
|
||||||
int vfs_removexattr(struct dentry *, const char *);
|
int vfs_removexattr(struct dentry *, const char *);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче