main: fix invalid access when filtering xattrs

Fix an invalid access when filtering internal xattrs.

The size passed to memmove was longer than the remaining bytes to
process.

As part of the fix: move the filtering logic to a separate function.

Closes: https://github.com/containers/fuse-overlayfs/issues/293

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2021-06-21 15:09:43 +02:00
parent 0087bbc85f
commit f41a872e0d
No known key found for this signature in database
GPG Key ID: E4730F97F60286ED

53
main.c
View File

@ -2474,6 +2474,42 @@ ovl_releasedir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
fuse_reply_err (req, 0);
}
/* in-place filter xattrs that cannot be accessed. */
static ssize_t
filter_xattrs_list (char *buf, ssize_t len)
{
ssize_t ret = 0;
size_t i = 0;
char *it;
if (buf == NULL)
return len;
it = buf;
while (it < buf + len)
{
size_t it_len;
it_len = strlen (it) + 1;
if (can_access_xattr (it))
{
it += it_len;
ret += it_len;
}
else
{
char *next = it + it_len;
memmove (it, next, buf + len - next);
len -= it_len;
}
}
return ret;
}
static void
ovl_listxattr (fuse_req_t req, fuse_ino_t ino, size_t size)
{
@ -2525,22 +2561,7 @@ ovl_listxattr (fuse_req_t req, fuse_ino_t ino, size_t size)
return;
}
len = ret;
for (i = 0; buf && i < len;)
{
size_t current_len;
const char *cur_attr = buf + i;
current_len = strlen (cur_attr) + 1;
if (can_access_xattr (cur_attr))
i += current_len;
else
{
memmove (buf + i, cur_attr + current_len, len - current_len);
len -= current_len;
}
}
len = filter_xattrs_list (buf, ret);
if (size == 0)
fuse_reply_xattr (req, len);