From e3685b8c172bf47832bf06cf8bdc69c024e874ee Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 24 Aug 2022 14:54:15 +0200 Subject: [PATCH] main: inherit ACLs for new files/dirs when creating a new file/directory, inherit the ACL from the parent directory. Closes: https://github.com/containers/fuse-overlayfs/issues/363 Signed-off-by: Giuseppe Scrivano --- main.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/main.c b/main.c index b6241da..9eb95bd 100644 --- a/main.c +++ b/main.c @@ -64,6 +64,8 @@ #include #include +#define ACL_XATTR "system.posix_acl_default" + #ifndef TEMP_FAILURE_RETRY #define TEMP_FAILURE_RETRY(expression) \ (__extension__ \ @@ -2508,6 +2510,33 @@ ovl_releasedir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) fuse_reply_err (req, 0); } +static int +inherit_acl (struct ovl_data *lo, struct ovl_node *parent, int targetfd, const char *path) +{ + cleanup_free char *v = NULL; + cleanup_close int dfd = -1; + int s; + + if (parent == NULL || lo->noacl) + return 0; + + dfd = safe_openat (node_dirfd (parent), parent->path, O_DIRECTORY, 0); + if (dfd < 0) + return -1; + + s = safe_read_xattr (&v, dfd, ACL_XATTR, 4096); + if (s < 0) + { + if (errno == ENODATA || errno == ENOTSUP) + return 0; + return -1; + } + if (targetfd >= 0) + return fsetxattr (targetfd, ACL_XATTR, v, s, 0); + + return setxattr (path, ACL_XATTR, v, s, 0); +} + /* in-place filter xattrs that cannot be accessed. */ static ssize_t filter_xattrs_list (char *buf, ssize_t len) @@ -2869,6 +2898,10 @@ create_directory (struct ovl_data *lo, int dirfd, const char *name, const struct goto out; } + ret = inherit_acl (lo, parent, dfd, NULL); + if (ret < 0) + goto out; + ret = renameat (lo->workdir_fd, wd_tmp_file_name, dirfd, name); if (ret < 0) { @@ -3641,6 +3674,10 @@ ovl_do_open (fuse_req_t req, fuse_ino_t parent, const char *name, int flags, mod if (fd < 0) return fd; + ret = inherit_acl (lo, n, fd, NULL); + if (ret < 0) + return ret; + if (need_delete_whiteout && delete_whiteout (lo, -1, p, name) < 0) return -1; @@ -4895,6 +4932,14 @@ ovl_mknod (fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode, dev return; } + ret = inherit_acl (lo, pnode, -1, path); + if (ret < 0) + { + fuse_reply_err (req, errno); + unlinkat (lo->workdir_fd, wd_tmp_file_name, 0); + return; + } + ret = renameat (lo->workdir_fd, wd_tmp_file_name, get_upper_layer (lo)->fd, path); if (ret < 0) {