fuse: listxattr: verify xattr list
commit cb3ae6d25a5471be62bfe6ac1fccc0e91edeaba0 upstream. Make sure userspace filesystem is returning a well formed list of xattr names (zero or more nonzero length, null terminated strings). [Michael Theall: only verify in the nonzero size case] Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
1ccdc77563
commit
80b742b84f
1 changed files with 19 additions and 0 deletions
|
@ -1797,6 +1797,23 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int fuse_verify_xattr_list(char *list, size_t size)
|
||||
{
|
||||
size_t origsize = size;
|
||||
|
||||
while (size) {
|
||||
size_t thislen = strnlen(list, size);
|
||||
|
||||
if (!thislen || thislen == size)
|
||||
return -EIO;
|
||||
|
||||
size -= thislen + 1;
|
||||
list += thislen + 1;
|
||||
}
|
||||
|
||||
return origsize;
|
||||
}
|
||||
|
||||
static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
|
||||
{
|
||||
struct inode *inode = d_inode(entry);
|
||||
|
@ -1832,6 +1849,8 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
|
|||
ret = fuse_simple_request(fc, &args);
|
||||
if (!ret && !size)
|
||||
ret = outarg.size;
|
||||
if (ret > 0 && size)
|
||||
ret = fuse_verify_xattr_list(list, ret);
|
||||
if (ret == -ENOSYS) {
|
||||
fc->no_listxattr = 1;
|
||||
ret = -EOPNOTSUPP;
|
||||
|
|
Loading…
Add table
Reference in a new issue