chown-recursive: also check mode before we bypass
authorLennart Poettering <lennart@poettering.net>
Tue, 16 Apr 2019 16:44:12 +0000 (18:44 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 26 Apr 2019 06:31:08 +0000 (08:31 +0200)
src/core/chown-recursive.c

index 49d96b7..fb42865 100644 (file)
@@ -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 */