diff options
| author | David P. Quigley <dpquigl@tycho.nsa.gov> | 2009-09-03 14:25:56 -0400 |
|---|---|---|
| committer | James Morris <jmorris@namei.org> | 2009-09-09 20:11:22 -0400 |
| commit | b1ab7e4b2a88d3ac13771463be8f302ce1616cfc (patch) | |
| tree | c08825120cb290a4307d36ee0bee806ad2aae83c | |
| parent | 733e5e4b4eb1bc1e27acbe092200154051171426 (diff) | |
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>
| -rw-r--r-- | fs/xattr.c | 55 | ||||
| -rw-r--r-- | include/linux/xattr.h | 1 |
2 files changed, 43 insertions, 13 deletions
diff --git a/fs/xattr.c b/fs/xattr.c index 1c3d0af59ddf..6d4f6d3449fb 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
| @@ -66,22 +66,28 @@ xattr_permission(struct inode *inode, const char *name, int mask) | |||
| 66 | return inode_permission(inode, mask); | 66 | return inode_permission(inode, mask); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | int | 69 | /** |
| 70 | vfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 70 | * __vfs_setxattr_noperm - perform setxattr operation without performing |
| 71 | size_t size, int flags) | 71 | * permission checks. |
| 72 | * | ||
| 73 | * @dentry - object to perform setxattr on | ||
| 74 | * @name - xattr name to set | ||
| 75 | * @value - value to set @name to | ||
| 76 | * @size - size of @value | ||
| 77 | * @flags - flags to pass into filesystem operations | ||
| 78 | * | ||
| 79 | * returns the result of the internal setxattr or setsecurity operations. | ||
| 80 | * | ||
| 81 | * This function requires the caller to lock the inode's i_mutex before it | ||
| 82 | * is executed. It also assumes that the caller will make the appropriate | ||
| 83 | * permission checks. | ||
| 84 | */ | ||
| 85 | int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, | ||
| 86 | const void *value, size_t size, int flags) | ||
| 72 | { | 87 | { |
| 73 | struct inode *inode = dentry->d_inode; | 88 | struct inode *inode = dentry->d_inode; |
| 74 | int error; | 89 | int error = -EOPNOTSUPP; |
| 75 | |||
| 76 | error = xattr_permission(inode, name, MAY_WRITE); | ||
| 77 | if (error) | ||
| 78 | return error; | ||
| 79 | 90 | ||
| 80 | mutex_lock(&inode->i_mutex); | ||
| 81 | error = security_inode_setxattr(dentry, name, value, size, flags); | ||
| 82 | if (error) | ||
| 83 | goto out; | ||
| 84 | error = -EOPNOTSUPP; | ||
| 85 | if (inode->i_op->setxattr) { | 91 | if (inode->i_op->setxattr) { |
| 86 | error = inode->i_op->setxattr(dentry, name, value, size, flags); | 92 | error = inode->i_op->setxattr(dentry, name, value, size, flags); |
| 87 | if (!error) { | 93 | if (!error) { |
| @@ -97,6 +103,29 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
| 97 | if (!error) | 103 | if (!error) |
| 98 | fsnotify_xattr(dentry); | 104 | fsnotify_xattr(dentry); |
| 99 | } | 105 | } |
| 106 | |||
| 107 | return error; | ||
| 108 | } | ||
| 109 | |||
| 110 | |||
| 111 | int | ||
| 112 | vfs_setxattr(struct dentry *dentry, const char *name, const void *value, | ||
| 113 | size_t size, int flags) | ||
| 114 | { | ||
| 115 | struct inode *inode = dentry->d_inode; | ||
| 116 | int error; | ||
| 117 | |||
| 118 | error = xattr_permission(inode, name, MAY_WRITE); | ||
| 119 | if (error) | ||
| 120 | return error; | ||
| 121 | |||
| 122 | mutex_lock(&inode->i_mutex); | ||
| 123 | error = security_inode_setxattr(dentry, name, value, size, flags); | ||
| 124 | if (error) | ||
| 125 | goto out; | ||
| 126 | |||
| 127 | error = __vfs_setxattr_noperm(dentry, name, value, size, flags); | ||
| 128 | |||
| 100 | out: | 129 | out: |
| 101 | mutex_unlock(&inode->i_mutex); | 130 | mutex_unlock(&inode->i_mutex); |
| 102 | return error; | 131 | return error; |
diff --git a/include/linux/xattr.h b/include/linux/xattr.h index d131e352cfe1..5c84af8c5f6f 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h | |||
| @@ -49,6 +49,7 @@ struct xattr_handler { | |||
| 49 | ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); | 49 | ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); |
| 50 | ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); | 50 | ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); |
| 51 | ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); | 51 | ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); |
| 52 | int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int); | ||
| 52 | int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int); | 53 | int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int); |
| 53 | int vfs_removexattr(struct dentry *, const char *); | 54 | int vfs_removexattr(struct dentry *, const char *); |
| 54 | 55 | ||
