]> git.proxmox.com Git - systemd.git/commitdiff
New upstream version 251.4
authorMichael Biebl <biebl@debian.org>
Sat, 13 Aug 2022 14:36:57 +0000 (16:36 +0200)
committerMichael Biebl <biebl@debian.org>
Sat, 13 Aug 2022 14:36:57 +0000 (16:36 +0200)
73 files changed:
man/journalctl.xml
man/os-release.xml
man/pam_systemd_home.xml
man/sd_notify.xml
man/system-or-user-ns.xml
man/systemctl.xml
man/systemd-creds.xml
man/systemd-integritysetup-generator.xml
man/systemd-sysctl.service.xml
man/systemd.exec.xml
man/systemd.mount.xml
man/systemd.netdev.xml
man/systemd.network.xml
man/sysupdate.d.xml
man/udevadm.xml
meson.build
src/basic/fd-util.c
src/basic/gcrypt-util.c
src/basic/missing_fs.h
src/basic/stat-util.c
src/basic/stat-util.h
src/basic/unit-file.c
src/basic/virt.c
src/boot/efi/meson.build
src/cgroups-agent/cgroups-agent.c
src/core/bpf/restrict_ifaces/restrict-ifaces.bpf.c
src/core/dbus.c
src/core/import-creds.c
src/core/main.c
src/core/mount.c
src/core/namespace.c
src/core/scope.c
src/coredump/coredump.c
src/home/homed-home-bus.c
src/home/homework-cifs.c
src/home/homework-luks.c
src/home/homework-mount.c
src/home/homework.h
src/import/pull-common.h
src/integritysetup/integritysetup.c
src/libsystemd-network/dhcp6-option.c
src/libsystemd-network/sd-dhcp6-lease.c
src/libsystemd-network/test-dhcp6-client.c
src/libsystemd/sd-bus/sd-bus.c
src/libsystemd/sd-device/device-internal.h
src/libsystemd/sd-device/device-monitor.c
src/libsystemd/sd-device/device-private.c
src/libsystemd/sd-device/device-private.h
src/libsystemd/sd-device/test-sd-device.c
src/locale/keymap-util.c
src/network/networkd-dhcp-common.c
src/network/networkd-dhcp4.c
src/network/networkd-dhcp6.c
src/network/networkd-link.c
src/network/networkd-ndisc.c
src/network/networkd-radv.c
src/partition/growfs.c
src/partition/repart.c
src/portable/profile/trusted/service.conf
src/resolve/resolved-dns-cache.c
src/resolve/resolved-dns-cache.h
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-transaction.c
src/resolve/resolved-dns-transaction.h
src/resolve/resolved-mdns.c
src/shared/base-filesystem.c
src/shared/mount-util.c
src/sleep/sleep.conf
src/systemctl/systemctl-util.c
src/systemd/_sd-common.h
src/tmpfiles/tmpfiles.c
src/udev/udevd.c
test/units/testsuite-67.sh

index 424acc9f163ebb2587ca1f92838ff9812aa75a48..e226663a51fa8b4ff07f2e25521b511706c98dcf 100644 (file)
 
         <listitem><para>If <replaceable>FILE</replaceable> exists and contains a
         cursor, start showing entries <emphasis>after</emphasis> this location.
-        Otherwise the show entries according the other given options. At the end,
+        Otherwise show entries according to the other given options. At the end,
         write the cursor of the last entry to <replaceable>FILE</replaceable>. Use
         this option to continually read the journal by sequentially calling
         <command>journalctl</command>.</para></listitem>
index 875ac946f04ed81a4108bf1919084fa02dbf436c..dd135d638fc5adf8297f1d9786a8bdf9e6e8597e 100644 (file)
           <listitem><para>Takes a space-separated list of one or more valid prefix match strings for the
           <ulink url="https://systemd.io/PORTABLE_SERVICES">Portable Services</ulink> logic. This field
           serves two purposes: it is informational, identifying portable service images as such (and thus
-          allowing them to be distinguished from other OS images, such as bootable system images). In is also
+          allowing them to be distinguished from other OS images, such as bootable system images). It is also
           used when a portable service image is attached: the specified or implied portable service prefix is
           checked against the list specified here, to enforce restrictions how images may be attached to a
           system.</para></listitem>
index 906d1c151695b84ac6f8f8d036bbb036a00668ee..9fa0e0a7e7c21ec1776599c552bf3e3a63090239 100644 (file)
@@ -17,8 +17,8 @@
 
   <refnamediv>
     <refname>pam_systemd_home</refname>
-    <refpurpose>Automatically mount home directories managed by <filename>systemd-homed.service</filename> on
-    login, and unmount them on logout</refpurpose>
+    <refpurpose>Authenticate users and mount home directories via <filename>systemd-homed.service</filename>
+    </refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
     <para><command>pam_systemd_home</command> ensures that home directories managed by
     <citerefentry><refentrytitle>systemd-homed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
     are automatically activated (mounted) on user login, and are deactivated (unmounted) when the last
-    session of the user ends.</para>
+    session of the user ends. For such users, it also provides authentication (when per-user disk encryption
+    is used, the disk encryption key is derived from the authentication credential supplied at login time),
+    account management (the <ulink url="https://systemd.io/USER_RECORD/">JSON user record</ulink> embedded in
+    the home store contains account details), and implements the updating of the encryption password (which
+    is also used for user authentication).</para>
   </refsect1>
 
   <refsect1>
   <refsect1>
     <title>Module Types Provided</title>
 
-    <para>The module provides all four management operations: <option>auth</option>, <option>account</option>,
-    <option>session</option>, <option>password</option>.</para>
+    <para>The module implements all four PAM operations: <option>auth</option> (reason: to allow
+    authentication using the encrypted data), <option>account</option> (reason: users with
+    <filename>systemd-homed.service</filename> user accounts are described in a <ulink
+    url="https://systemd.io/USER_RECORD/">JSON user record</ulink> and may be configured in more detail than
+    in the traditional Linux user database), <option>session</option> (user sessions must be tracked in order
+    to implement automatic release when the last session of the user is gone), <option>password</option> (to
+    change the encryption password â€” also used for user authentication â€” through PAM).</para>
   </refsect1>
 
   <refsect1>
index 4a0a7b34dc65593e381a8e9be835a267d3ca62d9..31388b9c3da762e6076cdb69c599aa66dfd25d60 100644 (file)
       <varlistentry>
         <term>BARRIER=1</term>
 
-        <listitem><para>Tells the service manager that the client is explicitly requesting synchronization by means of
-        closing the file descriptor sent with this command. The service manager guarantees that the processing of a <varname>
-        BARRIER=1</varname> command will only happen after all previous notification messages sent before this command
-        have been processed. Hence, this command accompanied with a single file descriptor can be used to synchronize
-        against reception of all previous status messages. Note that this command cannot be mixed with other notifications,
-        and has to be sent in a separate message to the service manager, otherwise all assignments will be ignored. Note that
-        sending 0 or more than 1 file descriptor with this command is a violation of the protocol.</para></listitem>
+        <listitem><para>Tells the service manager that the client is explicitly requesting synchronization by
+        means of closing the file descriptor sent with this command. The service manager guarantees that the
+        processing of a <varname>BARRIER=1</varname> command will only happen after all previous notification
+        messages sent before this command have been processed. Hence, this command accompanied with a single
+        file descriptor can be used to synchronize against reception of all previous status messages. Note
+        that this command cannot be mixed with other notifications, and has to be sent in a separate message
+        to the service manager, otherwise all assignments will be ignored. Note that sending 0 or more than 1
+        file descriptor with this command is a violation of the protocol.</para></listitem>
       </varlistentry>
     </variablelist>
 
 
     <para><function>sd_notify_barrier()</function> allows the caller to
     synchronize against reception of previously sent notification messages
-    and uses the <literal>BARRIER=1</literal> command. It takes a relative
+    and uses the <varname>BARRIER=1</varname> command. It takes a relative
     <varname>timeout</varname> value in microseconds which is passed to
     <citerefentry><refentrytitle>ppoll</refentrytitle><manvolnum>2</manvolnum>
     </citerefentry>. A value of UINT64_MAX is interpreted as infinite timeout.
index 01d1dd022ca022c6e5a2d7fb32f1484f9099d449..7a302d5980fe1be4189dd30258e0d7f95e60db96 100644 (file)
@@ -8,9 +8,9 @@
 <refsect1>
 
 <para id="singular">This option is only available for system services, or for services running in per-user
- instances of the service manager when unprivileged user namespaces are available.</para>
+ instances of the service manager when <varname>PrivateUsers=</varname> is enabled.</para>
 
 <para id="plural">These options are only available for system services, or for services running in per-user
- instances of the service manager when unprivileged user namespaces are available.</para>
+ instances of the service manager when <varname>PrivateUsers=</varname> is enabled.</para>
 
 </refsect1>
index b050030f822fee44dfa2fa7eb81a41c27d1494ca..64af0999a111dde15e7b93b07338a19e71628cba 100644 (file)
@@ -196,25 +196,24 @@ Sun 2017-02-26 20:57:49 EST  2h 3min left  Sun 2017-02-26 11:56:36 EST  6h ago
             <option>-t</option>). If a PID is passed, show information
             about the unit the process belongs to.</para>
 
-            <para>This function is intended to generate human-readable
-            output. If you are looking for computer-parsable output,
-            use <command>show</command> instead. By default, this
-            function only shows 10 lines of output and ellipsizes
-            lines to fit in the terminal window. This can be changed
-            with <option>--lines</option> and <option>--full</option>,
-            see above. In addition, <command>journalctl
-            --unit=<replaceable>NAME</replaceable></command> or
-            <command>journalctl
-            --user-unit=<replaceable>NAME</replaceable></command> use
-            a similar filter for messages and might be more
-            convenient.
-            </para>
-
-            <para>systemd implicitly loads units as necessary, so just running the <command>status</command> will
-            attempt to load a file. The command is thus not useful for determining if something was already loaded or
-            not.  The units may possibly also be quickly unloaded after the operation is completed if there's no reason
-            to keep it in memory thereafter.
-            </para>
+            <para>This function is intended to generate human-readable output. If you are looking for
+            computer-parsable output, use <command>show</command> instead. By default, this function only
+            shows 10 lines of output and ellipsizes lines to fit in the terminal window. This can be changed
+            with <option>--lines</option> and <option>--full</option>, see above. In addition,
+            <command>journalctl --unit=<replaceable>NAME</replaceable></command> or <command>journalctl
+            --user-unit=<replaceable>NAME</replaceable></command> use a similar filter for messages and might
+            be more convenient.</para>
+
+            <para>Note that this operation only displays <emphasis>runtime</emphasis> status, i.e. information about
+            the current invocation of the unit (if it is running) or the most recent invocation (if it is not
+            running anymore, and has not been released from memory). Information about earlier invocations,
+            invocations from previous system boots, or prior invocations that have already been released from
+            memory may be retrieved via <command>journalctl --unit=</command>.</para>
+
+            <para>systemd implicitly loads units as necessary, so just running the <command>status</command>
+            will attempt to load a file. The command is thus not useful for determining if something was
+            already loaded or not.  The units may possibly also be quickly unloaded after the operation is
+            completed if there's no reason to keep it in memory thereafter.</para>
 
             <example>
               <title>Example output from systemctl status </title>
index d803b5c12717586c22828367ae914b30339e6967..7592961f63306b03030d8bca3d60205269fdb197 100644 (file)
         <term><command>has-tpm2</command></term>
 
         <listitem><para>Reports whether the system is equipped with a TPM2 device usable for protecting
-        credentials. If the a TPM2 device has been discovered, is supported, and is being used by firmware,
+        credentials. If a TPM2 device has been discovered, is supported, and is being used by firmware,
         by the OS kernel drivers and by userspace (i.e. systemd) this prints <literal>yes</literal> and exits
         with exit status zero. If no such device is discovered/supported/used, prints
         <literal>no</literal>. Otherwise prints <literal>partial</literal>. In either of these two cases
index 23eab015f6fdc291b5520a9bae0cd48fdceb26e5..44248b2e80159c0da557d5caba1ac452c1acc3e9 100644 (file)
@@ -41,7 +41,7 @@
     <para>
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd-integritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-      <citerefentry project='die-net'><refentrytitle>integritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='die-net'><refentrytitle>integritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
     </para>
   </refsect1>
 
index 751aa2b09e07563579dd9e24156d37c51ed0ffe1..ea810846f19c5743a9ea3168bdc31c7e3d2916f8 100644 (file)
@@ -122,7 +122,7 @@ kernel.core_pattern = |/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t %P %I
     <para>
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-      <citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
     </para>
   </refsect1>
 
index 50c5c89703bf863263d0fccbc9fead3722e81c8f..daa2249d55f0762b2dff4ffbf8175ac1d5cd5193 100644 (file)
@@ -819,13 +819,13 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
 
         <listitem><para>Set soft and hard limits on various resources for executed processes. See
         <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 <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. <literal>LimitAS=16G</literal>). For the limits referring to time values, the
-        usual time units ms, s, min, h and so on may be used (see
+        details on the process resource limit concept. Process 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 <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. <literal>LimitAS=16G</literal>). For the limits
+        referring to time values, the usual time units ms, s, min, h and so on may be used (see
         <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
         details). Note that if no time unit is specified for <varname>LimitCPU=</varname> the default unit of
         seconds is implied, while for <varname>LimitRTTIME=</varname> the default unit of microseconds is
@@ -875,15 +875,17 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         <table>
           <title>Resource limit directives, their equivalent <command>ulimit</command> shell commands and the unit used</title>
 
-          <tgroup cols='3'>
+          <tgroup cols='4'>
             <colspec colname='directive' />
             <colspec colname='equivalent' />
             <colspec colname='unit' />
+            <colspec colname='notes' />
             <thead>
               <row>
                 <entry>Directive</entry>
                 <entry><command>ulimit</command> equivalent</entry>
                 <entry>Unit</entry>
+                <entry>Notes</entry>
               </row>
             </thead>
             <tbody>
@@ -891,81 +893,97 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
                 <entry>LimitCPU=</entry>
                 <entry>ulimit -t</entry>
                 <entry>Seconds</entry>
+                <entry>-</entry>
               </row>
               <row>
                 <entry>LimitFSIZE=</entry>
                 <entry>ulimit -f</entry>
                 <entry>Bytes</entry>
+                <entry>-</entry>
               </row>
               <row>
                 <entry>LimitDATA=</entry>
                 <entry>ulimit -d</entry>
                 <entry>Bytes</entry>
+                <entry>Don't use. This limits the allowed address range, not memory use! Defaults to unlimited and should not be lowered. To limit memory use, see <varname>MemoryMax=</varname> in <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</entry>
               </row>
               <row>
                 <entry>LimitSTACK=</entry>
                 <entry>ulimit -s</entry>
                 <entry>Bytes</entry>
+                <entry>-</entry>
               </row>
               <row>
                 <entry>LimitCORE=</entry>
                 <entry>ulimit -c</entry>
                 <entry>Bytes</entry>
+                <entry>-</entry>
               </row>
               <row>
                 <entry>LimitRSS=</entry>
                 <entry>ulimit -m</entry>
                 <entry>Bytes</entry>
+                <entry>Don't use. No effect on Linux.</entry>
               </row>
               <row>
                 <entry>LimitNOFILE=</entry>
                 <entry>ulimit -n</entry>
                 <entry>Number of File Descriptors</entry>
+                <entry>Don't use. Be careful when raising the soft limit above 1024, since <function>select()</function> cannot function with file descriptors above 1023 on Linux. Nowadays, the hard limit defaults to 524288, a very high value compared to historical defaults. Typically applications should increase their soft limit to the hard limit on their own, if they are OK with working with file descriptors above 1023, i.e. do not use <function>select()</function>. Note that file descriptors are nowadays accounted like any other form of memory, thus there should not be any need to lower the hard limit. Use <varname>MemoryMax=</varname> to control overall service memory use, including file descriptor memory.</entry>
               </row>
               <row>
                 <entry>LimitAS=</entry>
                 <entry>ulimit -v</entry>
                 <entry>Bytes</entry>
+                <entry>Don't use. This limits the allowed address range, not memory use! Defaults to unlimited and should not be lowered. To limit memory use, see <varname>MemoryMax=</varname> in <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</entry>
               </row>
               <row>
                 <entry>LimitNPROC=</entry>
                 <entry>ulimit -u</entry>
                 <entry>Number of Processes</entry>
+                <entry>This limit is enforced based on the number of processes belonging to the user. Typically it's better to track processes per service, i.e. use <varname>TasksMax=</varname>, see <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</entry>
               </row>
               <row>
                 <entry>LimitMEMLOCK=</entry>
                 <entry>ulimit -l</entry>
                 <entry>Bytes</entry>
+                <entry>-</entry>
               </row>
               <row>
                 <entry>LimitLOCKS=</entry>
                 <entry>ulimit -x</entry>
                 <entry>Number of Locks</entry>
+                <entry>-</entry>
               </row>
               <row>
                 <entry>LimitSIGPENDING=</entry>
                 <entry>ulimit -i</entry>
                 <entry>Number of Queued Signals</entry>
+                <entry>-</entry>
               </row>
               <row>
                 <entry>LimitMSGQUEUE=</entry>
                 <entry>ulimit -q</entry>
                 <entry>Bytes</entry>
+                <entry>-</entry>
               </row>
               <row>
                 <entry>LimitNICE=</entry>
                 <entry>ulimit -e</entry>
                 <entry>Nice Level</entry>
+                <entry>-</entry>
               </row>
               <row>
                 <entry>LimitRTPRIO=</entry>
                 <entry>ulimit -r</entry>
                 <entry>Realtime Priority</entry>
+                <entry>-</entry>
               </row>
               <row>
                 <entry>LimitRTTIME=</entry>
-                <entry>No equivalent</entry>
+                <entry>ulimit -R</entry>
                 <entry>Microseconds</entry>
+                <entry>-</entry>
               </row>
             </tbody>
           </tgroup>
@@ -2774,7 +2792,11 @@ SystemCallErrorNumber=EPERM</programlisting>
         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 <varname>DefaultStandardOutput=</varname> in
+        <para>If <varname>StandardInput=</varname> is set to one of <option>tty</option>, <option>tty-force</option>,
+        <option>tty-fail</option>, <option>socket</option>, or <option>fd:<replaceable>name</replaceable></option>, this
+        setting defaults to <option>inherit</option>.</para>
+
+        <para>In other cases, this setting defaults to the value set with <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>
@@ -3635,7 +3657,7 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
           <term><varname>$MONITOR_INVOCATION_ID</varname></term>
           <term><varname>$MONITOR_UNIT</varname></term>
 
-          <listitem><para>Only defined for the service unit type. Those environment variable are passed to
+          <listitem><para>Only defined for the service unit type. Those environment variables are passed to
           all <varname>ExecStart=</varname> and <varname>ExecStartPre=</varname> processes which run in
           services triggered by <varname>OnFailure=</varname> or <varname>OnSuccess=</varname> dependencies.
           </para>
@@ -3644,7 +3666,7 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
           and <varname>$MONITOR_EXIT_STATUS</varname> take the same values as for
           <varname>ExecStop=</varname> and <varname>ExecStopPost=</varname> processes. Variables
           <varname>$MONITOR_INVOCATION_ID</varname> and <varname>$MONITOR_UNIT</varname> are set to the
-          invocaton id and unit name of the service which triggered the dependency.</para>
+          invocation id and unit name of the service which triggered the dependency.</para>
 
           <para>Note that when multiple services trigger the same unit, those variables will be
           <emphasis>not</emphasis> be passed. Consider using a template handler unit for that case instead:
index 6d21d32778b8d6148e8dee3477acf68ddcd8b624..0b247c1f32ac520c4bd4cabe762b1013fd183274 100644 (file)
   <refsect1>
     <title><filename>fstab</filename></title>
 
-    <para>Mount units may either be configured via unit files, or via
-    <filename>/etc/fstab</filename> (see
+    <para>Mount units may either be configured via unit files, or via <filename>/etc/fstab</filename> (see
     <citerefentry project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-    for details). Mounts listed in <filename>/etc/fstab</filename>
-    will be converted into native units dynamically at boot and when
-    the configuration of the system manager is reloaded. In general,
-    configuring mount points through <filename>/etc/fstab</filename>
-    is the preferred approach. See
-    <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-    for details about the conversion.</para>
+    for details). Mounts listed in <filename>/etc/fstab</filename> will be converted into native units
+    dynamically at boot and when the configuration of the system manager is reloaded. In general, configuring
+    mount points through <filename>/etc/fstab</filename> is the preferred approach to manage mounts for
+    humans. For tooling, writing mount units should be preferred over editing <filename>/etc/fstab</filename>.
+    See <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    for details about the conversion from <filename>/etc/fstab</filename> to mount units.</para>
 
     <para>The NFS mount option <option>bg</option> for NFS background mounts
     as documented in <citerefentry project='man-pages'><refentrytitle>nfs</refentrytitle><manvolnum>5</manvolnum></citerefentry>
index 3a776b3f42190702e6cecf6b7401415bedb5e424..b197f333eedd33a63a536a429052f9489519a6e6 100644 (file)
         <term><varname>PhysicalDevice=</varname></term>
         <listitem>
           <para>Specifies the name or index of the physical WLAN device (e.g. <literal>0</literal> or
-          <literal>phy0</literal>). The list of the physical WLAN devices that exist os the host can be
+          <literal>phy0</literal>). The list of the physical WLAN devices that exist on the host can be
           obtained by <command>iw phy</command> command. This option is mandatory.</para>
         </listitem>
       </varlistentry>
index c2ce1b1d6949075ee16cde387aea5b96b5a7784d..3b29905894f54344caf6ed3eeb956ea7b9387bdc 100644 (file)
@@ -1103,9 +1103,9 @@ Table=1234</programlisting></para>
           IGMP snooping since the switch would not replicate multicast packets on  ports that did not
           have IGMP reports for the multicast addresses. Linux vxlan interfaces created via
           <command>ip link add vxlan</command> or networkd's netdev kind vxlan have the group option
-          that enables then to do the required join. By extending ip address command with option
-          <literal>autojoin</literal> we can get similar functionality for openvswitch (OVS) vxlan
-          interfaces as well as other tunneling mechanisms that need to receive multicast traffic.
+          that enables them to do the required join. By extending <command>ip address</command> command
+          with option <literal>autojoin</literal> we can get similar functionality for openvswitch (OVS)
+          vxlan interfaces as well as other tunneling mechanisms that need to receive multicast traffic.
           Defaults to <literal>no</literal>.</para>
         </listitem>
       </varlistentry>
@@ -1487,7 +1487,7 @@ Table=1234</programlisting></para>
           <para>For IPv4 route, defaults to <literal>host</literal> if <varname>Type=</varname> is
           <literal>local</literal> or <literal>nat</literal>, and <literal>link</literal> if
           <varname>Type=</varname> is <literal>broadcast</literal>, <literal>multicast</literal>,
-          <literal>anycast</literal>, or direct <literal>unicast</literal> routes. In other cases,
+          <literal>anycast</literal>, or <literal>unicast</literal>. In other cases,
           defaults to <literal>global</literal>. The value is not used for IPv6.</para>
         </listitem>
       </varlistentry>
@@ -2534,7 +2534,7 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
       <varlistentry>
         <term><varname>ServerAddress=</varname></term>
         <listitem><para>Specifies server address for the DHCP server. Takes an IPv4 address with prefix
-        length, for example <literal>192.168.0.1/24</literal>. This setting may be useful when the link on
+        length, for example 192.168.0.1/24. This setting may be useful when the link on
         which the DHCP server is running has multiple static addresses. When unset, one of static addresses
         in the link will be automatically selected. Defaults to unset.</para></listitem>
       </varlistentry>
@@ -2956,7 +2956,7 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
 
         <listitem><para>The IPv6 route that is to be distributed to hosts.  Similarly to configuring static
         IPv6 routes, the setting is configured as an IPv6 prefix routes and its prefix route length,
-        separated by a <literal>/</literal> character. Use multiple [IPv6PrefixRoutes] sections to configure
+        separated by a <literal>/</literal> character. Use multiple [IPv6RoutePrefix] sections to configure
         multiple IPv6 prefix routes.</para></listitem>
       </varlistentry>
 
index 03d27b9fbc45eddb0e9a020e74120bd82efecb9a..d57fbf0442b6a362759628467aa0fb9c60587870 100644 (file)
@@ -76,7 +76,7 @@
 
       <listitem><para>Similarly, a file <literal>https://download.example.com/foobarOS_47.verity.xz</literal>
       should be downloaded, decompressed and written to a previously empty partition with GPT partition type
-      UUID of 2c7357ed-ebd2-46d9-aec1-23d437ec2bf5 (i.e the partition type for Verity integrity information
+      UUID of 2c7357ed-ebd2-46d9-aec1-23d437ec2bf5 (i.e. the partition type for Verity integrity information
       for x86-64 root file systems).</para></listitem>
 
       <listitem><para>Finally, a file <literal>https://download.example.com/foobarOS_47.efi.xz</literal> (a
     <itemizedlist>
       <listitem><para>For partitions: the surrounding GPT partition table contains a list of defined
       partitions, including a partition type UUID and a partition label (in this scheme the partition label
-      plays a role for the partition similar to the filename for a regular file)</para></listitem>
+      plays a role for the partition similar to the filename for a regular file).</para></listitem>
 
       <listitem><para>For regular files: the directory listing of the directory the files are contained in
       provides a list of existing files in a straightforward way.</para></listitem>
             <entry><literal>@r</literal></entry>
             <entry>Read-only flag</entry>
             <entry>Either <literal>0</literal> or <literal>1</literal></entry>
-            <entry>Controls ReadOnly bit of the GPT partition flags, as per <ulink url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable Partitions Specification</ulink> and other output read-only flags, see <varname>ReadOnly=</varname> below.</entry>
+            <entry>Controls ReadOnly bit of the GPT partition flags, as per <ulink url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable Partitions Specification</ulink> and other output read-only flags, see <varname>ReadOnly=</varname> below</entry>
           </row>
 
           <row>
             <entry><literal>@l</literal></entry>
             <entry>Tries left</entry>
             <entry>Formatted decimal integer</entry>
-            <entry>Useful when operating with kernel images, as per <ulink url="https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT">Automatic Boot Assessment</ulink></entry>
+            <entry>Useful when operating with kernel image files, as per <ulink url="https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT">Automatic Boot Assessment</ulink></entry>
           </row>
 
           <row>
             <entry><literal>@h</literal></entry>
             <entry>SHA256 hash of compressed file</entry>
             <entry>64 hexadecimal characters</entry>
-            <entry>The SHA256 hash of the compressed file; not useful for <constant>url-file</constant> or <constant>url-tar</constant> where the SHA256 hash is already included in the manifest file anyway.</entry>
+            <entry>The SHA256 hash of the compressed file; not useful for <constant>url-file</constant> or <constant>url-tar</constant> where the SHA256 hash is already included in the manifest file anyway</entry>
           </row>
         </tbody>
       </tgroup>
   <refsect1>
     <title>[Transfer] Section Options</title>
 
-    <para>This section defines general properties of this transfer.</para>
+    <para>This section defines general properties of this transfer:</para>
 
     <variablelist>
       <varlistentry>
         <listitem><para>Specifies a file system path where to look for already installed versions or place
         newly downloaded versions of this configured resource. If <varname>Type=</varname> is set to
         <constant>partition</constant>, expects a path to a (whole) block device node, or the special string
-        <literal>auto</literal> in which case the block device the root file system of the currently booted
-        system is automatically determined and used. If <varname>Type=</varname> is set to
+        <literal>auto</literal> in which case the block device which contains the root file system of the
+        currently booted system is automatically determined and used. If <varname>Type=</varname> is set to
         <constant>regular-file</constant>, <constant>directory</constant> or <constant>subvolume</constant>,
         must refer to a path in the local file system referencing the directory to find or place the version
         files or directories under.</para>
@@ -818,7 +818,7 @@ Path=https://download.example.com/
 MatchPattern=foobarOS_@v.efi.xz
 
 [Target]
-Type=file
+Type=regular-file
 Path=/efi/EFI/Linux
 MatchPattern=foobarOS_@v+@l-@d.efi \
              foobarOS_@v+@l.efi \
@@ -831,7 +831,7 @@ InstancesMax=2</programlisting></para>
         <para>The above installs a unified kernel image into the ESP (which is mounted to
         <filename>/efi/</filename>), as per <ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot
         Loader Specification</ulink> Type #2. This defines three possible patterns for the names of the
-        kernel images images, as per <ulink url="https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT">Automatic Boot
+        kernel images, as per <ulink url="https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT">Automatic Boot
         Assessment</ulink>, and ensures when installing new kernels, they are set up with 3 tries left. No
         more than two parallel kernels are kept.</para>
 
index 3a9b133d304694fbb93d2599187a124bea56c8e1..89ebfbd0123917921c31afdf89a155a04cc5993b 100644 (file)
       <para><command>udevadm lock</command> takes an (advisory) exclusive lock(s) on a block device (or
       multiple thereof), as per <ulink url="https://systemd.io/BLOCK_DEVICE_LOCKING">Locking Block Device
       Access</ulink> and invokes a program with the lock(s) taken. When the invoked program exits the lock(s)
-      are automatically released.</para>
+      are automatically released and its return value is propagated as exit code of <command>udevadm
+      lock</command>.</para>
 
       <para>This tool is in particular useful to ensure that
       <citerefentry><refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
index 9c170acc0aa4e7dc7a2714fbc0671e221084652b..dbba108ad1aa1e7f7181e1a206d94df22f3c38e6 100644 (file)
@@ -481,7 +481,6 @@ decl_headers = '''
 #include <uchar.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
-#include <linux/fs.h>
 '''
 
 foreach decl : ['char16_t',
@@ -493,6 +492,17 @@ foreach decl : ['char16_t',
         # We get -1 if the size cannot be determined
         have = cc.sizeof(decl, prefix : decl_headers, args : '-D_GNU_SOURCE') > 0
 
+        if decl == 'struct mount_attr'
+                if have
+                        want_linux_fs_h = false
+                else
+                        have = cc.sizeof(decl,
+                                         prefix : decl_headers + '#include <linux/fs.h>',
+                                         args : '-D_GNU_SOURCE') > 0
+                        want_linux_fs_h = have
+                endif
+        endif
+
         if decl == 'struct statx'
                 if have
                         want_linux_stat_h = false
@@ -508,6 +518,7 @@ foreach decl : ['char16_t',
 endforeach
 
 conf.set10('WANT_LINUX_STAT_H', want_linux_stat_h)
+conf.set10('WANT_LINUX_FS_H', want_linux_fs_h)
 
 foreach ident : ['secure_getenv', '__secure_getenv']
         conf.set10('HAVE_' + ident.to_upper(), cc.has_function(ident))
@@ -2173,7 +2184,7 @@ public_programs += executable(
         dependencies : [versiondep,
                         libseccomp],
         install_rpath : rootlibexecdir,
-        install : conf.get('ENABLE_ANALYZE'))
+        install : conf.get('ENABLE_ANALYZE') == 1)
 
 executable(
         'systemd-journald',
index 6c1de92a26caa786211cdda45b209d5ed59eb07f..00591d6c2d31fe67805f6c6970100d6698273009 100644 (file)
@@ -3,7 +3,9 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <linux/btrfs.h>
+#if WANT_LINUX_FS_H
 #include <linux/fs.h>
+#endif
 #include <linux/magic.h>
 #include <sys/ioctl.h>
 #include <sys/resource.h>
index 64c63cdab1fe07533fedbdcf3a8ffd3fa2b119b3..41c9362be18e007d67dc450f739f8de9f17de23c 100644 (file)
@@ -9,12 +9,14 @@ void initialize_libgcrypt(bool secmem) {
         if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P))
                 return;
 
+        gcry_control(GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM);
         assert_se(gcry_check_version("1.4.5"));
 
         /* Turn off "secmem". Clients which wish to make use of this
          * feature should initialize the library manually */
         if (!secmem)
                 gcry_control(GCRYCTL_DISABLE_SECMEM);
+
         gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
 }
 
index 0cacd49bcff7eb500e7ed388091e51ebada3a0e3..6638d7696221d17ada03e392fad61c89c3bc50a4 100644 (file)
@@ -64,3 +64,8 @@
 #ifndef FS_PROJINHERIT_FL
 #define FS_PROJINHERIT_FL 0x20000000
 #endif
+
+/* linux/fscrypt.h */
+#ifndef FS_KEY_DESCRIPTOR_SIZE
+#define FS_KEY_DESCRIPTOR_SIZE 8
+#endif
index 64c2f80f3c3ff6b1a6b69e2f46ac6406bbe4d362..c31b4d89d020e35c6d00be51bfa8f5377a4498d1 100644 (file)
@@ -35,31 +35,23 @@ int is_symlink(const char *path) {
         return !!S_ISLNK(info.st_mode);
 }
 
-int is_dir(const char* path, bool follow) {
+int is_dir_full(int atfd, const char* path, bool follow) {
         struct stat st;
         int r;
 
-        assert(path);
+        assert(atfd >= 0 || atfd == AT_FDCWD);
+        assert(atfd >= 0 || path);
 
-        if (follow)
-                r = stat(path, &st);
+        if (path)
+                r = fstatat(atfd, path, &st, follow ? 0 : AT_SYMLINK_NOFOLLOW);
         else
-                r = lstat(path, &st);
+                r = fstat(atfd, &st);
         if (r < 0)
                 return -errno;
 
         return !!S_ISDIR(st.st_mode);
 }
 
-int is_dir_fd(int fd) {
-        struct stat st;
-
-        if (fstat(fd, &st) < 0)
-                return -errno;
-
-        return !!S_ISDIR(st.st_mode);
-}
-
 int is_device_node(const char *path) {
         struct stat info;
 
index 7f0b3dc0af5567b075009e307a4f511e4e4d0900..56f15534aa2565d51f0f6b0f1ecd8bc44785f93b 100644 (file)
 #include "missing_stat.h"
 
 int is_symlink(const char *path);
-int is_dir(const char *path, bool follow);
-int is_dir_fd(int fd);
+int is_dir_full(int atfd, const char *fname, bool follow);
+static inline int is_dir(const char *path, bool follow) {
+        return is_dir_full(AT_FDCWD, path, follow);
+}
+static inline int is_dir_fd(int fd) {
+        return is_dir_full(fd, NULL, false);
+}
 int is_device_node(const char *path);
 
 int dir_is_empty_at(int dir_fd, const char *path, bool ignore_hidden_or_backup);
index 83c29bb25f821b4f1eb844a854333ac26efb067c..bfe8c021301eb780dedd1cb23b18035258b77b09 100644 (file)
@@ -695,12 +695,9 @@ static int add_names(
                                 continue;
                         }
 
-                        r = set_consume(*names, TAKE_PTR(inst));
-                        if (r > 0)
-                                log_debug("Unit %s has alias %s.", unit_name, inst);
+                        r = add_name(unit_name, names, inst);
                 } else
                         r = add_name(unit_name, names, *alias);
-
                 if (r < 0)
                         return r;
         }
index 5cc1011ae8eea90e6f1adc8703a6d59301ea8e86..74e4ea836d23ef39d73f8f18f01860b715547d2f 100644 (file)
@@ -158,6 +158,7 @@ static Virtualization detect_vm_dmi_vendor(void) {
         } dmi_vendor_table[] = {
                 { "KVM",                 VIRTUALIZATION_KVM       },
                 { "OpenStack",           VIRTUALIZATION_KVM       }, /* Detect OpenStack instance as KVM in non x86 architecture */
+                { "KubeVirt",            VIRTUALIZATION_KVM       }, /* Detect KubeVirt instance as KVM in non x86 architecture */
                 { "Amazon EC2",          VIRTUALIZATION_AMAZON    },
                 { "QEMU",                VIRTUALIZATION_QEMU      },
                 { "VMware",              VIRTUALIZATION_VMWARE    }, /* https://kb.vmware.com/s/article/1009458 */
index 299a01b9be7eac4e69d39c10e5d0c857c02a462e..370ae97ecb04a880c1bf33c6025990e12b111ff1 100644 (file)
@@ -200,6 +200,12 @@ efi_cflags = cc.get_supported_arguments(
         '-include', version_h,
 ]
 
+# On some distros, sd-boot/-stub may trigger some bug somewhere that will cause
+# kernel execution to fail. The cause seems to be purely based on code size and
+# always compiling with at least -O1 will work around that.
+# https://github.com/systemd/systemd/issues/24202
+efi_cflags += '-O1'
+
 efi_cflags += cc.get_supported_arguments({
         'ia32':   ['-mno-sse', '-mno-mmx'],
         'x86_64': ['-mno-red-zone', '-mno-sse', '-mno-mmx'],
@@ -260,6 +266,13 @@ efi_ldflags = [
         '-z', 'nocombreloc',
         efi_crt0,
 ]
+
+possible_link_flags = [
+        '-Wl,--no-warn-execstack',
+        '-Wl,--no-warn-rwx-segments',
+]
+efi_ldflags += cc.get_supported_link_arguments(possible_link_flags)
+
 if efi_arch[1] in ['aarch64', 'arm', 'riscv64']
         efi_ldflags += ['-shared']
         # Aarch64, ARM32 and 64bit RISC-V don't have an EFI capable objcopy.
index 071cba30996e855d83bdad59ca8917234341dc4a..91267362351805b2e2c818347f009fad2986f381 100644 (file)
@@ -16,6 +16,13 @@ int main(int argc, char *argv[]) {
         _cleanup_close_ int fd = -1;
         ssize_t n;
         size_t l;
+        int r;
+
+        r = rearrange_stdio(-1, -1, -1);
+        if (r < 0) {
+                log_error_errno(r, "Failed to connect stdin/stdout/stderr with /dev/null: %m");
+                return EXIT_FAILURE;
+        }
 
         if (argc != 2) {
                 log_error("Incorrect number of arguments.");
index 347a3a8d21519a15abaea3d08217af65411c4266..6c960b86f30934d5141080e621f37d6830dab7c3 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/bpf.h>
 #include <bpf/bpf_helpers.h>
 
-const volatile __u8 is_allow_list = 0;
+const volatile __u8 is_allow_list SEC(".rodata") = 0;
 
 /* Map containing the network interfaces indexes.
  * The interpretation of the map depends on the value of is_allow_list.
index 073675ceefa446f074cc78a9554445f3d6474215..ad2230d1b5e9f95421296374a5b4f41c27a52298 100644 (file)
@@ -42,6 +42,7 @@
 #include "string-util.h"
 #include "strv.h"
 #include "strxcpyx.h"
+#include "umask-util.h"
 #include "user-util.h"
 
 #define CONNECTIONS_MAX 4096
@@ -950,7 +951,8 @@ int bus_init_private(Manager *m) {
         if (fd < 0)
                 return log_error_errno(errno, "Failed to allocate private socket: %m");
 
-        r = bind(fd, &sa.sa, sa_len);
+        RUN_WITH_UMASK(0077)
+                r = bind(fd, &sa.sa, sa_len);
         if (r < 0)
                 return log_error_errno(errno, "Failed to bind private socket: %m");
 
index 8b87434683d439e16633dffba9f0a354d9f223d9..53796484ee3f6457b836940ebe60a9c6e53afece 100644 (file)
@@ -226,7 +226,7 @@ static int import_credentials_boot(void) {
                         if (nfd == -EEXIST)
                                 continue;
                         if (nfd < 0)
-                                return r;
+                                return nfd;
 
                         r = copy_bytes(cfd, nfd, st.st_size, 0);
                         if (r < 0) {
@@ -325,7 +325,7 @@ static int proc_cmdline_callback(const char *key, const char *value, void *data)
         if (nfd == -EEXIST)
                 return 0;
         if (nfd < 0)
-                return r;
+                return nfd;
 
         r = loop_write(nfd, colon, l, /* do_poll= */ false);
         if (r < 0) {
@@ -417,7 +417,7 @@ static int import_credentials_qemu(ImportCredentialContext *c) {
 
                 rfd = openat(vfd, "raw", O_RDONLY|O_CLOEXEC);
                 if (rfd < 0) {
-                        log_warning_errno(r, "Failed to open '" QEMU_FWCFG_PATH "'/%s/raw, ignoring: %m", d->d_name);
+                        log_warning_errno(errno, "Failed to open '" QEMU_FWCFG_PATH "'/%s/raw, ignoring: %m", d->d_name);
                         continue;
                 }
 
@@ -429,7 +429,7 @@ static int import_credentials_qemu(ImportCredentialContext *c) {
                 if (nfd == -EEXIST)
                         continue;
                 if (nfd < 0)
-                        return r;
+                        return nfd;
 
                 r = copy_bytes(rfd, nfd, sz, 0);
                 if (r < 0) {
index 0cf2df6fab64c19e9de9139061b41a7251d17783..69d450a87ee7a9d8ba9dbb4616c6ca7f086370c0 100644 (file)
@@ -2806,6 +2806,11 @@ int main(int argc, char *argv[]) {
                 /* clear the kernel timestamp, because we are not PID 1 */
                 kernel_timestamp = DUAL_TIMESTAMP_NULL;
 
+                /* Clear ambient capabilities, so services do not inherit them implicitly. Dropping them does
+                 * not affect the permitted and effective sets which are important for the manager itself to
+                 * operate. */
+                capability_ambient_set_apply(0, /* also_inherit= */ false);
+
                 if (mac_selinux_init() < 0) {
                         error_message = "Failed to initialize SELinux support";
                         goto finish;
index 20b4bb6d2b8116c60df3e9ae189ab3d4f2e8b60b..029f1328c1cfc10b03b1c6c77e2ab8a7ce51764b 100644 (file)
@@ -1029,11 +1029,13 @@ static void mount_enter_mounting(Mount *m) {
         if (p && mount_is_bind(p)) {
                 r = mkdir_p_label(p->what, m->directory_mode);
                 /* mkdir_p_label() can return -EEXIST if the target path exists and is not a directory - which is
-                 * totally OK, in case the user wants us to overmount a non-directory inode. */
-                if (r < 0 && r != -EEXIST) {
-                        log_unit_error_errno(UNIT(m), r, "Failed to make bind mount source '%s': %m", p->what);
-                        goto fail;
-                }
+                 * totally OK, in case the user wants us to overmount a non-directory inode. Also -EROFS can be
+                 * returned on read-only filesystem. Moreover, -EACCES (and also maybe -EPERM?) may be returned
+                 * when the path is on NFS. See issue #24120. All such errors will be logged in the debug level. */
+                if (r < 0 && r != -EEXIST)
+                        log_unit_full_errno(UNIT(m),
+                                            (r == -EROFS || ERRNO_IS_PRIVILEGE(r)) ? LOG_DEBUG : LOG_WARNING,
+                                            r, "Failed to make bind mount source '%s', ignoring: %m", p->what);
         }
 
         if (p) {
index 32568718033aceea39822215039a9f2d2c859d87..2eafe432903f154aebe166560fcc9335d65fe398 100644 (file)
@@ -7,7 +7,9 @@
 #include <sys/file.h>
 #include <sys/mount.h>
 #include <unistd.h>
+#if WANT_LINUX_FS_H
 #include <linux/fs.h>
+#endif
 
 #include "alloc-util.h"
 #include "base-filesystem.h"
index 63d3288caf16fc8bb3960b8d94d9498f84a6b480..080bb713560e27de0340fde53704d8c575b54c04 100644 (file)
@@ -392,7 +392,7 @@ static int scope_start(Unit *u) {
                 return r;
         }
         if (r == 0) {
-                log_unit_warning(u, "No PIDs left to attach to the scope's control group, refusing: %m");
+                log_unit_warning(u, "No PIDs left to attach to the scope's control group, refusing.");
                 scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
                 return -ECHILD;
         }
index fc1b7bb4345996fd3645fc15ca9ab76a40f51821..231a42f836ce4e6d6cb8c5aa24d1d2b5ed8471ab 100644 (file)
@@ -1275,6 +1275,13 @@ static int process_kernel(int argc, char* argv[]) {
         struct iovec_wrapper *iovw;
         int r;
 
+        /* When we're invoked by the kernel, stdout/stderr are closed which is dangerous because the fds
+         * could get reallocated. To avoid hard to debug issues, let's instead bind stdout/stderr to
+         * /dev/null. */
+        r = rearrange_stdio(STDIN_FILENO, -1, -1);
+        if (r < 0)
+                return log_error_errno(r, "Failed to connect stdout/stderr to /dev/null: %m");
+
         log_debug("Processing coredump received from the kernel...");
 
         iovw = iovw_new();
index b39ca3262c7695a97d5e0699bf1280829cf7fcaa..4663792e5c34dde026b922c666b5c414e9883cf2 100644 (file)
@@ -771,6 +771,8 @@ static int bus_home_node_enumerator(
                 r = bus_home_path(h, l + k);
                 if (r < 0)
                         return r;
+
+                k++;
         }
 
         *nodes = TAKE_PTR(l);
index 728a92260cfdb9253eca1fdd37a5b76679255bc8..e79def3daec75a3c5215eb9c9f45b3b815fa813d 100644 (file)
@@ -1,5 +1,10 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include <sys/mount.h>
+#if WANT_LINUX_FS_H
+#include <linux/fs.h>
+#endif
+
 #include "dirent-util.h"
 #include "fd-util.h"
 #include "fileio.h"
index 11360c470fe063066b5a3a4e1a4834a2c91e6948..cf2083153f22f79e1879ceabedd3ea0c7fa6bb88 100644 (file)
@@ -4,7 +4,6 @@
 #include <poll.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
-#include <sys/mount.h>
 #include <sys/xattr.h>
 
 #if HAVE_VALGRIND_MEMCHECK_H
index 3095a10ff9ab75fb3d2c8e937126f17f66c0de1b..239d441992f8fcd8d81e533d2ae97ff4736db57e 100644 (file)
@@ -2,7 +2,9 @@
 
 #include <sched.h>
 #include <sys/mount.h>
+#if WANT_LINUX_FS_H
 #include <linux/fs.h>
+#endif
 
 #include "alloc-util.h"
 #include "fd-util.h"
index 882a3f500b3bfcf0151e7a8f510f6004a600dce1..b27c31d56bab562e54050440e7cf2c7b8213fae4 100644 (file)
@@ -1,13 +1,14 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <linux/fs.h>
 #include <sys/vfs.h>
 
 #include "sd-id128.h"
 
+#include "cryptsetup-util.h"
 #include "homework-password-cache.h"
 #include "loop-util.h"
+#include "missing_fs.h" /* for FS_KEY_DESCRIPTOR_SIZE, do not include linux/fs.h */
 #include "missing_keyctl.h"
 #include "missing_syscall.h"
 #include "user-record.h"
index 2347db3bacf33faf82168bf1c3b3bf956f4a0f40..475613a9076f2c0c99806be2c0c41643ae177c6e 100644 (file)
@@ -9,15 +9,15 @@
 typedef enum PullFlags {
         PULL_FORCE              = 1 << 0, /* replace existing image */
         PULL_READ_ONLY          = 1 << 1, /* make generated image read-only */
-        PULL_SETTINGS           = 1 << 1, /* download .nspawn settings file */
-        PULL_ROOTHASH           = 1 << 2, /* only for raw: download .roothash file for verity */
-        PULL_ROOTHASH_SIGNATURE = 1 << 3, /* only for raw: download .roothash.p7s file for verity */
-        PULL_VERITY             = 1 << 4, /* only for raw: download .verity file for verity */
-        PULL_BTRFS_SUBVOL       = 1 << 2, /* tar: preferably create images as btrfs subvols */
-        PULL_BTRFS_QUOTA        = 1 << 3, /* tar: set up btrfs quota for new subvolume as child of parent subvolume */
-        PULL_CONVERT_QCOW2      = 1 << 4, /* raw: if we detect a qcow2 image, unpack it */
-        PULL_DIRECT             = 1 << 5, /* download without rename games */
-        PULL_SYNC               = 1 << 6, /* fsync() right before we are done */
+        PULL_SETTINGS           = 1 << 2, /* download .nspawn settings file */
+        PULL_ROOTHASH           = 1 << 3, /* only for raw: download .roothash file for verity */
+        PULL_ROOTHASH_SIGNATURE = 1 << 4, /* only for raw: download .roothash.p7s file for verity */
+        PULL_VERITY             = 1 << 5, /* only for raw: download .verity file for verity */
+        PULL_BTRFS_SUBVOL       = 1 << 6, /* tar: preferably create images as btrfs subvols */
+        PULL_BTRFS_QUOTA        = 1 << 7, /* tar: set up btrfs quota for new subvolume as child of parent subvolume */
+        PULL_CONVERT_QCOW2      = 1 << 8, /* raw: if we detect a qcow2 image, unpack it */
+        PULL_DIRECT             = 1 << 9, /* download without rename games */
+        PULL_SYNC               = 1 << 10, /* fsync() right before we are done */
 
         /* The supported flags for the tar and the raw pulling */
         PULL_FLAGS_MASK_TAR     = PULL_FORCE|PULL_READ_ONLY|PULL_SETTINGS|PULL_BTRFS_SUBVOL|PULL_BTRFS_QUOTA|PULL_DIRECT|PULL_SYNC,
index 924c15b6eb1caeed3feab4fee7a3f2f4b636fdb3..a602886cb3e9fe6a610efdb5f0883cbdc25c1871 100644 (file)
@@ -152,12 +152,6 @@ static int run(int argc, char *argv[]) {
                         return 0;
                 }
 
-                if (!isempty(arg_existing_data_device)) {
-                        r = crypt_init_data_device(&cd, device, arg_existing_data_device);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to add separate data device: %m");
-                }
-
                 r = crypt_load(cd,
                         CRYPT_INTEGRITY,
                         &(struct crypt_params_integrity) {
@@ -168,6 +162,12 @@ static int run(int argc, char *argv[]) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to load integrity superblock: %m");
 
+                if (!isempty(arg_existing_data_device)) {
+                        r = crypt_set_data_device(cd, arg_existing_data_device);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to add separate data device: %m");
+                }
+
                 r = crypt_activate_by_volume_key(cd, volume, key_buf, key_buf_size, arg_activate_flags);
                 if (r < 0)
                         return log_error_errno(r, "Failed to set up integrity device: %m");
index 63d3f60513afff6a45d189297e6c713903eda8c1..5e91e86f536d36ac29fe4d5d774e1cac01a26828 100644 (file)
@@ -508,7 +508,7 @@ int dhcp6_option_parse(
         if (buflen < offsetof(DHCP6Option, data))
                 return -EBADMSG;
 
-        if (*offset >= buflen - offsetof(DHCP6Option, data))
+        if (*offset > buflen - offsetof(DHCP6Option, data))
                 return -EBADMSG;
 
         len = unaligned_read_be16(buf + *offset + offsetof(DHCP6Option, len));
@@ -518,14 +518,14 @@ int dhcp6_option_parse(
 
         *ret_option_code = unaligned_read_be16(buf + *offset + offsetof(DHCP6Option, code));
         *ret_option_data_len = len;
-        *ret_option_data = buf + *offset + offsetof(DHCP6Option, data);
+        *ret_option_data = len == 0 ? NULL : buf + *offset + offsetof(DHCP6Option, data);
         *offset += offsetof(DHCP6Option, data) + len;
 
         return 0;
 }
 
 int dhcp6_option_parse_status(const uint8_t *data, size_t data_len, char **ret_status_message) {
-        assert(data);
+        assert(data || data_len == 0);
 
         if (data_len < sizeof(uint16_t))
                 return -EBADMSG;
@@ -803,7 +803,7 @@ int dhcp6_option_parse_addresses(
                 struct in6_addr **addrs,
                 size_t *count) {
 
-        assert(optval);
+        assert(optval || optlen == 0);
         assert(addrs);
         assert(count);
 
@@ -826,8 +826,8 @@ static int parse_domain(const uint8_t **data, size_t *len, char **ret) {
         int r;
 
         assert(data);
-        assert(*data);
         assert(len);
+        assert(*data || *len == 0);
         assert(ret);
 
         optval = *data;
@@ -891,7 +891,7 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, size_t optlen, char **r
         _cleanup_free_ char *domain = NULL;
         int r;
 
-        assert(optval);
+        assert(optval || optlen == 0);
         assert(ret);
 
         r = parse_domain(&optval, &optlen, &domain);
@@ -910,7 +910,7 @@ int dhcp6_option_parse_domainname_list(const uint8_t *optval, size_t optlen, cha
         _cleanup_strv_free_ char **names = NULL;
         int r;
 
-        assert(optval);
+        assert(optval || optlen == 0);
         assert(ret);
 
         if (optlen <= 1)
index 2475cdb7eda6a69b2a6a009d3b32bad8831224e8..f588514cb646ba537e177ca47b6c423766e694c3 100644 (file)
@@ -467,7 +467,9 @@ static int dhcp6_lease_parse_message(
 
                 r = dhcp6_option_parse(message->options, len, &offset, &optcode, &optlen, &optval);
                 if (r < 0)
-                        return r;
+                        return log_dhcp6_client_errno(client, r,
+                                                      "Failed to parse option header at offset %zu of total length %zu: %m",
+                                                      offset, len);
 
                 switch (optcode) {
                 case SD_DHCP6_OPTION_CLIENTID:
@@ -477,7 +479,7 @@ static int dhcp6_lease_parse_message(
 
                         r = dhcp6_lease_set_clientid(lease, optval, optlen);
                         if (r < 0)
-                                return r;
+                                return log_dhcp6_client_errno(client, r, "Failed to set client ID: %m");
 
                         break;
 
@@ -488,17 +490,17 @@ static int dhcp6_lease_parse_message(
 
                         r = dhcp6_lease_set_serverid(lease, optval, optlen);
                         if (r < 0)
-                                return r;
+                                return log_dhcp6_client_errno(client, r, "Failed to set server ID: %m");
 
                         break;
 
                 case SD_DHCP6_OPTION_PREFERENCE:
                         if (optlen != 1)
-                                return -EINVAL;
+                                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "Received invalid length for preference.");
 
                         r = dhcp6_lease_set_preference(lease, optval[0]);
                         if (r < 0)
-                                return r;
+                                return log_dhcp6_client_errno(client, r, "Failed to set preference: %m");
 
                         break;
 
@@ -507,7 +509,7 @@ static int dhcp6_lease_parse_message(
 
                         r = dhcp6_option_parse_status(optval, optlen, &msg);
                         if (r < 0)
-                                return r;
+                                return log_dhcp6_client_errno(client, r, "Failed to parse status code: %m");
 
                         if (r > 0)
                                 return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
@@ -527,9 +529,11 @@ static int dhcp6_lease_parse_message(
 
                         r = dhcp6_option_parse_ia(client, client->ia_na.header.id, optcode, optlen, optval, &ia);
                         if (r == -ENOMEM)
-                                return r;
-                        if (r < 0)
+                                return log_oom_debug();
+                        if (r < 0) {
+                                log_dhcp6_client_errno(client, r, "Failed to parse IA_NA option, ignoring: %m");
                                 continue;
+                        }
 
                         if (lease->ia_na) {
                                 log_dhcp6_client(client, "Received duplicate matching IA_NA option, ignoring.");
@@ -550,9 +554,11 @@ static int dhcp6_lease_parse_message(
 
                         r = dhcp6_option_parse_ia(client, client->ia_pd.header.id, optcode, optlen, optval, &ia);
                         if (r == -ENOMEM)
-                                return r;
-                        if (r < 0)
+                                return log_oom_debug();
+                        if (r < 0) {
+                                log_dhcp6_client_errno(client, r, "Failed to parse IA_PD option, ignoring: %m");
                                 continue;
+                        }
 
                         if (lease->ia_pd) {
                                 log_dhcp6_client(client, "Received duplicate matching IA_PD option, ignoring.");
@@ -564,9 +570,12 @@ static int dhcp6_lease_parse_message(
                         break;
                 }
                 case SD_DHCP6_OPTION_RAPID_COMMIT:
+                        if (optlen != 0)
+                                log_dhcp6_client(client, "Received rapid commit option with an invalid length (%zu), ignoring.", optlen);
+
                         r = dhcp6_lease_set_rapid_commit(lease);
                         if (r < 0)
-                                return r;
+                                return log_dhcp6_client_errno(client, r, "Failed to set rapid commit flag: %m");
 
                         break;
 
@@ -607,7 +616,8 @@ static int dhcp6_lease_parse_message(
 
                 case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME:
                         if (optlen != 4)
-                                return -EINVAL;
+                                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
+                                                              "Received information refresh time option with an invalid length (%zu).", optlen);
 
                         irt = unaligned_read_be32((be32_t *) optval) * USEC_PER_SEC;
                         break;
index 95a6c514c6df0299fc4cff4a5d6ab3800e33243c..e5c09f96648ed0480d0dbdc3c4db101bc54eb668 100644 (file)
@@ -443,6 +443,48 @@ TEST(client_parse_message_issue_22099) {
         assert_se(dhcp6_lease_new_from_message(client, (const DHCP6Message*) msg, sizeof(msg), NULL, NULL, &lease) >= 0);
 }
 
+TEST(client_parse_message_issue_24002) {
+        static const uint8_t msg[] = {
+                /* Message Type */
+                0x07,
+                /* Transaction ID */
+                0x0e, 0xa5, 0x7c,
+                /* Client ID */
+                0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
+                0x00, 0x02, /* DUID-EN */
+                0x00, 0x00, 0xab, 0x11, /* pen */
+                0x5c, 0x6b, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, /* id */
+                /* Server ID */
+                0x00, 0x02, 0x00, 0x1a,
+                0x00, 0x02, 0x00, 0x00, 0x05, 0x83, 0x30, 0x63, 0x3a, 0x38, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
+                0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+                /* IA_PD */
+                0x00, 0x19, 0x00, 0x29,
+                0xaa, 0xbb, 0xcc, 0xdd, /* iaid */
+                0x00, 0x00, 0x03, 0x84, /* lifetime (T1) */
+                0x00, 0x00, 0x05, 0xa0, /* lifetime (T2) */
+                /* IA_PD (iaprefix suboption) */
+                0x00, 0x1a, 0x00, 0x19,
+                0x00, 0x00, 0x07, 0x08, /* preferred lifetime */
+                0x00, 0x00, 0x38, 0x40, /* valid lifetime */
+                0x38, /* prefixlen */
+                0x20, 0x03, 0x00, 0xff, 0xaa, 0xbb, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* prefix */
+                /* Rapid commit */
+                0x00, 0x0e, 0x00, 0x00,
+        };
+        static const uint8_t duid[] = {
+                0x00, 0x00, 0xab, 0x11, 0x5c, 0x6b, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+        };
+        _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
+        _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
+
+        assert_se(sd_dhcp6_client_new(&client) >= 0);
+        assert_se(sd_dhcp6_client_set_iaid(client, 0xaabbccdd) >= 0);
+        assert_se(sd_dhcp6_client_set_duid(client, 2, duid, sizeof(duid)) >= 0);
+
+        assert_se(dhcp6_lease_new_from_message(client, (const DHCP6Message*) msg, sizeof(msg), NULL, NULL, &lease) >= 0);
+}
+
 static const uint8_t msg_information_request[] = {
         /* Message type */
         DHCP6_MESSAGE_INFORMATION_REQUEST,
index c7a58e95cc45113ee636e423e488519640dbd89c..a9189360fdd24ac0b79fab4e202d58a0e0e5057a 100644 (file)
@@ -48,7 +48,7 @@
         do {                                                             \
                 sd_bus_message *_mm = (m);                               \
                 log_debug("Got message type=%s sender=%s destination=%s path=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " signature=%s error-name=%s error-message=%s", \
-                          bus_message_type_to_string(_mm->header->type), \
+                          strna(bus_message_type_to_string(_mm->header->type)), \
                           strna(sd_bus_message_get_sender(_mm)),         \
                           strna(sd_bus_message_get_destination(_mm)),    \
                           strna(sd_bus_message_get_path(_mm)),           \
index 7ea964acf9947a53a4a29bd9f4a1ffb8eb5af3bd..09325aae0454d7eedff31a5b1ffe8c3c02475465 100644 (file)
@@ -55,7 +55,7 @@ struct sd_device {
         dev_t devnum;
 
         char **properties_strv; /* the properties hashmap as a strv */
-        uint8_t *properties_nulstr; /* the same as a nulstr */
+        char *properties_nulstr; /* the same as a nulstr */
         size_t properties_nulstr_len;
 
         char *syspath;
index 80cb0ce622ca25d44222c4c32cc417e4e5cd47c6..e8913c3d1f8a3c3433d8bfdf384b78f76949f891 100644 (file)
@@ -508,7 +508,7 @@ int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret) {
                                                "sd-device-monitor: Invalid message header");
         }
 
-        r = device_new_from_nulstr(&device, (uint8_t*) &buf.raw[bufpos], buflen - bufpos);
+        r = device_new_from_nulstr(&device, &buf.raw[bufpos], buflen - bufpos);
         if (r < 0)
                 return log_debug_errno(r, "sd-device-monitor: Failed to create device from received message: %m");
 
@@ -574,7 +574,7 @@ int device_monitor_send_device(
         assert(m);
         assert(device);
 
-        r = device_get_properties_nulstr(device, (const uint8_t **) &buf, &blen);
+        r = device_get_properties_nulstr(device, &buf, &blen);
         if (r < 0)
                 return log_device_debug_errno(device, r, "sd-device-monitor: Failed to get device properties: %m");
         if (blen < 32)
index 4a5a110364c50867cc6f07b8419f61cecd418e8a..a45389991073c53d54aeef623bc4f3373dd0d11c 100644 (file)
@@ -356,6 +356,10 @@ static int device_amend(sd_device *device, const char *key, const char *value) {
                         if (r < 0)
                                 return log_device_debug_errno(device, r, "sd-device: Failed to add tag '%s': %m", word);
                 }
+        } else if (streq(key, "UDEV_DATABASE_VERSION")) {
+                r = safe_atou(value, &device->database_version);
+                if (r < 0)
+                        return log_device_debug_errno(device, r, "sd-device: Failed to parse udev database version '%s': %m", value);
         } else {
                 r = device_add_property_internal(device, key, value);
                 if (r < 0)
@@ -467,7 +471,7 @@ int device_new_from_strv(sd_device **ret, char **strv) {
         return 0;
 }
 
-int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
+int device_new_from_nulstr(sd_device **ret, char *nulstr, size_t len) {
         _cleanup_(sd_device_unrefp) sd_device *device = NULL;
         const char *major = NULL, *minor = NULL;
         int r;
@@ -484,7 +488,7 @@ int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
                 char *key;
                 const char *end;
 
-                key = (char*) &nulstr[i];
+                key = nulstr + i;
                 end = memchr(key, '\0', len - i);
                 if (!end)
                         return log_device_debug_errno(device, SYNTHETIC_ERRNO(EINVAL),
@@ -517,16 +521,24 @@ int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
 }
 
 static int device_update_properties_bufs(sd_device *device) {
+        _cleanup_free_ char **buf_strv = NULL, *buf_nulstr = NULL;
+        size_t nulstr_len = 0, num = 0;
         const char *val, *prop;
-        _cleanup_free_ char **buf_strv = NULL;
-        _cleanup_free_ uint8_t *buf_nulstr = NULL;
-        size_t nulstr_len = 0, num = 0, i = 0;
 
         assert(device);
 
         if (!device->properties_buf_outdated)
                 return 0;
 
+        /* append udev database version */
+        buf_nulstr = newdup(char, "UDEV_DATABASE_VERSION=" STRINGIFY(LATEST_UDEV_DATABASE_VERSION) "\0",
+                            STRLEN("UDEV_DATABASE_VERSION=" STRINGIFY(LATEST_UDEV_DATABASE_VERSION)) + 2);
+        if (!buf_nulstr)
+                return -ENOMEM;
+
+        nulstr_len += STRLEN("UDEV_DATABASE_VERSION=" STRINGIFY(LATEST_UDEV_DATABASE_VERSION)) + 1;
+        num++;
+
         FOREACH_DEVICE_PROPERTY(device, prop, val) {
                 size_t len = 0;
 
@@ -536,59 +548,58 @@ static int device_update_properties_bufs(sd_device *device) {
                 if (!buf_nulstr)
                         return -ENOMEM;
 
-                strscpyl((char *)buf_nulstr + nulstr_len, len + 1, prop, "=", val, NULL);
+                strscpyl(buf_nulstr + nulstr_len, len + 1, prop, "=", val, NULL);
                 nulstr_len += len + 1;
-                ++num;
+                num++;
         }
 
         /* build buf_strv from buf_nulstr */
-        buf_strv = new0(char *, num + 1);
+        buf_strv = new0(char*, num + 1);
         if (!buf_strv)
                 return -ENOMEM;
 
-        NULSTR_FOREACH(val, (char*) buf_nulstr) {
-                buf_strv[i] = (char *) val;
-                assert(i < num);
-                i++;
-        }
+        size_t i = 0;
+        char *p;
+        NULSTR_FOREACH(p, buf_nulstr)
+                buf_strv[i++] = p;
+        assert(i == num);
 
         free_and_replace(device->properties_nulstr, buf_nulstr);
         device->properties_nulstr_len = nulstr_len;
         free_and_replace(device->properties_strv, buf_strv);
 
         device->properties_buf_outdated = false;
-
         return 0;
 }
 
-int device_get_properties_nulstr(sd_device *device, const uint8_t **nulstr, size_t *len) {
+int device_get_properties_nulstr(sd_device *device, const char **ret_nulstr, size_t *ret_len) {
         int r;
 
         assert(device);
-        assert(nulstr);
-        assert(len);
 
         r = device_update_properties_bufs(device);
         if (r < 0)
                 return r;
 
-        *nulstr = device->properties_nulstr;
-        *len = device->properties_nulstr_len;
+        if (ret_nulstr)
+                *ret_nulstr = device->properties_nulstr;
+        if (ret_len)
+                *ret_len = device->properties_nulstr_len;
 
         return 0;
 }
 
-int device_get_properties_strv(sd_device *device, char ***strv) {
+int device_get_properties_strv(sd_device *device, char ***ret) {
         int r;
 
         assert(device);
-        assert(strv);
 
         r = device_update_properties_bufs(device);
         if (r < 0)
                 return r;
 
-        *strv = device->properties_strv;
+        if (ret)
+                *ret = device->properties_strv;
 
         return 0;
 }
index 5160f580069c0346dc240d2814aa7392e1a076d4..9602f9eda3e5f4e83d556d5ffeddbb8a9834c271 100644 (file)
@@ -10,7 +10,7 @@
 
 #include "macro.h"
 
-int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len);
+int device_new_from_nulstr(sd_device **ret, char *nulstr, size_t len);
 int device_new_from_strv(sd_device **ret, char **strv);
 int device_new_from_watch_handle_at(sd_device **ret, int dirfd, int wd);
 static inline int device_new_from_watch_handle(sd_device **ret, int wd) {
@@ -48,8 +48,8 @@ uint64_t device_get_tags_generation(sd_device *device);
 uint64_t device_get_devlinks_generation(sd_device *device);
 
 int device_properties_prepare(sd_device *device);
-int device_get_properties_nulstr(sd_device *device, const uint8_t **nulstr, size_t *len);
-int device_get_properties_strv(sd_device *device, char ***strv);
+int device_get_properties_nulstr(sd_device *device, const char **ret_nulstr, size_t *ret_len);
+int device_get_properties_strv(sd_device *device, char ***ret);
 
 int device_rename(sd_device *device, const char *name);
 int device_shallow_clone(sd_device *device, sd_device **ret);
index 5e3536be40b24253caf0a6ab2e291706eb116688..fa334df6c70cf78bd70d01853dea7f1d7d20dbc2 100644 (file)
@@ -317,9 +317,8 @@ TEST(sd_device_new_from_nulstr) {
                 "\0";
 
         _cleanup_(sd_device_unrefp) sd_device *device = NULL, *from_nulstr = NULL;
-        _cleanup_free_ uint8_t *nulstr_copy = NULL;
-        const char *devlink;
-        const uint8_t *nulstr;
+        _cleanup_free_ char *nulstr_copy = NULL;
+        const char *devlink, *nulstr;
         size_t len;
 
         assert_se(sd_device_new_from_syspath(&device, "/sys/class/net/lo") >= 0);
@@ -332,14 +331,29 @@ TEST(sd_device_new_from_nulstr) {
                 assert_se(set_contains(device->devlinks, devlink));
         }
 
+        /* For issue #23799 */
+        assert_se(device_add_tag(device, "tag1", false) >= 0);
+        assert_se(device_add_tag(device, "tag2", false) >= 0);
+        assert_se(device_add_tag(device, "current-tag1", true) >= 0);
+        assert_se(device_add_tag(device, "current-tag2", true) >= 0);
+
         /* These properties are necessary for device_new_from_nulstr(). See device_verify(). */
         assert_se(device_add_property_internal(device, "SEQNUM", "1") >= 0);
         assert_se(device_add_property_internal(device, "ACTION", "change") >= 0);
 
         assert_se(device_get_properties_nulstr(device, &nulstr, &len) >= 0);
-        assert_se(nulstr_copy = newdup(uint8_t, nulstr, len));
+        assert_se(nulstr_copy = newdup(char, nulstr, len));
         assert_se(device_new_from_nulstr(&from_nulstr, nulstr_copy, len) >= 0);
 
+        assert_se(sd_device_has_tag(from_nulstr, "tag1") == 1);
+        assert_se(sd_device_has_tag(from_nulstr, "tag2") == 1);
+        assert_se(sd_device_has_tag(from_nulstr, "current-tag1") == 1);
+        assert_se(sd_device_has_tag(from_nulstr, "current-tag2") == 1);
+        assert_se(sd_device_has_current_tag(from_nulstr, "tag1") == 0);
+        assert_se(sd_device_has_current_tag(from_nulstr, "tag2") == 0);
+        assert_se(sd_device_has_current_tag(from_nulstr, "current-tag1") == 1);
+        assert_se(sd_device_has_current_tag(from_nulstr, "current-tag2") == 1);
+
         NULSTR_FOREACH(devlink, devlinks) {
                 log_device_info(from_nulstr, "checking devlink: %s", devlink);
                 assert_se(set_contains(from_nulstr->devlinks, devlink));
index 9759f461631e8c6114e440a18d8ffca1b804dcc3..2d1b9826d0b832ec32c805e3ca657419223a5a4c 100644 (file)
@@ -843,7 +843,7 @@ int locale_gen_enable_locale(const char *locale) {
                         return r;
                 r = copy_xattr(fileno(fr), fileno(fw), COPY_ALL_XATTRS);
                 if (r < 0)
-                        return r;
+                        log_debug_errno(r, "Failed to copy all xattrs from old to new /etc/locale.gen file, ignoring: %m");
         }
 
         if (!write_new) {
index 43c8ca42fef082d663765a1076543cc01d1867be..ce5262fcd6907c8337c98c1204004f4095bb024a 100644 (file)
@@ -52,6 +52,10 @@ bool link_dhcp_enabled(Link *link, int family) {
         assert(link);
         assert(IN_SET(family, AF_INET, AF_INET6));
 
+        /* Currently, sd-dhcp-client supports only ethernet and infiniband. */
+        if (family == AF_INET && !IN_SET(link->iftype, ARPHRD_ETHER, ARPHRD_INFINIBAND))
+                return false;
+
         if (family == AF_INET6 && !socket_ipv6_is_supported())
                 return false;
 
@@ -61,13 +65,6 @@ bool link_dhcp_enabled(Link *link, int family) {
         if (link->iftype == ARPHRD_CAN)
                 return false;
 
-        if (!IN_SET(link->hw_addr.length, ETH_ALEN, INFINIBAND_ALEN) &&
-            !streq_ptr(link->kind, "wwan"))
-                /* Currently, only interfaces whose MAC address length is ETH_ALEN or INFINIBAND_ALEN
-                 * are supported. Note, wwan interfaces may be assigned MAC address slightly later.
-                 * Hence, let's wait for a while.*/
-                return false;
-
         if (!link->network)
                 return false;
 
index d3fd2571e0db29c70f950817a1ea301c7d43ce7c..0941ad026c46324c93b6ebfa502ae55dce5a7451 100644 (file)
@@ -1587,11 +1587,6 @@ static int dhcp4_process_request(Request *req, Link *link, void *userdata) {
         if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
                 return 0;
 
-        if (!IN_SET(link->hw_addr.length, ETH_ALEN, INFINIBAND_ALEN) ||
-            hw_addr_is_null(&link->hw_addr))
-                /* No MAC address is assigned to the hardware, or non-supported MAC address length. */
-                return 0;
-
         r = dhcp4_configure_duid(link);
         if (r <= 0)
                 return r;
index 5786eca8039e0ce0e4323394d5d1d2c2dea1d157..69fb855068fe681542ebd99e534fe3d635677aca 100644 (file)
@@ -743,11 +743,6 @@ static int dhcp6_process_request(Request *req, Link *link, void *userdata) {
         if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
                 return 0;
 
-        if (!IN_SET(link->hw_addr.length, ETH_ALEN, INFINIBAND_ALEN) ||
-            hw_addr_is_null(&link->hw_addr))
-                /* No MAC address is assigned to the hardware, or non-supported MAC address length. */
-                return 0;
-
         r = dhcp_configure_duid(link, link_get_dhcp6_duid(link));
         if (r <= 0)
                 return r;
index 63679505f70e728afbfdd73d949836298243b733..95f4bbe37544c51c6a3a9728d19d9555221c1b1c 100644 (file)
@@ -2191,7 +2191,7 @@ static int link_update_hardware_address(Link *link, sd_netlink_message *message)
         if (r < 0)
                 return log_link_debug_errno(link, r, "Could not update MAC address for Router Advertisement: %m");
 
-        if (link->ndisc) {
+        if (link->ndisc && link->hw_addr.length == ETH_ALEN) {
                 r = sd_ndisc_set_mac(link->ndisc, &link->hw_addr.ether);
                 if (r < 0)
                         return log_link_debug_errno(link, r, "Could not update MAC for NDisc: %m");
index efe407fedb563f185ce1888059409953141adca3..23f302ba998ad80c54cf24e7daa8c4bbf2c35af8 100644 (file)
@@ -38,12 +38,6 @@ bool link_ipv6_accept_ra_enabled(Link *link) {
         if (link->iftype == ARPHRD_CAN)
                 return false;
 
-        if (link->hw_addr.length != ETH_ALEN && !streq_ptr(link->kind, "wwan"))
-                /* Currently, only interfaces whose MAC address length is ETH_ALEN are supported.
-                 * Note, wwan interfaces may be assigned MAC address slightly later.
-                 * Hence, let's wait for a while.*/
-                return false;
-
         if (!link->network)
                 return false;
 
@@ -1077,9 +1071,11 @@ static int ndisc_configure(Link *link) {
         if (r < 0)
                 return r;
 
-        r = sd_ndisc_set_mac(link->ndisc, &link->hw_addr.ether);
-        if (r < 0)
-                return r;
+        if (link->hw_addr.length == ETH_ALEN) {
+                r = sd_ndisc_set_mac(link->ndisc, &link->hw_addr.ether);
+                if (r < 0)
+                        return r;
+        }
 
         r = sd_ndisc_set_ifindex(link->ndisc, link->ifindex);
         if (r < 0)
@@ -1123,10 +1119,6 @@ static int ndisc_process_request(Request *req, Link *link, void *userdata) {
         if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
                 return 0;
 
-        if (link->hw_addr.length != ETH_ALEN || hw_addr_is_null(&link->hw_addr))
-                /* No MAC address is assigned to the hardware, or non-supported MAC address length. */
-                return 0;
-
         r = ndisc_configure(link);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to configure IPv6 Router Discovery: %m");
index 7fc1306d199ac4d9c686da05ebc1c95814d92e41..442f99ed86b932d8d682e09c02b6e7942b1f5fd9 100644 (file)
@@ -458,9 +458,11 @@ static int radv_configure(Link *link) {
         if (r < 0)
                 return r;
 
-        r = sd_radv_set_mac(link->radv, &link->hw_addr.ether);
-        if (r < 0)
-                return r;
+        if (link->hw_addr.length == ETH_ALEN) {
+                r = sd_radv_set_mac(link->radv, &link->hw_addr.ether);
+                if (r < 0)
+                        return r;
+        }
 
         r = sd_radv_set_ifindex(link->radv, link->ifindex);
         if (r < 0)
@@ -518,6 +520,9 @@ int radv_update_mac(Link *link) {
         if (!link->radv)
                 return 0;
 
+        if (link->hw_addr.length != ETH_ALEN)
+                return 0;
+
         restart = sd_radv_is_running(link->radv);
 
         r = sd_radv_stop(link->radv);
index 31dcf0ffdf14f47c3f00bc85d816789e66994c32..978f5373375198580eefa8d333de7755aeaebe19 100644 (file)
@@ -223,7 +223,7 @@ static int run(int argc, char *argv[]) {
 
         r = maybe_resize_underlying_device(arg_target, devno);
         if (r < 0)
-                return r;
+                log_warning_errno(r, "Unable to resize underlying device of \"%s\", proceeding anyway: %m", arg_target);
 
         mountfd = open(arg_target, O_RDONLY|O_CLOEXEC);
         if (mountfd < 0)
@@ -241,6 +241,10 @@ static int run(int argc, char *argv[]) {
                 return log_error_errno(errno, "Failed to query size of \"%s\": %m", devpath);
 
         log_debug("Resizing \"%s\" to %"PRIu64" bytes...", arg_target, size);
+
+        if (arg_dry_run)
+                return 0;
+
         r = resize_fs(mountfd, size, &newsize);
         if (r < 0)
                 return log_error_errno(r, "Failed to resize \"%s\" to %"PRIu64" bytes: %m",
index 051242e836c5e5a575c361b8bf7090371dfcfd91..d493f2572907df078a45baa8241eb8af8cd79309 100644 (file)
@@ -1611,9 +1611,9 @@ static int context_load_partition_table(
 
         if (*backing_fd < 0) {
                 /* If we have no fd referencing the device yet, make a copy of the fd now, so that we have one */
-                *backing_fd = fcntl(fdisk_get_devfd(c), F_DUPFD_CLOEXEC, 3);
+                *backing_fd = fd_reopen(fdisk_get_devfd(c), O_RDONLY|O_CLOEXEC);
                 if (*backing_fd < 0)
-                        return log_error_errno(errno, "Failed to duplicate fdisk fd: %m");
+                        return log_error_errno(*backing_fd, "Failed to duplicate fdisk fd: %m");
         }
 
         /* Tell udev not to interfere while we are processing the device */
index 9a6af70b93989a73dbcd903a5ecd578402e8caae..04deeb2262e1696141b430bd19d01343be3bd49b 100644 (file)
@@ -1,7 +1,8 @@
-# The "trusted" profile for services, i.e. no restrictions are applied
+# The "trusted" profile for services, i.e. no restrictions are applied apart from a private /tmp
 
 [Service]
 MountAPIVFS=yes
+PrivateTmp=yes
 BindPaths=/run
 BindReadOnlyPaths=/etc/machine-id
 BindReadOnlyPaths=/etc/resolv.conf
index 409f1d046428113d14b58e7f985c19b173eaff31..d6f7a90ac73b25523ccf8925ab2c90e90d61a85c 100644 (file)
@@ -1249,13 +1249,14 @@ int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_
         return 1;
 }
 
-int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
+int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p, usec_t ts, unsigned max_rr) {
         unsigned ancount = 0;
         DnsCacheItem *i;
         int r;
 
         assert(cache);
         assert(p);
+        assert(p->protocol == DNS_PROTOCOL_MDNS);
 
         HASHMAP_FOREACH(i, cache->by_key)
                 LIST_FOREACH(by_key, j, i) {
@@ -1265,11 +1266,19 @@ int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
                         if (!j->shared_owner)
                                 continue;
 
+                        /* RFC6762 7.1: Don't append records with less than half the TTL remaining
+                         * as known answers. */
+                        if (usec_sub_unsigned(j->until, ts) < j->rr->ttl * USEC_PER_SEC / 2)
+                                continue;
+
                         r = dns_packet_append_rr(p, j->rr, 0, NULL, NULL);
-                        if (r == -EMSGSIZE && p->protocol == DNS_PROTOCOL_MDNS) {
-                                /* For mDNS, if we're unable to stuff all known answers into the given packet,
-                                 * allocate a new one, push the RR into that one and link it to the current one.
-                                 */
+                        if (r == -EMSGSIZE) {
+                                if (max_rr == 0)
+                                        /* If max_rr == 0, do not allocate more packets. */
+                                        goto finalize;
+
+                                /* If we're unable to stuff all known answers into the given packet, allocate
+                                 * a new one, push the RR into that one and link it to the current one. */
 
                                 DNS_PACKET_HEADER(p)->ancount = htobe16(ancount);
                                 ancount = 0;
@@ -1287,8 +1296,21 @@ int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
                                 return r;
 
                         ancount++;
+                        if (max_rr > 0 && ancount >= max_rr) {
+                                DNS_PACKET_HEADER(p)->ancount = htobe16(ancount);
+                                ancount = 0;
+
+                                r = dns_packet_new_query(&p->more, p->protocol, 0, true);
+                                if (r < 0)
+                                        return r;
+
+                                p = p->more;
+
+                                max_rr = UINT_MAX;
+                        }
                 }
 
+finalize:
         DNS_PACKET_HEADER(p)->ancount = htobe16(ancount);
 
         return 0;
index 621b52f8926f8267bc55fde75fe93366bef18e1d..fb2e61a65bcab73140dd6f54d585b3ec20410454 100644 (file)
@@ -53,4 +53,4 @@ bool dns_cache_is_empty(DnsCache *cache);
 
 unsigned dns_cache_size(DnsCache *cache);
 
-int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p);
+int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p, usec_t ts, unsigned max_rr);
index a872e9d255017325d24d3e49c9e0ea9113672769..8fd987bd824d05b7b872d894974cd035673ace74 100644 (file)
@@ -692,6 +692,11 @@ DnsScopeMatch dns_scope_good_domain(
                 if (has_search_domains && dns_name_is_single_label(domain))
                         return DNS_SCOPE_YES_BASE + 1;
 
+                /* If ResolveUnicastSingleLabel=yes and the query is single-label, then bump match result
+                   to prevent LLMNR monopoly among candidates. */
+                if (s->manager->resolve_unicast_single_label && dns_name_is_single_label(domain))
+                        return DNS_SCOPE_YES_BASE + 1;
+
                 /* Let's return the number of labels in the best matching result */
                 if (n_best >= 0) {
                         assert(n_best <= DNS_SCOPE_YES_END - DNS_SCOPE_YES_BASE);
@@ -1011,7 +1016,9 @@ void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
                 return;
         }
 
-        assert(dns_question_size(p->question) == 1);
+        if (dns_question_size(p->question) != 1)
+                return (void) log_debug("Received LLMNR query without question or multiple questions, ignoring.");
+
         key = dns_question_first_key(p->question);
 
         r = dns_zone_lookup(&s->zone, key, 0, &answer, &soa, &tentative);
@@ -1204,7 +1211,6 @@ static int on_conflict_dispatch(sd_event_source *es, usec_t usec, void *userdata
 }
 
 int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr) {
-        usec_t jitter;
         int r;
 
         assert(scope);
@@ -1233,15 +1239,12 @@ int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr) {
         if (scope->conflict_event_source)
                 return 0;
 
-        random_bytes(&jitter, sizeof(jitter));
-        jitter %= LLMNR_JITTER_INTERVAL_USEC;
-
         r = sd_event_add_time_relative(
                         scope->manager->event,
                         &scope->conflict_event_source,
                         CLOCK_BOOTTIME,
-                        jitter,
-                        LLMNR_JITTER_INTERVAL_USEC,
+                        random_u64_range(LLMNR_JITTER_INTERVAL_USEC),
+                        0,
                         on_conflict_dispatch, scope);
         if (r < 0)
                 return log_debug_errno(r, "Failed to add conflict dispatch event: %m");
@@ -1511,7 +1514,7 @@ int dns_scope_announce(DnsScope *scope, bool goodbye) {
                                 &scope->announce_event_source,
                                 CLOCK_BOOTTIME,
                                 MDNS_ANNOUNCE_DELAY,
-                                MDNS_JITTER_RANGE_USEC,
+                                0,
                                 on_announcement_timeout, scope);
                 if (r < 0)
                         return log_debug_errno(r, "Failed to schedule second announcement: %m");
index eee664057f38a247a8354fd76cd53592ae98a36d..91c3c85262c1bbc049a6f36cfc5f046f355ffb21 100644 (file)
@@ -1553,6 +1553,33 @@ static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdat
         return 0;
 }
 
+static int dns_transaction_setup_timeout(
+                DnsTransaction *t,
+                usec_t timeout_usec /* relative */,
+                usec_t next_usec /* CLOCK_BOOTTIME */) {
+
+        int r;
+
+        assert(t);
+
+        dns_transaction_stop_timeout(t);
+
+        r = sd_event_add_time_relative(
+                t->scope->manager->event,
+                &t->timeout_event_source,
+                CLOCK_BOOTTIME,
+                timeout_usec, 0,
+                on_transaction_timeout, t);
+        if (r < 0)
+                return r;
+
+        (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
+
+        t->next_attempt_after = next_usec;
+        t->state = DNS_TRANSACTION_PENDING;
+        return 0;
+}
+
 static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
         assert(t);
         assert(t->scope);
@@ -1570,11 +1597,12 @@ static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
                 return DNS_TIMEOUT_USEC;
 
         case DNS_PROTOCOL_MDNS:
-                assert(t->n_attempts > 0);
                 if (t->probing)
                         return MDNS_PROBING_INTERVAL_USEC;
-                else
-                        return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
+
+                /* See RFC 6762 Section 5.1 suggests that timeout should be a few seconds. */
+                assert(t->n_attempts > 0);
+                return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
 
         case DNS_PROTOCOL_LLMNR:
                 return t->scope->resend_timeout;
@@ -1754,13 +1782,30 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
         return 1;
 }
 
+static int dns_packet_append_zone(DnsPacket *p, DnsTransaction *t, DnsResourceKey *k, unsigned *nscount) {
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        bool tentative;
+        int r;
+
+        assert(p);
+        assert(t);
+        assert(k);
+
+        if (k->type != DNS_TYPE_ANY)
+                return 0;
+
+        r = dns_zone_lookup(&t->scope->zone, k, t->scope->link->ifindex, &answer, NULL, &tentative);
+        if (r < 0)
+                return r;
+
+        return dns_packet_append_answer(p, answer, nscount);
+}
+
 static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
-        bool add_known_answers = false;
-        DnsResourceKey *tkey;
         _cleanup_set_free_ Set *keys = NULL;
-        unsigned qdcount;
-        unsigned nscount = 0;
+        unsigned qdcount, ancount = 0 /* avoid false maybe-uninitialized warning */, nscount;
+        bool add_known_answers = false;
         usec_t ts;
         int r;
 
@@ -1770,6 +1815,7 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
         /* Discard any previously prepared packet, so we can start over and coalesce again */
         t->sent = dns_packet_unref(t->sent);
 
+        /* First, create a dummy packet to calculate packet size. */
         r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
         if (r < 0)
                 return r;
@@ -1783,11 +1829,14 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
         if (dns_key_is_shared(dns_transaction_key(t)))
                 add_known_answers = true;
 
-        if (dns_transaction_key(t)->type == DNS_TYPE_ANY) {
-                r = set_ensure_put(&keys, &dns_resource_key_hash_ops, dns_transaction_key(t));
-                if (r < 0)
-                        return r;
-        }
+        r = dns_packet_append_zone(p, t, dns_transaction_key(t), NULL);
+        if (r < 0)
+                return r;
+
+        /* Save appended keys */
+        r = set_ensure_put(&keys, &dns_resource_key_hash_ops, dns_transaction_key(t));
+        if (r < 0)
+                return r;
 
         /*
          * For mDNS, we want to coalesce as many open queries in pending transactions into one single
@@ -1797,90 +1846,114 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
 
         assert_se(sd_event_now(t->scope->manager->event, CLOCK_BOOTTIME, &ts) >= 0);
 
-        LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
-
-                /* Skip ourselves */
-                if (other == t)
-                        continue;
+        for (bool restart = true; restart;) {
+                restart = false;
+                LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
+                        size_t saved_packet_size;
+                        bool append = false;
 
-                if (other->state != DNS_TRANSACTION_PENDING)
-                        continue;
-
-                if (other->next_attempt_after > ts)
-                        continue;
-
-                if (qdcount >= UINT16_MAX)
-                        break;
+                        /* Skip ourselves */
+                        if (other == t)
+                                continue;
 
-                r = dns_packet_append_key(p, dns_transaction_key(other), 0, NULL);
+                        if (other->state != DNS_TRANSACTION_PENDING)
+                                continue;
 
-                /*
-                 * If we can't stuff more questions into the packet, just give up.
-                 * One of the 'other' transactions will fire later and take care of the rest.
-                 */
-                if (r == -EMSGSIZE)
-                        break;
+                        if (other->next_attempt_after > ts)
+                                continue;
 
-                if (r < 0)
-                        return r;
+                        if (!set_contains(keys, dns_transaction_key(other))) {
+                                r = dns_packet_append_key(p, dns_transaction_key(other), 0, &saved_packet_size);
+                                /* If we can't stuff more questions into the packet, just give up.
+                                 * One of the 'other' transactions will fire later and take care of the rest. */
+                                if (r == -EMSGSIZE)
+                                        break;
+                                if (r < 0)
+                                        return r;
 
-                r = dns_transaction_prepare(other, ts);
-                if (r <= 0)
-                        continue;
+                                r = dns_packet_append_zone(p, t, dns_transaction_key(other), NULL);
+                                if (r == -EMSGSIZE)
+                                        break;
+                                if (r < 0)
+                                        return r;
 
-                ts += transaction_get_resend_timeout(other);
+                                append = true;
+                        }
 
-                r = sd_event_add_time(
-                                other->scope->manager->event,
-                                &other->timeout_event_source,
-                                CLOCK_BOOTTIME,
-                                ts, 0,
-                                on_transaction_timeout, other);
-                if (r < 0)
-                        return r;
+                        r = dns_transaction_prepare(other, ts);
+                        if (r < 0)
+                                return r;
+                        if (r == 0) {
+                                if (append)
+                                        dns_packet_truncate(p, saved_packet_size);
 
-                (void) sd_event_source_set_description(other->timeout_event_source, "dns-transaction-timeout");
+                                /* In this case, not only this transaction, but multiple transactions may be
+                                 * freed. Hence, we need to restart the loop. */
+                                restart = true;
+                                break;
+                        }
 
-                other->state = DNS_TRANSACTION_PENDING;
-                other->next_attempt_after = ts;
+                        usec_t timeout = transaction_get_resend_timeout(other);
+                        r = dns_transaction_setup_timeout(other, timeout, usec_add(ts, timeout));
+                        if (r < 0)
+                                return r;
 
-                qdcount++;
+                        if (dns_key_is_shared(dns_transaction_key(other)))
+                                add_known_answers = true;
 
-                if (dns_key_is_shared(dns_transaction_key(other)))
-                        add_known_answers = true;
+                        if (append) {
+                                r = set_ensure_put(&keys, &dns_resource_key_hash_ops, dns_transaction_key(other));
+                                if (r < 0)
+                                        return r;
+                        }
 
-                if (dns_transaction_key(other)->type == DNS_TYPE_ANY) {
-                        r = set_ensure_put(&keys, &dns_resource_key_hash_ops, dns_transaction_key(other));
-                        if (r < 0)
-                                return r;
+                        qdcount++;
+                        if (qdcount >= UINT16_MAX)
+                                break;
                 }
         }
 
-        DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
-
         /* Append known answer section if we're asking for any shared record */
         if (add_known_answers) {
-                r = dns_cache_export_shared_to_packet(&t->scope->cache, p);
+                r = dns_cache_export_shared_to_packet(&t->scope->cache, p, ts, 0);
                 if (r < 0)
                         return r;
+
+                ancount = be16toh(DNS_PACKET_HEADER(p)->ancount);
         }
 
-        SET_FOREACH(tkey, keys) {
-                _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
-                bool tentative;
+        /* Then, create acctual packet. */
+        p = dns_packet_unref(p);
+        r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
+        if (r < 0)
+                return r;
 
-                r = dns_zone_lookup(&t->scope->zone, tkey, t->scope->link->ifindex, &answer, NULL, &tentative);
+        /* Questions */
+        DnsResourceKey *k;
+        SET_FOREACH(k, keys) {
+                r = dns_packet_append_key(p, k, 0, NULL);
                 if (r < 0)
                         return r;
+        }
+        DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
 
-                r = dns_packet_append_answer(p, answer, &nscount);
+        /* Known answers */
+        if (add_known_answers) {
+                r = dns_cache_export_shared_to_packet(&t->scope->cache, p, ts, ancount);
+                if (r < 0)
+                        return r;
+        }
+
+        /* Authorities */
+        nscount = 0;
+        SET_FOREACH(k, keys) {
+                r = dns_packet_append_zone(p, t, k, &nscount);
                 if (r < 0)
                         return r;
         }
         DNS_PACKET_HEADER(p)->nscount = htobe16(nscount);
 
         t->sent = TAKE_PTR(p);
-
         return 0;
 }
 
@@ -1952,45 +2025,36 @@ int dns_transaction_go(DnsTransaction *t) {
 
         if (!t->initial_jitter_scheduled &&
             IN_SET(t->scope->protocol, DNS_PROTOCOL_LLMNR, DNS_PROTOCOL_MDNS)) {
-                usec_t jitter, accuracy;
+                usec_t jitter;
 
-                /* RFC 4795 Section 2.7 suggests all queries should be delayed by a random time from 0 to
-                 * JITTER_INTERVAL. */
+                /* RFC 4795 Section 2.7 suggests all LLMNR queries should be delayed by a random time from 0 to
+                 * JITTER_INTERVAL.
+                 * RFC 6762 Section 8.1 suggests initial probe queries should be delayed by a random time from
+                 * 0 to 250ms. */
 
                 t->initial_jitter_scheduled = true;
+                t->n_attempts = 0;
 
                 switch (t->scope->protocol) {
 
                 case DNS_PROTOCOL_LLMNR:
                         jitter = random_u64_range(LLMNR_JITTER_INTERVAL_USEC);
-                        accuracy = LLMNR_JITTER_INTERVAL_USEC;
                         break;
 
                 case DNS_PROTOCOL_MDNS:
-                        jitter = usec_add(random_u64_range(MDNS_JITTER_RANGE_USEC), MDNS_JITTER_MIN_USEC);
-                        accuracy = MDNS_JITTER_RANGE_USEC;
+                        if (t->probing)
+                                jitter = random_u64_range(MDNS_PROBING_INTERVAL_USEC);
+                        else
+                                jitter = 0;
                         break;
                 default:
                         assert_not_reached();
                 }
 
-                assert(!t->timeout_event_source);
-
-                r = sd_event_add_time_relative(
-                                t->scope->manager->event,
-                                &t->timeout_event_source,
-                                CLOCK_BOOTTIME,
-                                jitter, accuracy,
-                                on_transaction_timeout, t);
+                r = dns_transaction_setup_timeout(t, jitter, ts);
                 if (r < 0)
                         return r;
 
-                (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
-
-                t->n_attempts = 0;
-                t->next_attempt_after = ts;
-                t->state = DNS_TRANSACTION_PENDING;
-
                 log_debug("Delaying %s transaction %" PRIu16 " for " USEC_FMT "us.",
                           dns_protocol_to_string(t->scope->protocol),
                           t->id,
@@ -2064,22 +2128,11 @@ int dns_transaction_go(DnsTransaction *t) {
                 return dns_transaction_go(t);
         }
 
-        ts += transaction_get_resend_timeout(t);
-
-        r = sd_event_add_time(
-                        t->scope->manager->event,
-                        &t->timeout_event_source,
-                        CLOCK_BOOTTIME,
-                        ts, 0,
-                        on_transaction_timeout, t);
+        usec_t timeout = transaction_get_resend_timeout(t);
+        r = dns_transaction_setup_timeout(t, timeout, usec_add(ts, timeout));
         if (r < 0)
                 return r;
 
-        (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
-
-        t->state = DNS_TRANSACTION_PENDING;
-        t->next_attempt_after = ts;
-
         return 1;
 }
 
index 498cabb7e501b56e4b09bb0281e52c1e9374c860..ab86f0f01f55f7c8c867c95a74369dec6b7b15f3 100644 (file)
@@ -201,10 +201,6 @@ DnsTransactionSource dns_transaction_source_from_string(const char *s) _pure_;
 /* LLMNR Jitter interval, see RFC 4795 Section 7 */
 #define LLMNR_JITTER_INTERVAL_USEC (100 * USEC_PER_MSEC)
 
-/* mDNS Jitter interval, see RFC 6762 Section 5.2 */
-#define MDNS_JITTER_MIN_USEC   (20 * USEC_PER_MSEC)
-#define MDNS_JITTER_RANGE_USEC (100 * USEC_PER_MSEC)
-
 /* mDNS probing interval, see RFC 6762 Section 8.1 */
 #define MDNS_PROBING_INTERVAL_USEC (250 * USEC_PER_MSEC)
 
index d5c71f4080265d45858332ff523833df17d03d25..e1965c3833d80828771fa1bdecb85f2747ac0adb 100644 (file)
@@ -177,8 +177,6 @@ static int mdns_do_tiebreak(DnsResourceKey *key, DnsAnswer *answer, DnsPacket *p
         if (r < 0)
                 return r;
 
-        assert(r > 0);
-
         if (proposed_rrs_cmp(remote, r, our, size) > 0)
                 return 1;
 
@@ -207,10 +205,10 @@ static bool mdns_should_reply_using_unicast(DnsPacket *p) {
         }
 
         /* All the questions in the query had a QU bit set, RFC 6762, section 5.4 */
-        DNS_QUESTION_FOREACH_ITEM(item, p->question) {
+        DNS_QUESTION_FOREACH_ITEM(item, p->question)
                 if (!FLAGS_SET(item->flags, DNS_QUESTION_WANTS_UNICAST_REPLY))
                         return false;
-        }
+
         return true;
 }
 
@@ -256,7 +254,8 @@ static int mdns_scope_process_query(DnsScope *s, DnsPacket *p) {
         if (r < 0)
                 return log_debug_errno(r, "Failed to extract resource records from incoming packet: %m");
 
-        assert_return((dns_question_size(p->question) > 0), -EINVAL);
+        if (dns_question_size(p->question) <= 0)
+                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Received mDNS query without question, ignoring.");
 
         unicast_reply = mdns_should_reply_using_unicast(p);
         if (unicast_reply && !sender_on_local_subnet(s, p)) {
@@ -410,12 +409,28 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us
                         }
                 }
 
-                LIST_FOREACH(transactions_by_scope, t, scope->transactions) {
-                        r = dns_answer_match_key(p->answer, t->key, NULL);
-                        if (r < 0)
-                                log_debug_errno(r, "Failed to match resource key, ignoring: %m");
-                        else if (r > 0) /* This packet matches the transaction, let's pass it on as reply */
+                for (bool match = true; match;) {
+                        match = false;
+                        LIST_FOREACH(transactions_by_scope, t, scope->transactions) {
+                                if (t->state != DNS_TRANSACTION_PENDING)
+                                        continue;
+
+                                r = dns_answer_match_key(p->answer, dns_transaction_key(t), NULL);
+                                if (r <= 0) {
+                                        if (r < 0)
+                                                log_debug_errno(r, "Failed to match resource key, ignoring: %m");
+                                        continue;
+                                }
+
+                                /* This packet matches the transaction, let's pass it on as reply */
                                 dns_transaction_process_reply(t, p, false);
+
+                                /* The dns_transaction_process_reply() -> dns_transaction_complete() ->
+                                 * dns_query_candidate_stop() may free multiple transactions. Hence, restart
+                                 * the loop. */
+                                match = true;
+                                break;
+                        }
                 }
 
                 dns_cache_put(&scope->cache, scope->manager->enable_cache, NULL, DNS_PACKET_RCODE(p), p->answer, NULL, false, _DNSSEC_RESULT_INVALID, UINT32_MAX, p->family, &p->sender);
index 6dacc1d20ae1af591ada29b1302918611396ca48..cd8ea493199330945b3620983391596cb13db9c5 100644 (file)
@@ -31,7 +31,7 @@ typedef struct BaseFilesystem {
 static const BaseFilesystem table[] = {
         { "bin",      0, "usr/bin\0",                  NULL },
         { "lib",      0, "usr/lib\0",                  NULL },
-        { "root",  0755, NULL,                         NULL, true },
+        { "root",  0750, NULL,                         NULL, true },
         { "sbin",     0, "usr/sbin\0",                 NULL },
         { "usr",   0755, NULL,                         NULL },
         { "var",   0755, NULL,                         NULL },
index e76e4a0b389c16b3beab1905ad8bd63321d01453..0c8dec76887052ac107863946efe21ca42ab273f 100644 (file)
@@ -7,7 +7,9 @@
 #include <sys/statvfs.h>
 #include <unistd.h>
 #include <linux/loop.h>
+#if WANT_LINUX_FS_H
 #include <linux/fs.h>
+#endif
 
 #include "alloc-util.h"
 #include "chase-symlinks.h"
index 174f5ea3e8b0b01c8d013aa4f508fd895c0c4a45..a3d31140d8b573a8e3f93092ba9f640548e35341 100644 (file)
@@ -23,4 +23,4 @@
 #HibernateState=disk
 #HybridSleepMode=suspend platform shutdown
 #HybridSleepState=disk
-#HibernateDelaySec=180min
+#HibernateDelaySec=120min
index 6a71bce5fb267a85d5ad541f1e592080fe8743ee..60b956d6142a01c1c81dab64ddcc2a74bfef1146 100644 (file)
@@ -705,13 +705,14 @@ int maybe_extend_with_unit_dependencies(sd_bus *bus, char ***list) {
 int unit_get_dependencies(sd_bus *bus, const char *name, char ***ret) {
         _cleanup_strv_free_ char **deps = NULL;
 
-        static const struct bus_properties_map map[_DEPENDENCY_MAX][6] = {
+        static const struct bus_properties_map map[_DEPENDENCY_MAX][7] = {
                 [DEPENDENCY_FORWARD] = {
                         { "Requires",    "as", NULL, 0 },
                         { "Requisite",   "as", NULL, 0 },
                         { "Wants",       "as", NULL, 0 },
                         { "ConsistsOf",  "as", NULL, 0 },
                         { "BindsTo",     "as", NULL, 0 },
+                        { "Upholds",     "as", NULL, 0 },
                         {}
                 },
                 [DEPENDENCY_REVERSE] = {
@@ -720,6 +721,7 @@ int unit_get_dependencies(sd_bus *bus, const char *name, char ***ret) {
                         { "WantedBy",    "as", NULL, 0 },
                         { "PartOf",      "as", NULL, 0 },
                         { "BoundBy",     "as", NULL, 0 },
+                        { "UpheldBy",    "as", NULL, 0 },
                         {}
                 },
                 [DEPENDENCY_AFTER] = {
index e121429640ba4d76558718772f170b04643f552c..f7db3706ff4b9bb1f3fed776a1e7a9da24d46e81 100644 (file)
@@ -85,7 +85,7 @@ typedef void (*_sd_destroy_t)(void *userdata);
 #endif
 
 #ifndef _SD_ARRAY_STATIC
-#  if __STDC_VERSION__ >= 199901L
+#  if __STDC_VERSION__ >= 199901L && !defined(__cplusplus)
 #    define _SD_ARRAY_STATIC static
 #  else
 #    define _SD_ARRAY_STATIC
index d5db0304d5236910d2f835609e948498e7e365ef..53cd57036ded92240976b690767a0fe85dcd8906 100644 (file)
@@ -1614,15 +1614,12 @@ static int create_directory_or_subvolume(const char *path, mode_t mode, bool sub
                         r = btrfs_is_subvol(empty_to_root(arg_root)) > 0;
                 }
                 if (!r)
-                        /* Don't create a subvolume unless the root directory is
-                         * one, too. We do this under the assumption that if the
-                         * root directory is just a plain directory (i.e. very
-                         * light-weight), we shouldn't try to split it up into
-                         * subvolumes (i.e. more heavy-weight). Thus, chroot()
-                         * environments and suchlike will get a full brtfs
-                         * subvolume set up below their tree only if they
-                         * specifically set up a btrfs subvolume for the root
-                         * dir too. */
+                        /* Don't create a subvolume unless the root directory is one, too. We do this under
+                         * the assumption that if the root directory is just a plain directory (i.e. very
+                         * light-weight), we shouldn't try to split it up into subvolumes (i.e. more
+                         * heavy-weight). Thus, chroot() environments and suchlike will get a full brtfs
+                         * subvolume set up below their tree only if they specifically set up a btrfs
+                         * subvolume for the root dir too. */
 
                         subvol = false;
                 else {
@@ -1642,7 +1639,7 @@ static int create_directory_or_subvolume(const char *path, mode_t mode, bool sub
                 if (!IN_SET(r, -EEXIST, -EROFS))
                         return log_error_errno(r, "Failed to create directory or subvolume \"%s\": %m", path);
 
-                k = is_dir_fd(pfd);
+                k = is_dir_full(pfd, basename(path), /* follow= */ false);
                 if (k == -ENOENT && r == -EROFS)
                         return log_error_errno(r, "%s does not exist and cannot be created as the file system is read-only.", path);
                 if (k < 0)
index 478db198aced4ffe356a9394ecae678f46c82955..a12697275ced6fd57a8eb435acb6aa0cd9567db5 100644 (file)
@@ -2064,7 +2064,7 @@ static int main_loop(Manager *manager) {
 
         r = udev_rules_apply_static_dev_perms(manager->rules);
         if (r < 0)
-                log_error_errno(r, "Failed to apply permissions on static device nodes: %m");
+                log_warning_errno(r, "Failed to apply permissions on static device nodes, ignoring: %m");
 
         notify_ready();
 
index ac7e7ba01633ed9f6760392a2d65bc853dd3f1f1..b813621055f4ce9c69d7594e706910c414b1a482 100755 (executable)
@@ -41,6 +41,7 @@ if [ -z "${image_dir}" ] || [ ! -d "${image_dir}" ]; then
 fi
 
 dd if=/dev/zero of="${image_dir}/image" bs=1048576 count=64 || exit 1
+dd if=/dev/zero of="${image_dir}/data" bs=1048576 count=64 || exit 1
 loop="$(losetup --show -f "${image_dir}/image")"
 
 if [[ ! -e ${loop} ]]; then
@@ -48,10 +49,18 @@ if [[ ! -e ${loop} ]]; then
     exit 1
 fi
 
+# Do one iteration with a separate data device, to test those branches
+separate_data=1
+
 for algorithm in crc32c crc32 sha1 sha256
 do
-    integritysetup format "${loop}" --batch-mode -I "${algorithm}" || exit 1
-    integritysetup open -I "${algorithm}" "${loop}" "${DM_NAME}" || exit 1
+    if [ "${separate_data}" -eq 1 ]; then
+        data_option="--data-device=${image_dir}/data"
+    else
+        data_option=""
+    fi
+    integritysetup format "${loop}" --batch-mode -I "${algorithm}" "${data_option}" || exit 1
+    integritysetup open -I "${algorithm}" "${loop}" "${DM_NAME}" "${data_option}" || exit 1
     mkfs.ext4 -U "${FS_UUID}" "${FULL_DM_DEV_NAME}" || exit 1
 
     # Give userspace time to handle udev events for new FS showing up ...
@@ -60,7 +69,12 @@ do
     integritysetup close "${DM_NAME}" || exit 1
 
     # create integritytab, generate units, start service
-    build_integrity_tab ${algorithm}
+    if [ "${separate_data}" -eq 1 ]; then
+        data_option=",data-device=${image_dir}/data"
+    else
+        data_option=""
+    fi
+    build_integrity_tab "${algorithm}${data_option}"
 
     # Cause the generator to re-run
     systemctl daemon-reload || exit 1
@@ -77,7 +91,13 @@ do
 
     # Check the signature on the FS to ensure we can retrieve it and that is matches
     if [ -e "${FULL_DM_DEV_NAME}" ]; then
-        if [ "${FULL_DM_DEV_NAME}" != "$(blkid -U "${FS_UUID}")" ]; then
+        # If a separate device is used for the metadata storage, then blkid will return one of the loop devices
+        if [ "${separate_data}" -eq 1 ]; then
+            dev_name="$(integritysetup status ${DM_NAME} | grep '^\s*device:' | awk '{print $2}')"
+        else
+            dev_name="${FULL_DM_DEV_NAME}"
+        fi
+        if [ "${dev_name}" != "$(blkid -U "${FS_UUID}")" ]; then
             echo "Failed to locate FS with matching UUID!"
             exit 1
         fi
@@ -93,6 +113,7 @@ do
         exit 1
     fi
 
+    separate_data=0
 done
 
 echo OK >/testok