diff --git a/main.c b/main.c index fc5cc79..5bd1993 100644 --- a/main.c +++ b/main.c @@ -4158,6 +4158,24 @@ ovl_setattr (fuse_req_t req, fuse_ino_t ino, struct stat *attr, int to_set, stru if (uid != -1 || gid != -1) { + struct stat st; + + if (do_stat (node, fd, NULL, &st) < 0) + { + fuse_reply_err (req, errno); + return; + } + + if (uid == -1) + { + uid = st.st_uid; + } + + if (gid == -1) + { + gid = st.st_gid; + } + if (fd >= 0) ret = do_fchown (lo, fd, uid, gid, node->ino->mode); else diff --git a/tests/unpriv.sh b/tests/unpriv.sh index 7bb19ed..a5916c7 100755 --- a/tests/unpriv.sh +++ b/tests/unpriv.sh @@ -29,3 +29,21 @@ else fi fusermount -u merged || [ $? -eq "${EXPECT_UMOUNT_STATUS:-0}" ] + +# xattr_permissions=2 +rm -rf lower upper workdir merged +mkdir lower upper workdir merged + +touch upper/file + +fuse-overlayfs -o lowerdir=lower,upperdir=upper,workdir=workdir,xattr_permissions=2 merged + +# Ensure UID is preserved with chgrp. +unshare --map-auto -r chgrp 1 merged/file +test $(unshare --map-auto -r stat -c %u:%g merged/file) = 0:1 + +# Ensure UID and GID are preserved with chmod. +chmod 600 merged/file +test $(unshare --map-auto -r stat -c %u:%g merged/file) = 0:1 + +fusermount -u merged || [ $? -eq "${EXPECT_UMOUNT_STATUS:-0}" ]