From 6d6f7b7a1fba4cda551ab8851bc5172457bd3f13 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 8 Aug 2025 09:27:39 -0700 Subject: [PATCH] fuse2fs: fix various problems in get_req_groups get_req_groups has two problems: first, it doesn't free the array if fuse_getgroups errors out; and it passes errors to its caller. The memory leak is an obvious fix, but in the error case we actually want to fall back to checking the sole gid that the fuse request context gave us. Fix both of these errors. Cc: # v1.47.3 Fixes: 3469e6ff606af8 ("fuse2fs: fix group membership checking in op_chmod") Signed-off-by: "Darrick J. Wong" --- misc/fuse2fs.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index f9da9c1a..cce1c97c 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -2264,8 +2264,17 @@ static int get_req_groups(struct fuse2fs *ff, gid_t **gids, size_t *nr_gids) return translate_error(fs, 0, err); ret = fuse_getgroups(nr, array); - if (ret < 0) - return ret; + if (ret < 0) { + /* + * If there's an error, we failed to find the group + * membership of the process that initiated the file + * change, either because the process went away or + * because there's no Linux procfs. Regardless of the + * cause, we return -ENOENT. + */ + ext2fs_free_mem(&array); + return -ENOENT; + } if (ret <= nr) { *gids = array; @@ -2296,13 +2305,23 @@ static int in_file_group(struct fuse_context *ctxt, int ret; ret = get_req_groups(ff, &gids, &nr_gids); + if (ret == -ENOENT) { + /* magic return code for "could not get caller group info" */ + return ctxt->gid == inode_gid(*inode); + } if (ret < 0) return ret; - for (i = 0; i < nr_gids; i++) - if (gids[i] == gid) - return 1; - return 0; + ret = 0; + for (i = 0; i < nr_gids; i++) { + if (gids[i] == gid) { + ret = 1; + break; + } + } + + ext2fs_free_mem(&gids); + return ret; } #else static int in_file_group(struct fuse_context *ctxt, -- 2.47.3