diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 06ae6b32529..02d2e9e2598 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -220,10 +220,13 @@
cannot leave files around after unit termination. Moreover ProtectSystem=strict and
ProtectHome=read-only are implied, thus prohibiting the service to write to arbitrary file
system locations. In order to allow the service to write to certain directories, they have to be whitelisted
- using ReadWritePaths=, but care must be taken so that UID/GID recycling doesn't
- create security issues involving files created by the service. Use RuntimeDirectory= (see
- below) in order to assign a writable runtime directory to a service, owned by the dynamic user/group and
- removed automatically when the unit is terminated. Defaults to off.
+ using ReadWritePaths=, but care must be taken so that UID/GID recycling doesn't create
+ security issues involving files created by the service. Use RuntimeDirectory= (see below) in
+ order to assign a writable runtime directory to a service, owned by the dynamic user/group and removed
+ automatically when the unit is terminated. Use StateDirectory=,
+ CacheDirectory= and LogsDirectory= in order to assign a set of writable
+ directories for specific purposes to the service in a way that they are protected from vulnerabilities due to
+ UID reuse (see below). Defaults to off.
@@ -1753,23 +1756,58 @@ CapabilityBoundingSet=~CAP_B CAP_C
RuntimeDirectory=
+ StateDirectory=
+ CacheDirectory=
+ LogsDirectory=
+ ConfigurationDirectory=
- Takes a whitespace-separated list of directory names. The specified directory names must be
- relative, and may not include . or ... If set, one or more directories
- including their parents by the specified names will be created below /run (for system
- services) or below $XDG_RUNTIME_DIR (for user services) when the unit is started. The
- lowest subdirectories are removed when the unit is stopped. It is possible to preserve the directories if
- RuntimeDirectoryPreserve= is configured to or .
- The lowest subdirectories will have the access mode specified in RuntimeDirectoryMode=,
- and be owned by the user and group specified in User= and Group=.
- This implies ReadWritePaths=, that is, the directories specified
- in this option are accessible with the access mode specified in RuntimeDirectoryMode=
- even if ProtectSystem= is set to .
- Use this to manage one or more runtime directories of the unit and bind their
- lifetime to the daemon runtime. This is particularly useful for unprivileged daemons that cannot create
+ These options take a whitespace-separated list of directory names. The specified directory
+ names must be relative, and may not include . or ... If set, one or more
+ directories by the specified names will be created (including their parents) below /run
+ (or $XDG_RUNTIME_DIR for user services), /var/lib (or
+ $XDG_CONFIG_HOME for user services), /var/cache (or
+ $XDG_CACHE_HOME for user services), /var/log (or
+ $XDG_CONFIG_HOME/log for user services), or /etc
+ (or $XDG_CONFIG_HOME for user services), respectively, when the unit is started.
+
+ In case of RuntimeDirectory= the lowest subdirectories are removed when the unit is
+ stopped. It is possible to preserve the specified directories in this case if
+ RuntimeDirectoryPreserve= is configured to or
+ (see below). The directories specified with StateDirectory=,
+ CacheDirectory=, LogsDirectory=,
+ ConfigurationDirectory= are not removed when the unit is stopped.
+
+ Except in case of ConfigurationDirectory=, the innermost specified directories will be
+ owned by the user and group specified in User= and Group=. If the
+ specified directories already exist and their owning user or group do not match the configured ones, all files
+ and directories below the specified directories as well as the directories themselves will have their file
+ ownership recursively changed to match what is configured. As an optimization, if the specified directories are
+ already owned by the right user and group, files and directories below of them are left as-is, even if they do
+ not match what is requested. The innermost specified directories will have their access mode adjusted to the
+ what is specified in RuntimeDirectoryMode=, StateDirectoryMode=,
+ CacheDirectoryMode=, LogsDirectoryMode= and
+ ConfigurationDirectoryMode=.
+
+ Except in case of ConfigurationDirectory=, these options imply
+ ReadWritePaths= for the specified paths. When combined with
+ RootDirectory= or RootImage= these paths always reside on the host and
+ are mounted from there into the unit's file system namespace. If DynamicUser= is used in
+ conjunction with RuntimeDirectory=, StateDirectory=,
+ CacheDirectory= and LogsDirectory=, the behaviour of these options is
+ slightly altered: the directories are created below /run/private,
+ /var/lib/private, /var/cache/private and
+ /var/log/private, respectively, which are host directories made inaccessible to
+ unprivileged users, which ensures that access to these directories cannot be gained through dynamic user ID
+ recycling. Symbolic links are created to hide this difference in behaviour. Both from perspective of the host
+ and from inside the unit, the relevant directories hence always appear directly below
+ /run, /var/lib, /var/cache and
+ /var/log.
+
+ Use RuntimeDirectory= to manage one or more runtime directories for the unit and bind
+ their lifetime to the daemon runtime. This is particularly useful for unprivileged daemons that cannot create
runtime directories in /run due to lack of privileges, and to make sure the runtime
- directory is cleaned up automatically after use. For runtime directories that require more complex or
- different configuration or lifetime guarantees, please consider using
+ directory is cleaned up automatically after use. For runtime directories that require more complex or different
+ configuration or lifetime guarantees, please consider using
tmpfiles.d5.Example: if a system service unit has the following,
@@ -1779,22 +1817,7 @@ CapabilityBoundingSet=~CAP_B CAP_C
except /run/foo are owned by the user and group specified in User= and
Group=, and removed when the service is stopped.
-
-
- StateDirectory=
- CacheDirectory=
- LogsDirectory=
- ConfigurationDirectory=
-
- Takes a whitespace-separated list of directory names. If set, as similar to
- RuntimeDirectory=, one or more directories including their parents by the specified names
- will be created below /var/lib, /var/cache, /var/log,
- or /etc, respectively, when the unit is started.
- Unlike RuntimeDirectory=, the directories are not removed when the unit is stopped.
- The lowest subdirectories will be owned by the user and group specified in User=
- and Group=. The options imply ReadWritePaths=.
-