Blame SOURCES/0268-core-change-ownership-mode-of-the-execution-director.patch

ddca0b
From 789806ac06bb13d1b579fef47dbb85f224b6dbb1 Mon Sep 17 00:00:00 2001
ddca0b
From: Lennart Poettering <lennart@poettering.net>
ddca0b
Date: Thu, 14 Mar 2019 17:19:30 +0100
ddca0b
Subject: [PATCH] core: change ownership/mode of the execution directories also
ddca0b
 for static users
ddca0b
ddca0b
It's probably unexpected if we do a recursive chown() when dynamic users
ddca0b
are used but not on static users.
ddca0b
ddca0b
hence, let's tweak the logic slightly, and recursively chown in both
ddca0b
cases, except when operating on the configuration directory.
ddca0b
ddca0b
Fixes: #11842
ddca0b
(cherry picked from commit 206e9864de460dd79d9edd7bedb47dee168765e1)
ddca0b
ddca0b
Resolves: #1778384
ddca0b
---
ddca0b
 src/core/execute.c | 47 +++++++++++++++++++++++++---------------------
ddca0b
 1 file changed, 26 insertions(+), 21 deletions(-)
ddca0b
ddca0b
diff --git a/src/core/execute.c b/src/core/execute.c
ddca0b
index 46aa733937..c42300a41e 100644
ddca0b
--- a/src/core/execute.c
ddca0b
+++ b/src/core/execute.c
ddca0b
@@ -2090,37 +2090,42 @@ static int setup_exec_directory(
ddca0b
                         if (r < 0)
ddca0b
                                 goto fail;
ddca0b
 
ddca0b
-                        /* Lock down the access mode */
ddca0b
-                        if (chmod(pp, context->directories[type].mode) < 0) {
ddca0b
-                                r = -errno;
ddca0b
-                                goto fail;
ddca0b
-                        }
ddca0b
                 } else {
ddca0b
                         r = mkdir_label(p, context->directories[type].mode);
ddca0b
                         if (r < 0) {
ddca0b
-                                struct stat st;
ddca0b
-
ddca0b
                                 if (r != -EEXIST)
ddca0b
                                         goto fail;
ddca0b
 
ddca0b
-                                if (stat(p, &st) < 0) {
ddca0b
-                                        r = -errno;
ddca0b
-                                        goto fail;
ddca0b
-                                }
ddca0b
-                                if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0)
ddca0b
-                                        log_warning("%s \'%s\' already exists but the mode is different. "
ddca0b
-                                                    "(filesystem: %o %sMode: %o)",
ddca0b
-                                                    exec_directory_type_to_string(type), *rt,
ddca0b
-                                                    st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777);
ddca0b
-                                if (!context->dynamic_user)
ddca0b
+                                if (type == EXEC_DIRECTORY_CONFIGURATION) {
ddca0b
+                                        struct stat st;
ddca0b
+
ddca0b
+                                        /* Don't change the owner/access mode of the configuration directory,
ddca0b
+                                         * as in the common case it is not written to by a service, and shall
ddca0b
+                                         * not be writable. */
ddca0b
+
ddca0b
+                                        if (stat(p, &st) < 0) {
ddca0b
+                                                r = -errno;
ddca0b
+                                                goto fail;
ddca0b
+                                        }
ddca0b
+
ddca0b
+                                        /* Still complain if the access mode doesn't match */
ddca0b
+                                        if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0)
ddca0b
+                                                log_warning("%s \'%s\' already exists but the mode is different. "
ddca0b
+                                                            "(File system: %o %sMode: %o)",
ddca0b
+                                                            exec_directory_type_to_string(type), *rt,
ddca0b
+                                                            st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777);
ddca0b
+
ddca0b
                                         continue;
ddca0b
+                                }
ddca0b
                         }
ddca0b
                 }
ddca0b
 
ddca0b
-                /* Don't change the owner of the configuration directory, as in the common case it is not written to by
ddca0b
-                 * a service, and shall not be writable. */
ddca0b
-                if (type == EXEC_DIRECTORY_CONFIGURATION)
ddca0b
-                        continue;
ddca0b
+                /* Lock down the access mode (we use chmod_and_chown() to make this idempotent. We don't
ddca0b
+                 * specifiy UID/GID here, so that path_chown_recursive() can optimize things depending on the
ddca0b
+                 * current UID/GID ownership.) */
ddca0b
+                r = chmod_and_chown(pp ?: p, context->directories[type].mode, UID_INVALID, GID_INVALID);
ddca0b
+                if (r < 0)
ddca0b
+                        goto fail;
ddca0b
 
ddca0b
                 /* Then, change the ownership of the whole tree, if necessary */
ddca0b
                 r = path_chown_recursive(pp ?: p, uid, gid);