]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - man/systemd.exec.xml
fs-util: rename path_is_safe() → path_is_normalized()
[thirdparty/systemd.git] / man / systemd.exec.xml
index 53daff0f641309d1493aeb86d9b20d83ba9bd9ff..d043555860ac83c3d3f87b8298b3e64a0760ec08 100644 (file)
         enabled for a unit, the name of the dynamic user/group is implicitly derived from the unit name. If the unit
         name without the type suffix qualifies as valid user name it is used directly, otherwise a name incorporating a
         hash of it is used. If a statically allocated user or group of the configured name already exists, it is used
-        and no dynamic user/group is allocated. Dynamic users/groups are allocated from the UID/GID range
+        and no dynamic user/group is allocated. Note that if <varname>User=</varname> is specified and the static group
+        with the name exists, then it is required that the static user with the name already exists. Similarly,
+        if <varname>Group=</varname> is specified and the static user with the name exists, then it is required that
+        the static group with the name already exists. Dynamic users/groups are allocated from the UID/GID range
         61184…65519. It is recommended to avoid this range for regular system or login users.  At any point in time
         each UID/GID from this range is only assigned to zero or one dynamically allocated users/groups in
         use. However, UID/GIDs are recycled after a unit is terminated. Care should be taken that any processes running
         cannot leave files around after unit termination. Moreover <varname>ProtectSystem=strict</varname> and
         <varname>ProtectHome=read-only</varname> 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 <varname>ReadWritePaths=</varname>, but care must be taken so that UID/GID recycling doesn't
-        create security issues involving files created by the service. Use <varname>RuntimeDirectory=</varname> (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.</para></listitem>
+        using <varname>ReadWritePaths=</varname>, but care must be taken so that UID/GID recycling doesn't create
+        security issues involving files created by the service. Use <varname>RuntimeDirectory=</varname> (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 <varname>StateDirectory=</varname>,
+        <varname>CacheDirectory=</varname> and <varname>LogsDirectory=</varname> 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.</para></listitem>
       </varlistentry>
 
       <varlistentry>
 
         <para>If the standard output (or error output, see below) of a unit is connected to the journal, syslog or the
         kernel log buffer, the unit will implicitly gain a dependency of type <varname>After=</varname> on
-        <filename>systemd-journald.socket</filename> (also see the "Implicit Dependencies" section above).</para>
+        <filename>systemd-journald.socket</filename> (also see the "Implicit Dependencies" section above). Also note
+        that in this case stdout (or stderr, see below) will be an <constant>AF_UNIX</constant> stream socket, and not
+        a pipe or FIFO that can be re-opened. This means when executing shell scripts the construct <command>echo
+        "hello" &gt; /dev/stderr</command> for writing text to stderr will not work. To mitigate this use the construct
+        <command>echo "hello" >&amp;2</command> instead, which is mostly equivalent and avoids this pitfall.</para>
 
         <para>This setting defaults to the value set with
-        <option>DefaultStandardOutput=</option> in
+        <varname>DefaultStandardOutput=</varname> in
         <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
         which defaults to <option>journal</option>. Note that setting
         this parameter might result in additional dependencies to be
-        added to the unit (see above).</para></listitem>
+        added to the unit (see above).</para>
+      </listitem>
       </varlistentry>
 
       <varlistentry>
         <literal>stderr</literal>.</para>
 
         <para>This setting defaults to the value set with
-        <option>DefaultStandardError=</option> in
+        <varname>DefaultStandardError=</varname> in
         <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
         which defaults to <option>inherit</option>. Note that setting
         this parameter might result in additional dependencies to be
         that the screen and scrollback buffer is cleared. Defaults to
         <literal>no</literal>.</para></listitem>
       </varlistentry>
+
       <varlistentry>
         <term><varname>SyslogIdentifier=</varname></term>
-        <listitem><para>Sets the process name to prefix log lines sent
-        to the logging system or the kernel log buffer with. If not
-        set, defaults to the process name of the executed process.
-        This option is only useful when
-        <varname>StandardOutput=</varname> or
-        <varname>StandardError=</varname> are set to
-        <option>syslog</option>, <option>journal</option> or
-        <option>kmsg</option> (or to the same settings in combination
-        with <option>+console</option>).</para></listitem>
+        <listitem><para>Sets the process name ("<command>syslog</command> tag") to prefix log lines sent to the logging
+        system or the kernel log buffer with. If not set, defaults to the process name of the executed process.  This
+        option is only useful when <varname>StandardOutput=</varname> or <varname>StandardError=</varname> are set to
+        <option>journal</option>, <option>syslog</option> or <option>kmsg</option> (or to the same settings in
+        combination with <option>+console</option>) and only applies to log messages written to stdout or
+        stderr.</para></listitem>
       </varlistentry>
+
       <varlistentry>
         <term><varname>SyslogFacility=</varname></term>
-        <listitem><para>Sets the syslog facility to use when logging
-        to syslog. One of <option>kern</option>,
-        <option>user</option>, <option>mail</option>,
-        <option>daemon</option>, <option>auth</option>,
-        <option>syslog</option>, <option>lpr</option>,
-        <option>news</option>, <option>uucp</option>,
-        <option>cron</option>, <option>authpriv</option>,
-        <option>ftp</option>, <option>local0</option>,
-        <option>local1</option>, <option>local2</option>,
-        <option>local3</option>, <option>local4</option>,
-        <option>local5</option>, <option>local6</option> or
-        <option>local7</option>. See
+        <listitem><para>Sets the <command>syslog</command> facility identifier to use when logging. One of
+        <option>kern</option>, <option>user</option>, <option>mail</option>, <option>daemon</option>,
+        <option>auth</option>, <option>syslog</option>, <option>lpr</option>, <option>news</option>,
+        <option>uucp</option>, <option>cron</option>, <option>authpriv</option>, <option>ftp</option>,
+        <option>local0</option>, <option>local1</option>, <option>local2</option>, <option>local3</option>,
+        <option>local4</option>, <option>local5</option>, <option>local6</option> or <option>local7</option>. See
         <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-        for details. This option is only useful when
-        <varname>StandardOutput=</varname> or
-        <varname>StandardError=</varname> are set to
-        <option>syslog</option>. Defaults to
-        <option>daemon</option>.</para></listitem>
+        for details. This option is only useful when <varname>StandardOutput=</varname> or
+        <varname>StandardError=</varname> are set to <option>journal</option>, <option>syslog</option> or
+        <option>kmsg</option> (or to the same settings in combination with <option>+console</option>), and only applies
+        to log messages written to stdout or stderr. Defaults to <option>daemon</option>.</para></listitem>
       </varlistentry>
+
       <varlistentry>
         <term><varname>SyslogLevel=</varname></term>
-        <listitem><para>The default syslog level to use when logging to
-        syslog or the kernel log buffer. One of
-        <option>emerg</option>,
-        <option>alert</option>,
-        <option>crit</option>,
-        <option>err</option>,
-        <option>warning</option>,
-        <option>notice</option>,
-        <option>info</option>,
-        <option>debug</option>. See
-        <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-        for details. This option is only useful when
-        <varname>StandardOutput=</varname> or
-        <varname>StandardError=</varname> are set to
-        <option>syslog</option> or <option>kmsg</option>. Note that
-        individual lines output by the daemon might be prefixed with a
-        different log level which can be used to override the default
-        log level specified here. The interpretation of these prefixes
-        may be disabled with <varname>SyslogLevelPrefix=</varname>,
-        see below. For details, see
-        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+        <listitem><para>The default <command>syslog</command> log level to use when logging to the logging system or
+        the kernel log buffer. One of <option>emerg</option>, <option>alert</option>, <option>crit</option>,
+        <option>err</option>, <option>warning</option>, <option>notice</option>, <option>info</option>,
+        <option>debug</option>. See <citerefentry
+        project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> for
+        details. This option is only useful when <varname>StandardOutput=</varname> or
+        <varname>StandardError=</varname> are set to <option>journal</option>, <option>syslog</option> or
+        <option>kmsg</option> (or to the same settings in combination with <option>+console</option>), and only applies
+        to log messages written to stdout or stderr. Note that individual lines output by executed processes may be
+        prefixed with a different log level which can be used to override the default log level specified here. The
+        interpretation of these prefixes may be disabled with <varname>SyslogLevelPrefix=</varname>, see below. For
+        details, see <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
 
-        Defaults to
-        <option>info</option>.</para></listitem>
+        Defaults to <option>info</option>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>SyslogLevelPrefix=</varname></term>
-        <listitem><para>Takes a boolean argument. If true and
-        <varname>StandardOutput=</varname> or
-        <varname>StandardError=</varname> are set to
-        <option>syslog</option>, <option>kmsg</option> or
-        <option>journal</option>, log lines written by the executed
-        process that are prefixed with a log level will be passed on
-        to syslog with this log level set but the prefix removed. If
-        set to false, the interpretation of these prefixes is disabled
-        and the logged lines are passed on as-is. For details about
-        this prefixing see
-        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
-        Defaults to true.</para></listitem>
+        <listitem><para>Takes a boolean argument. If true and <varname>StandardOutput=</varname> or
+        <varname>StandardError=</varname> are set to <option>journal</option>, <option>syslog</option> or
+        <option>kmsg</option> (or to the same settings in combination with <option>+console</option>), log lines
+        written by the executed process that are prefixed with a log level will be processed with this log level set
+        but the prefix removed. If set to false, the interpretation of these prefixes is disabled and the logged lines
+        are passed on as-is. This only applies to log messages written to stdout or stderr.  For details
+        about this prefixing see
+        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.  Defaults to
+        true.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>LogLevelMax=</varname></term>
+        <listitem><para>Configures filtering by log level of log messages generated by this unit. Takes a
+        <command>syslog</command> log level, one of <option>emerg</option> (lowest log level, only highest priority
+        messages), <option>alert</option>, <option>crit</option>, <option>err</option>, <option>warning</option>,
+        <option>notice</option>, <option>info</option>, <option>debug</option> (highest log level, also lowest priority
+        messages). See <citerefentry
+        project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> for
+        details. By default no filtering is applied (i.e. the default maximum log level is <option>debug</option>). Use
+        this option to configure the logging system to drop log messages of a specific service above the specified
+        level. For example, set <varname>LogLevelMax=</varname><option>info</option> in order to turn off debug logging
+        of a particularly chatty unit. Note that the the configured level is applied to any log messages written by any
+        of the processes belonging to this unit, sent via any supported logging protocol. The filtering is applied
+        early in the logging pipeline, before any kind of further processing is done. Moreover, messages which pass
+        through this filter successfully might still be dropped by filters applied at a later stage in the logging
+        subsystem. For example, <varname>MaxLevelStore=</varname> configured in
+        <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> might
+        prohibit messages of higher log levels to be stored on disk, even though the per-unit
+        <varname>LogLevelMax=</varname> permitted it to be processed.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>LogExtraFields=</varname></term>
+        <listitem><para>Configures additional log metadata fields to include in all log records generated by processes
+        associated with this unit. This setting takes one or more journal field assignments in the format
+        <literal>FIELD=VALUE</literal> separated by whitespace. See
+        <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+        details on the journal field concept. Even though the underlying journal implementation permits binary field
+        values, this setting accepts only valid UTF-8 values. To include space characters in a journal field value,
+        enclose the assignment in double quotes ("). The usual specifiers are expanded in all assignments (see
+        below). Note that this setting is not only useful for attaching additional metadata to log records of a unit,
+        but given that all fields and values are indexed may also be used to implement cross-unit log record
+        matching. Assign an empty string to reset the list.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <citerefentry><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry> for details on
         the resource limit concept. Resource limits may be specified in two formats: either as single value to set a
         specific soft and hard limit to the same value, or as colon-separated pair <option>soft:hard</option> to set
-        both limits individually (e.g. <literal>LimitAS=4G:16G</literal>).  Use the string <varname>infinity</varname>
+        both limits individually (e.g. <literal>LimitAS=4G:16G</literal>).  Use the string <option>infinity</option>
         to configure no limit on a specific resource. The multiplicative suffixes K, M, G, T, P and E (to the base
         1024) may be used for resource limits measured in bytes (e.g. LimitAS=16G). For the limits referring to time
         values, the usual time units ms, s, min, h and so on may be used (see
         <para>Note that for each unit making use of this option a PAM session handler process will be maintained as
         part of the unit and stays around as long as the unit is active, to ensure that appropriate actions can be
         taken when the unit and hence the PAM session terminates. This process is named <literal>(sd-pam)</literal> and
-        is an immediate child process of the unit's main process.</para></listitem>
+        is an immediate child process of the unit's main process.</para>
+
+        <para>Note that when this option is used for a unit it is very likely (depending on PAM configuration) that the
+        main unit process will be migrated to its own session scope unit when it is activated. This process will hence
+        be associated with two units: the unit it was originally started from (and for which
+        <varname>PAMName=</varname> was configured), and the session scope unit. Any child processes of that process
+        will however be associated with the session scope unit only. This has implications when used in combination
+        with <varname>NotifyAccess=</varname><option>all</option>, as these child processes will not be able to affect
+        changes in the original unit through notification messages. These messages will be considered belonging to the
+        session scope unit and not the original unit. It is hence not recommended to use <varname>PAMName=</varname> in
+        combination with <varname>NotifyAccess=</varname><option>all</option>.</para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
@@ -1421,7 +1458,12 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         executed by the unit processes except for the listed ones will result in immediate process termination with the
         <constant>SIGSYS</constant> signal (whitelisting). If the first character of the list is <literal>~</literal>,
         the effect is inverted: only the listed system calls will result in immediate process termination
-        (blacklisting). If running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant>
+        (blacklisting). Blacklisted system calls and system call groups may optionally be suffixed with a colon
+        (<literal>:</literal>) and <literal>errno</literal> error number (between 0 and 4095) or errno name such as
+        <constant>EPERM</constant>, <constant>EACCES</constant> or <constant>EUCLEAN</constant>. This value will be
+        returned when a blacklisted system call is triggered, instead of terminating the processes immediately.
+        This value takes precedence over the one given in <varname>SystemCallErrorNumber=</varname>.
+        If running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant>
         capability (e.g. setting <varname>User=nobody</varname>), <varname>NoNewPrivileges=yes</varname> is
         implied. This feature makes use of the Secure Computing Mode 2 interfaces of the kernel ('seccomp filtering')
         and is useful for enforcing a minimal sandboxing environment. Note that the <function>execve</function>,
@@ -1476,10 +1518,18 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
               </row>
             </thead>
             <tbody>
+              <row>
+                <entry>@aio</entry>
+                <entry>Asynchronous I/O (<citerefentry project='man-pages'><refentrytitle>io_setup</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>io_submit</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
+              </row>
               <row>
                 <entry>@basic-io</entry>
                 <entry>System calls for basic I/O: reading, writing, seeking, file descriptor duplication and closing (<citerefentry project='man-pages'><refentrytitle>read</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>write</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
               </row>
+              <row>
+                <entry>@chown</entry>
+                <entry>Changing file ownership (<citerefentry project='man-pages'><refentrytitle>chown</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>fchownat</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
+              </row>
               <row>
                 <entry>@clock</entry>
                 <entry>System calls for changing the system clock (<citerefentry project='man-pages'><refentrytitle>adjtimex</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>settimeofday</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
@@ -1488,10 +1538,6 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
                 <entry>@cpu-emulation</entry>
                 <entry>System calls for CPU emulation functionality (<citerefentry project='man-pages'><refentrytitle>vm86</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
               </row>
-              <row>
-                <entry>@credentials</entry>
-                <entry>System calls for querying process credentials (<citerefentry project='man-pages'><refentrytitle>getuid</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>capget</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
-              </row>
               <row>
                 <entry>@debug</entry>
                 <entry>Debugging, performance monitoring and tracing functionality (<citerefentry project='man-pages'><refentrytitle>ptrace</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>perf_event_open</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
@@ -1564,6 +1610,10 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
                 <entry>@swap</entry>
                 <entry>System calls for enabling/disabling swap devices (<citerefentry project='man-pages'><refentrytitle>swapon</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>swapoff</refentrytitle><manvolnum>2</manvolnum></citerefentry>)</entry>
               </row>
+              <row>
+                <entry>@sync</entry>
+                <entry>Synchronizing files and memory to disk: (<citerefentry project='man-pages'><refentrytitle>fsync</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>msync</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
+              </row>
               <row>
                 <entry>@timer</entry>
                 <entry>System calls for scheduling operations by time (<citerefentry project='man-pages'><refentrytitle>alarm</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>timer_create</refentrytitle><manvolnum>2</manvolnum></citerefentry>, …)</entry>
@@ -1592,15 +1642,11 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
       <varlistentry>
         <term><varname>SystemCallErrorNumber=</varname></term>
 
-        <listitem><para>Takes an <literal>errno</literal> error number
-        name to return when the system call filter configured with
-        <varname>SystemCallFilter=</varname> is triggered, instead of
-        terminating the process immediately. Takes an error name such
-        as <constant>EPERM</constant>, <constant>EACCES</constant> or
-        <constant>EUCLEAN</constant>. When this setting is not used,
-        or when the empty string is assigned, the process will be
-        terminated immediately when the filter is
-        triggered.</para></listitem>
+        <listitem><para>Takes an <literal>errno</literal> error number (between 1 and 4095) or errno name such as
+        <constant>EPERM</constant>, <constant>EACCES</constant> or <constant>EUCLEAN</constant>, to return when the
+        system call filter configured with <varname>SystemCallFilter=</varname> is triggered, instead of terminating
+        the process immediately. When this setting is not used, or when the empty string is assigned, the process
+        will be terminated immediately when the filter is triggered.</para></listitem>
       </varlistentry>
 
       <varlistentry>
@@ -1720,25 +1766,78 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         <varname>NoNewPrivileges=yes</varname> is implied.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>KeyringMode=</varname></term>
+
+        <listitem><para>Controls how the kernel session keyring is set up for the service (see <citerefentry
+        project='man-pages'><refentrytitle>session-keyring</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+        details on the session keyring). Takes one of <option>inherit</option>, <option>private</option>,
+        <option>shared</option>. If set to <option>inherit</option> no special keyring setup is done, and the kernel's
+        default behaviour is applied. If <option>private</option> is used a new session keyring is allocated when a
+        service process is invoked, and it is not linked up with any user keyring. This is the recommended setting for
+        system services, as this ensures that multiple services running under the same system user ID (in particular
+        the root user) do not share their key material among each other. If <option>shared</option> is used a new
+        session keyring is allocated as for <option>private</option>, but the user keyring of the user configured with
+        <varname>User=</varname> is linked into it, so that keys assigned to the user may be requested by the unit's
+        processes. In this modes multiple units running processes under the same user ID may share key material. Unless
+        <option>inherit</option> is selected the unique invocation ID for the unit (see below) is added as a protected
+        key by the name <literal>invocation_id</literal> to the newly created session keyring. Defaults to
+        <option>private</option> for the system service manager and to <option>inherit</option> for the user service
+        manager.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>RuntimeDirectory=</varname></term>
+        <term><varname>StateDirectory=</varname></term>
+        <term><varname>CacheDirectory=</varname></term>
+        <term><varname>LogsDirectory=</varname></term>
+        <term><varname>ConfigurationDirectory=</varname></term>
 
-        <listitem><para>Takes a whitespace-separated list of directory names. The specified directory names must be
-        relative, and may not include <literal>.</literal> or <literal>..</literal>. If set, one or more directories
-        including their parents by the specified names will be created below <filename>/run</filename> (for system
-        services) or below <varname>$XDG_RUNTIME_DIR</varname> (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
-        <varname>RuntimeDirectoryPreserve=</varname> is configured to <option>restart</option> or <option>yes</option>.
-        The lowest subdirectories will have the access mode specified in <varname>RuntimeDirectoryMode=</varname>,
-        and be owned by the user and group specified in <varname>User=</varname> and <varname>Group=</varname>.
-        This implies <varname>ReadWritePaths=</varname>, that is, the directories specified
-        in this option are accessible with the access mode specified in <varname>RuntimeDirectoryMode=</varname>
-        even if <varname>ProtectSystem=</varname> is set to <option>strict</option>.
-        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
+        <listitem><para>These options take a whitespace-separated list of directory names. The specified directory
+        names must be relative, and may not include <literal>.</literal> or <literal>..</literal>. If set, one or more
+        directories by the specified names will be created (including their parents) below <filename>/run</filename>
+        (or <varname>$XDG_RUNTIME_DIR</varname> for user services), <filename>/var/lib</filename> (or
+        <varname>$XDG_CONFIG_HOME</varname> for user services), <filename>/var/cache</filename> (or
+        <varname>$XDG_CACHE_HOME</varname> for user services), <filename>/var/log</filename> (or
+        <varname>$XDG_CONFIG_HOME</varname><filename>/log</filename> for user services), or <filename>/etc</filename>
+        (or <varname>$XDG_CONFIG_HOME</varname> for user services), respectively, when the unit is started.</para>
+
+        <para>In case of <varname>RuntimeDirectory=</varname> the lowest subdirectories are removed when the unit is
+        stopped. It is possible to preserve the specified directories in this case if
+        <varname>RuntimeDirectoryPreserve=</varname> is configured to <option>restart</option> or <option>yes</option>
+        (see below). The directories specified with <varname>StateDirectory=</varname>,
+        <varname>CacheDirectory=</varname>, <varname>LogsDirectory=</varname>,
+        <varname>ConfigurationDirectory=</varname> are not removed when the unit is stopped.</para>
+
+        <para>Except in case of <varname>ConfigurationDirectory=</varname>, the innermost specified directories will be
+        owned by the user and group specified in <varname>User=</varname> and <varname>Group=</varname>. 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 <varname>RuntimeDirectoryMode=</varname>, <varname>StateDirectoryMode=</varname>,
+        <varname>CacheDirectoryMode=</varname>, <varname>LogsDirectoryMode=</varname> and
+        <varname>ConfigurationDirectoryMode=</varname>.</para>
+
+        <para>These options imply <varname>BindPaths=</varname> for the specified paths. When combined with
+        <varname>RootDirectory=</varname> or <varname>RootImage=</varname> these paths always reside on the host and
+        are mounted from there into the unit's file system namespace.</para>
+
+        <para>If <varname>DynamicUser=</varname> is used in conjunction with <varname>StateDirectory=</varname>,
+        <varname>CacheDirectory=</varname> and <varname>LogsDirectory=</varname> is slightly altered: the directories
+        are created below <filename>/var/lib/private</filename>, <filename>/var/cache/private</filename> and
+        <filename>/var/log/private</filename>, 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
+        <filename>/var/lib</filename>, <filename>/var/cache</filename> and <filename>/var/log</filename>.</para>
+
+        <para>Use <varname>RuntimeDirectory=</varname> 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 <filename>/run</filename> 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
         <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
 
         <para>Example: if a system service unit has the following,
@@ -1748,22 +1847,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         except <filename>/run/foo</filename> are owned by the user and group specified in <varname>User=</varname> and
         <varname>Group=</varname>, and removed when the service is stopped.
         </para></listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><varname>StateDirectory=</varname></term>
-        <term><varname>CacheDirectory=</varname></term>
-        <term><varname>LogsDirectory=</varname></term>
-        <term><varname>ConfigurationDirectory=</varname></term>
 
-        <listitem><para>Takes a whitespace-separated list of directory names. If set, as similar to
-        <varname>RuntimeDirectory=</varname>, one or more directories including their parents by the specified names
-        will be created below <filename>/var/lib</filename>, <filename>/var/cache</filename>, <filename>/var/log</filename>,
-        or <filename>/etc</filename>, respectively, when the unit is started.
-        Unlike <varname>RuntimeDirectory=</varname>, the directories are not removed when the unit is stopped.
-        The lowest subdirectories will be owned by the user and group specified in <varname>User=</varname>
-        and <varname>Group=</varname>. The options imply <varname>ReadWritePaths=</varname>.
-        </para></listitem>
       </varlistentry>
 
       <varlistentry>
@@ -1805,8 +1889,9 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         memory segments as executable are prohibited.  Specifically, a system call filter is added that rejects
         <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with both
         <constant>PROT_EXEC</constant> and <constant>PROT_WRITE</constant> set,
-        <citerefentry><refentrytitle>mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with
-        <constant>PROT_EXEC</constant> set and
+        <citerefentry><refentrytitle>mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+        or <citerefentry><refentrytitle>pkey_mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+        system calls with <constant>PROT_EXEC</constant> set and
         <citerefentry><refentrytitle>shmat</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with
         <constant>SHM_EXEC</constant> set. Note that this option is incompatible with programs and libraries that
         generate program code dynamically at runtime, including JIT execution engines, executable stacks, and code
@@ -2197,6 +2282,316 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
     </variablelist>
   </refsect1>
 
+  <refsect1>
+    <title>Process exit codes</title>
+
+    <para>When invoking a unit process the service manager possibly fails to apply the execution parameters configured
+    with the settings above. In that case the already created service process will exit with a non-zero exit code
+    before the configured command line is executed. (Or in other words, the child process possibly exits with these
+    error codes, after having been created by the <citerefentry
+    project='man-pages'><refentrytitle>fork</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call, but
+    before the matching <citerefentry
+    project='man-pages'><refentrytitle>execve</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call is
+    called.) Specifically, exit codes defined by the C library, by the LSB specification and by the systemd service
+    manager itself are used.</para>
+
+    <para>The following basic service exit codes are defined by the C library.</para>
+
+    <table>
+      <title>Basic C library exit codes</title>
+      <tgroup cols='3'>
+        <thead>
+          <row>
+            <entry>Exit Code</entry>
+            <entry>Symbolic Name</entry>
+            <entry>Description</entry>
+          </row>
+        </thead>
+        <tbody>
+          <row>
+            <entry>0</entry>
+            <entry><constant>EXIT_SUCCESS</constant></entry>
+            <entry>Generic success code.</entry>
+          </row>
+          <row>
+            <entry>1</entry>
+            <entry><constant>EXIT_FAILURE</constant></entry>
+            <entry>Generic failure or unspecified error.</entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+
+    <para>The following service exit codes are defined by the <ulink
+    url="https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB specification
+    </ulink>.
+    </para>
+
+    <table>
+      <title>LSB service exit codes</title>
+      <tgroup cols='3'>
+        <thead>
+          <row>
+            <entry>Exit Code</entry>
+            <entry>Symbolic Name</entry>
+            <entry>Description</entry>
+          </row>
+        </thead>
+        <tbody>
+          <row>
+            <entry>2</entry>
+            <entry><constant>EXIT_INVALIDARGUMENT</constant></entry>
+            <entry>Invalid or excess arguments.</entry>
+          </row>
+          <row>
+            <entry>3</entry>
+            <entry><constant>EXIT_NOTIMPLEMENTED</constant></entry>
+            <entry>Unimplemented feature.</entry>
+          </row>
+          <row>
+            <entry>4</entry>
+            <entry><constant>EXIT_NOPERMISSION</constant></entry>
+            <entry>The user has insufficient privileges.</entry>
+          </row>
+          <row>
+            <entry>5</entry>
+            <entry><constant>EXIT_NOTINSTALLED</constant></entry>
+            <entry>The program is not installed.</entry>
+          </row>
+          <row>
+            <entry>6</entry>
+            <entry><constant>EXIT_NOTCONFIGURED</constant></entry>
+            <entry>The program is not configured.</entry>
+          </row>
+          <row>
+            <entry>7</entry>
+            <entry><constant>EXIT_NOTRUNNING</constant></entry>
+            <entry>The program is not running.</entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+
+    <para>
+      The LSB specification suggests that error codes 200 and above are reserved for implementations. Some of them are
+      used by the service manager to indicate problems during process invocation:
+    </para>
+    <table>
+      <title>systemd-specific exit codes</title>
+      <tgroup cols='3'>
+        <thead>
+          <row>
+            <entry>Exit Code</entry>
+            <entry>Symbolic Name</entry>
+            <entry>Description</entry>
+          </row>
+        </thead>
+        <tbody>
+          <row>
+            <entry>200</entry>
+            <entry><constant>EXIT_CHDIR</constant></entry>
+            <entry>Changing to the requested working directory failed. See <varname>WorkingDirectory=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>201</entry>
+            <entry><constant>EXIT_NICE</constant></entry>
+            <entry>Failed to set up process scheduling priority (nice level). See <varname>Nice=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>202</entry>
+            <entry><constant>EXIT_FDS</constant></entry>
+            <entry>Failed to close unwanted file descriptors, or to adjust passed file descriptors.</entry>
+          </row>
+          <row>
+            <entry>203</entry>
+            <entry><constant>EXIT_EXEC</constant></entry>
+            <entry>The actual process execution failed (specifically, the <citerefentry project='man-pages'><refentrytitle>execve</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call). Most likely this is caused by a missing or non-accessible executable file.</entry>
+          </row>
+          <row>
+            <entry>204</entry>
+            <entry><constant>EXIT_MEMORY</constant></entry>
+            <entry>Failed to perform an action due to memory shortage.</entry>
+          </row>
+          <row>
+            <entry>205</entry>
+            <entry><constant>EXIT_LIMITS</constant></entry>
+            <entry>Failed to adjust resource limits. See <varname>LimitCPU=</varname> and related settings above.</entry>
+          </row>
+          <row>
+            <entry>206</entry>
+            <entry><constant>EXIT_OOM_ADJUST</constant></entry>
+            <entry>Failed to adjust the OOM setting. See <varname>OOMScoreAdjust=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>207</entry>
+            <entry><constant>EXIT_SIGNAL_MASK</constant></entry>
+            <entry>Failed to set process signal mask.</entry>
+          </row>
+          <row>
+            <entry>208</entry>
+            <entry><constant>EXIT_STDIN</constant></entry>
+            <entry>Failed to set up standard input. See <varname>StandardInput=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>209</entry>
+            <entry><constant>EXIT_STDOUT</constant></entry>
+            <entry>Failed to set up standard output. See <varname>StandardOutput=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>210</entry>
+            <entry><constant>EXIT_CHROOT</constant></entry>
+            <entry>Failed to change root directory (<citerefentry project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>). See <varname>RootDirectory=</varname>/<varname>RootImage=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>211</entry>
+            <entry><constant>EXIT_IOPRIO</constant></entry>
+            <entry>Failed to set up IO scheduling priority. See <varname>IOSchedulingClass=</varname>/<varname>IOSchedulingPriority=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>212</entry>
+            <entry><constant>EXIT_TIMERSLACK</constant></entry>
+            <entry>Failed to set up timer slack. See <varname>TimerSlackNSec=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>213</entry>
+            <entry><constant>EXIT_SECUREBITS</constant></entry>
+            <entry>Failed to set process secure bits. See <varname>SecureBits=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>214</entry>
+            <entry><constant>EXIT_SETSCHEDULER</constant></entry>
+            <entry>Failed to set up CPU scheduling. See <varname>CPUSchedulingPolicy=</varname>/<varname>CPUSchedulingPriority=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>215</entry>
+            <entry><constant>EXIT_CPUAFFINITY</constant></entry>
+            <entry>Failed to set up CPU affinity. See <varname>CPUAffinity=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>216</entry>
+            <entry><constant>EXIT_GROUP</constant></entry>
+            <entry>Failed to determine or change group credentials. See <varname>Group=</varname>/<varname>SupplementaryGroups=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>217</entry>
+            <entry><constant>EXIT_USER</constant></entry>
+            <entry>Failed to determine or change user credentials, or to set up user namespacing. See <varname>User=</varname>/<varname>PrivateUsers=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>218</entry>
+            <entry><constant>EXIT_CAPABILITIES</constant></entry>
+            <entry>Failed to drop capabilities, or apply ambient capabilities. See <varname>CapabilityBoundingSet=</varname>/<varname>AmbientCapabilities=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>219</entry>
+            <entry><constant>EXIT_CGROUP</constant></entry>
+            <entry>Setting up the service control group failed.</entry>
+          </row>
+          <row>
+            <entry>220</entry>
+            <entry><constant>EXIT_SETSID</constant></entry>
+            <entry>Failed to create new process session.</entry>
+          </row>
+          <row>
+            <entry>221</entry>
+            <entry><constant>EXIT_CONFIRM</constant></entry>
+            <entry>Execution has been cancelled by the user. See the <varname>systemd.confirm_spawn=</varname> kernel command line setting on <citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details.</entry>
+          </row>
+          <row>
+            <entry>222</entry>
+            <entry><constant>EXIT_STDERR</constant></entry>
+            <entry>Failed to set up standard error output. See <varname>StandardError=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>224</entry>
+            <entry><constant>EXIT_PAM</constant></entry>
+            <entry>Failed to set up PAM session. See <varname>PAMName=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>225</entry>
+            <entry><constant>EXIT_NETWORK</constant></entry>
+            <entry>Failed to set up network namespacing. See <varname>PrivateNetwork=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>226</entry>
+            <entry><constant>EXIT_NAMESPACE</constant></entry>
+            <entry>Failed to set up mount namespacing. See <varname>ReadOnlyPaths=</varname> and related settings above.</entry>
+          </row>
+          <row>
+            <entry>227</entry>
+            <entry><constant>EXIT_NO_NEW_PRIVILEGES</constant></entry>
+            <entry>Failed to disable new privileges. See <varname>NoNewPrivileges=yes</varname> above.</entry>
+          </row>
+          <row>
+            <entry>228</entry>
+            <entry><constant>EXIT_SECCOMP</constant></entry>
+            <entry>Failed to apply system call filters. See <varname>SystemCallFilter=</varname> and related settings above.</entry>
+          </row>
+          <row>
+            <entry>229</entry>
+            <entry><constant>EXIT_SELINUX_CONTEXT</constant></entry>
+            <entry>Determining or changing SELinux context failed. See <varname>SELinuxContext=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>230</entry>
+            <entry><constant>EXIT_PERSONALITY</constant></entry>
+            <entry>Failed to set up an execution domain (personality). See <varname>Personality=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>231</entry>
+            <entry><constant>EXIT_APPARMOR_PROFILE</constant></entry>
+            <entry>Failed to prepare changing AppArmor profile. See <varname>AppArmorProfile=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>232</entry>
+            <entry><constant>EXIT_ADDRESS_FAMILIES</constant></entry>
+            <entry>Failed to restrict address families. See <varname>RestrictAddressFamilies=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>233</entry>
+            <entry><constant>EXIT_RUNTIME_DIRECTORY</constant></entry>
+            <entry>Setting up runtime directory failed. See <varname>RuntimeDirectory=</varname> and related settings above.</entry>
+          </row>
+          <row>
+            <entry>235</entry>
+            <entry><constant>EXIT_CHOWN</constant></entry>
+            <entry>Failed to adjust socket ownership. Used for socket units only.</entry>
+          </row>
+          <row>
+            <entry>236</entry>
+            <entry><constant>EXIT_SMACK_PROCESS_LABEL</constant></entry>
+            <entry>Failed to set SMACK label. See <varname>SmackProcessLabel=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>237</entry>
+            <entry><constant>EXIT_KEYRING</constant></entry>
+            <entry>Failed to set up kernel keyring.</entry>
+          </row>
+          <row>
+            <entry>238</entry>
+            <entry><constant>EXIT_STATE_DIRECTORY</constant></entry>
+            <entry>Failed to set up unit's state directory. See <varname>StateDirectory=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>239</entry>
+            <entry><constant>EXIT_CACHE_DIRECTORY</constant></entry>
+            <entry>Failed to set up unit's cache directory. See <varname>CacheDirectory=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>240</entry>
+            <entry><constant>EXIT_LOGS_DIRECTORY</constant></entry>
+            <entry>Failed to set up unit's logging directory. See <varname>LogsDirectory=</varname> above.</entry>
+          </row>
+          <row>
+            <entry>241</entry>
+            <entry><constant>EXIT_CONFIGURATION_DIRECTORY</constant></entry>
+            <entry>Failed to set up unit's configuration directory. See <varname>ConfigurationDirectory=</varname> above.</entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
   <refsect1>
       <title>See Also</title>
       <para>