fuse: listxattr: verify xattr list
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> Cc: <stable@vger.kernel.org>
This commit is contained in:
parent
08895a8b6b
commit
cb3ae6d25a
|
@ -1801,6 +1801,23 @@ static ssize_t fuse_getxattr(struct dentry *entry, struct inode *inode,
|
||||||
return ret;
|
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)
|
static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(entry);
|
struct inode *inode = d_inode(entry);
|
||||||
|
@ -1836,6 +1853,8 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
|
||||||
ret = fuse_simple_request(fc, &args);
|
ret = fuse_simple_request(fc, &args);
|
||||||
if (!ret && !size)
|
if (!ret && !size)
|
||||||
ret = outarg.size;
|
ret = outarg.size;
|
||||||
|
if (ret > 0 && size)
|
||||||
|
ret = fuse_verify_xattr_list(list, ret);
|
||||||
if (ret == -ENOSYS) {
|
if (ret == -ENOSYS) {
|
||||||
fc->no_listxattr = 1;
|
fc->no_listxattr = 1;
|
||||||
ret = -EOPNOTSUPP;
|
ret = -EOPNOTSUPP;
|
||||||
|
|
Loading…
Reference in New Issue