diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-08-06 14:53:15 +0300 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-08-06 14:56:20 +0300 |
commit | 6bfe5c28cad4716ed3ff6667c1546b5e180391fb (patch) | |
tree | 7111d9c6e833312e4dee535da209905f8881b9ad /src | |
parent | 5df0997459fef2a3d3e15fcb1f4aa8d0643231aa (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')
-rw-r--r-- | src/core/execute.c | 8 |
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; |