From f41a872e0de9747baf1a209af8c98ce8af1698e6 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 21 Jun 2021 15:09:43 +0200 Subject: [PATCH] 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 --- main.c | 53 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/main.c b/main.c index 2b04262..b448d9b 100644 --- a/main.c +++ b/main.c @@ -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);