summaryrefslogtreecommitdiff
path: root/src/core/execute.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-08-06 14:53:15 +0300
committerLennart Poettering <lennart@poettering.net>2015-08-06 14:56:20 +0300
commit6bfe5c28cad4716ed3ff6667c1546b5e180391fb (patch)
tree7111d9c6e833312e4dee535da209905f8881b9ad /src/core/execute.c
parent5df0997459fef2a3d3e15fcb1f4aa8d0643231aa (diff)
execute: don't fail if we create the runtime directory from two processes simultaneously
If a service has both ExecStart= and ExecStartPost= set with Type=simple, then it might happen that we have two children create the runtime directory of a service (as configured with RuntimeDirectory=) at the same time. Previously we did this with mkdir_safe() which will create the dir only if it is missing, but if it already exists will at least verify the access mode and ownership to match the right values. This is problematic in this case, since it creates and then adjusts the settings, thus it might happen that one child creates the directory with root owner, another one then verifies it, and only afterwards the directory ownership is fixed by the original child, while the second child already failed. With this change we'll now always adjust the access mode, so that we know that it is right. In the worst case this means we adjust the mode/ownership even though its unnecessary, but this should have no negative effect. https://bugzilla.redhat.com/show_bug.cgi?id=1226509
Diffstat (limited to 'src/core/execute.c')
-rw-r--r--src/core/execute.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/core/execute.c b/src/core/execute.c
index 125cb0dbd4..3820165241 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1554,7 +1554,13 @@ static int exec_child(
return -ENOMEM;
}
- r = mkdir_safe_label(p, context->runtime_directory_mode, uid, gid);
+ r = mkdir_p_label(p, context->runtime_directory_mode);
+ if (r < 0) {
+ *exit_status = EXIT_RUNTIME_DIRECTORY;
+ return r;
+ }
+
+ r = chmod_and_chown(p, context->runtime_directory_mode, uid, gid);
if (r < 0) {
*exit_status = EXIT_RUNTIME_DIRECTORY;
return r;