summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2019-04-16 18:44:12 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-04-26 08:31:08 +0200
commit85318688ccd5eb39d554cbe8fa78e6b3218ac621 (patch)
tree9604f5165f645c178bc4023b6b128aec696e3e3c
parentcbb3092ce647221644204c4b79ae8088303bda82 (diff)
downloadsystemd-85318688ccd5eb39d554cbe8fa78e6b3218ac621.tar.gz
chown-recursive: also check mode before we bypass
-rw-r--r--src/core/chown-recursive.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/src/core/chown-recursive.c b/src/core/chown-recursive.c
index 49d96b7376..fb42865875 100644
--- a/src/core/chown-recursive.c
+++ b/src/core/chown-recursive.c
@@ -133,17 +133,17 @@ int path_chown_recursive(
if (fd < 0)
return -errno;
- if (!uid_is_valid(uid) && !gid_is_valid(gid))
+ if (!uid_is_valid(uid) && !gid_is_valid(gid) && (mask & 07777) == 07777)
return 0; /* nothing to do */
if (fstat(fd, &st) < 0)
return -errno;
- /* Let's take a shortcut: if the top-level directory is properly owned, we don't descend into the whole tree,
- * under the assumption that all is OK anyway. */
-
+ /* Let's take a shortcut: if the top-level directory is properly owned, we don't descend into the
+ * whole tree, under the assumption that all is OK anyway. */
if ((!uid_is_valid(uid) || st.st_uid == uid) &&
- (!gid_is_valid(gid) || st.st_gid == gid))
+ (!gid_is_valid(gid) || st.st_gid == gid) &&
+ ((st.st_mode & ~mask & 07777) == 0))
return 0;
return chown_recursive_internal(TAKE_FD(fd), &st, uid, gid, mask); /* we donate the fd to the call, regardless if it succeeded or failed */