Skip to content

Commit

Permalink
VFS: Factor out part of vfs_setxattr so it can be called from the SEL…
Browse files Browse the repository at this point in the history
…inux 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 <[email protected]>
Acked-by: Serge Hallyn <[email protected]>
Signed-off-by: James Morris <[email protected]>
  • Loading branch information
David P. Quigley authored and James Morris committed Sep 10, 2009
1 parent 733e5e4 commit b1ab7e4
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 13 deletions.
55 changes: 42 additions & 13 deletions fs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

error = xattr_permission(inode, name, MAY_WRITE);
if (error)
return error;
int error = -EOPNOTSUPP;

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) {
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions include/linux/xattr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);

Expand Down

0 comments on commit b1ab7e4

Please sign in to comment.