]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #15872 from keszybz/networkd-types
authorLennart Poettering <lennart@poettering.net>
Mon, 25 May 2020 15:31:00 +0000 (17:31 +0200)
committerGitHub <noreply@github.com>
Mon, 25 May 2020 15:31:00 +0000 (17:31 +0200)
Type and parsing fixes for networkd

51 files changed:
TODO
docs/CODE_QUALITY.md
hwdb.d/60-sensor.hwdb
hwdb.d/70-mouse.hwdb
hwdb.d/parse_hwdb.py
man/homed.conf.xml
man/logind.conf.xml
man/org.freedesktop.login1.xml
man/sd_bus_close.xml
meson.build
meson_options.txt
rules.d/60-persistent-storage.rules
rules.d/99-systemd.rules.in
shell-completion/zsh/_resolvectl
src/basic/fileio.c
src/basic/fs-util.c
src/basic/proc-cmdline.c
src/basic/proc-cmdline.h
src/home/homed-home.c
src/home/homed-manager.c
src/home/homework-cifs.c
src/home/homework-luks.c
src/home/homework-mount.c
src/home/homework-mount.h
src/home/homework.c
src/home/homework.h
src/journal/journal-send.c
src/libsystemd/sd-bus/bus-common-errors.c
src/libsystemd/sd-bus/bus-common-errors.h
src/login/logind-core.c
src/login/logind-dbus.c
src/login/logind-gperf.gperf
src/login/logind.conf.in
src/login/logind.h
src/login/user-runtime-dir.c
src/network/networkd-dhcp-common.c
src/resolve/resolved-manager.h
src/shared/bus-util.c
src/shared/install.c
src/udev/udev-builtin-path_id.c
src/udev/udev-rules.c
test/TEST-03-JOBS/test.sh
test/TEST-13-NSPAWN-SMOKE/test.sh
test/TEST-14-MACHINE-ID/test.sh
test/TEST-21-SYSUSERS/test.sh
test/fuzz/fuzz-network-parser/github-15885 [new file with mode: 0644]
test/fuzz/fuzz-unit-file/directives.service
test/fuzz/meson.build
test/test-functions
tools/oss-fuzz.sh
travis-ci/managers/debian.sh

diff --git a/TODO b/TODO
index ee50452d040e1b22814ea618978eb75ed075843e..e4182588fe87320d30efdb7c670e9188b33a43a6 100644 (file)
--- a/TODO
+++ b/TODO
@@ -81,7 +81,7 @@ Features:
 * homed: as an extension to the directory+subvolume backend: if located on
   especially marked fs, then sync down password into LUKS header of that fs,
   and always verify passwords against it too. Bootstrapping is a problem
-  though: if noone is logged in (or no other user even exists yet), how do you
+  though: if no one is logged in (or no other user even exists yet), how do you
   unlock the volume in order to create the first user and add the first pw.
 
 * homed: support new FS_IOC_ADD_ENCRYPTION_KEY ioctl for setting up fscrypt
index 9f261474acdba3795c9770f154c714db06c0ae40..a724d663f69b66dad3fb7b8210dc17f2338a303a 100644 (file)
@@ -71,5 +71,8 @@ available functionality:
     See [Testing systemd using sanitizers](https://systemd.io/TESTING_WITH_SANITIZERS)
     for more information.
 
+16. Fossies provides [source code misspelling reports](https://fossies.org/features.html#codespell).
+    The systemd report can be found [here](https://fossies.org/linux/test/systemd-master.tar.gz/codespell.html).
+
 Access to Coverity and oss-fuzz reports is limited. Please reach out to the
 maintainers if you need access.
index 0763f040f11ff238a7c6c9a12ad3ffc841bf670d..49bb90f58ec0f2d884dbd0ab0950aca5e226a4dc 100644 (file)
@@ -93,6 +93,9 @@ sensor:modalias:acpi:BOSC0200*:dmi:*:svnAcer*:pnSwitchSW312-31:*
 sensor:modalias:acpi:BOSC0200*:dmi:*svn*Acer*:*pn*Spin*SP111-33*
  ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
 
+sensor:modalias:acpi:BOSC0200*:dmi:*svnAcer*:*pnSpinSP111-34*
+ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
+
 #########################################
 # Archos
 #########################################
index c759527e2a2ce4031ed792b1439949296dd05019..ef5a473e87ae5ea990db48d9955fa81c1f7d3acf 100644 (file)
@@ -50,8 +50,6 @@
 #    MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL
 #    MOUSE_WHEEL_CLICK_COUNT
 #    MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL
-#    MOUSE_WHEEL_TILT_HORIZONTAL
-#    MOUSE_WHEEL_TILT_VERTICAL
 #
 #########################################
 #         ID_INPUT_TRACKBALL            #
 # MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL works the same way but also follows the
 # rules of MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL.
 
-#########################################
-#    MOUSE_WHEEL_TILT_HORIZONTAL        #
-#    MOUSE_WHEEL_TILT_VERTICAL          #
-#########################################
-#
-# Indicates that the respective axis is not a mouse wheel rotation but a
-# tilt along that axis. Wheel tilt is most commonly used for horizontal
-# scroll wheel emulation on mice with only a single vertical wheel.
-#
-# The vertical and horizontal Axes are independently marked as tilt axes,
-# for example it is permitted to have a MOUSE_WHEEL_CLICK_COUNT or
-# MOUSE_WHEEL_CLICK_ANGLE for the vertical axis and mark the horizontal axis
-# marked as as MOUSE_WHEEL_TILT_HORIZONTAL.
-#
-# It is a bug to have either CLICK_COUNT or CLICK_ANGLE set on the same axis
-# as WHEEL_TILT. Applications should give priority to WHEEL_TILT and ignore
-# other settings.
-#
-# This is a flag only, permitted values: 0 or 1
-
 #
 # Sort by brand, type (usb, bluetooth), DPI, frequency.
 # For mice with switchable resolution, sort by the starred entry.
index 579c45fda0218281080d94aef71493e1d171eeb3..abef56728fcbf86162e8cd81e1f6bc5efbac1ead 100755 (executable)
@@ -115,8 +115,6 @@ def property_grammar():
              ('ID_INPUT_TOUCHPAD', Literal('1')),
              ('ID_INPUT_TOUCHSCREEN', Literal('1')),
              ('ID_INPUT_TRACKBALL', Literal('1')),
-             ('MOUSE_WHEEL_TILT_HORIZONTAL', Literal('1')),
-             ('MOUSE_WHEEL_TILT_VERTICAL', Literal('1')),
              ('POINTINGSTICK_SENSITIVITY', INTEGER),
              ('POINTINGSTICK_CONST_ACCEL', REAL),
              ('ID_INPUT_JOYSTICK_INTEGRATION', Or(('internal', 'external'))),
index 03590feeaa6e8b577c4ba3aba702fd2eb9bf9a68..3e08b1a091c799df110fd1cbe821af43e8337795 100644 (file)
@@ -53,7 +53,7 @@
         <literal>cifs</literal>. For details about these options, see
         <citerefentry><refentrytitle>homectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. If not
         configured or assigned the empty string, the default storage is automatically determined: if not
-        running in a container enviroment and <filename>/home/</filename> is not itself encrypted, defaults
+        running in a container environment and <filename>/home/</filename> is not itself encrypted, defaults
         to <literal>luks</literal>. Otherwise defaults to <literal>subvolume</literal> if
         <filename>/home/</filename> is on a btrfs file system, and <literal>directory</literal>
         otherwise. Note that the storage selected on the <command>homectl</command> command line always takes
index 4cbfd09cbf26db75774e784917decf6360f4a206..b00daf366da7971c538d541c9f210e1bba4673c2 100644 (file)
         memory as is needed.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>RuntimeDirectoryInodesMax=</varname></term>
+
+        <listitem><para>Sets the limit on number of inodes for the
+        <varname>$XDG_RUNTIME_DIR</varname> runtime directory for each
+        user who logs in. Takes a number, optionally suffixed with the
+        usual K, G, M, and T suffixes, to the base 1024 (IEC).
+        Defaults to <varname>RuntimeDirectorySize=</varname> divided
+        by 4096. Note that this size is a safety limit only.
+        As each runtime directory is a tmpfs file system, it will
+        only consume as much memory as is needed.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>InhibitorsMax=</varname></term>
 
index 44ad033752d526b56c36640415a684fa919ff807..0292288d3a6402b5162c8bcf4a93b5de3c5cf924 100644 (file)
@@ -217,6 +217,8 @@ node /org/freedesktop/login1 {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly t RuntimeDirectorySize = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+      readonly t RuntimeDirectoryInodesMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly t InhibitorsMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t NCurrentInhibitors = ...;
@@ -425,6 +427,8 @@ node /org/freedesktop/login1 {
 
     <variablelist class="dbus-property" generated="True" extra-ref="RuntimeDirectorySize"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="RuntimeDirectoryInodesMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="InhibitorsMax"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="NCurrentInhibitors"/>
@@ -623,7 +627,8 @@ node /org/freedesktop/login1 {
       <varname>HandleLidSwitchExternalPower</varname>, <varname>HandleLidSwitchDocked</varname>,
       <varname>IdleActionUSec</varname>, <varname>HoldoffTimeoutUSec</varname>,
       <varname>RemoveIPC</varname>, <varname>RuntimeDirectorySize</varname>,
-      <varname>InhibitorsMax</varname>, and <varname>SessionsMax</varname>.
+      <varname>RuntimeDirectoryInodesMax</varname>, <varname>InhibitorsMax</varname>, and
+      <varname>SessionsMax</varname>.
       </para>
 
       <para>The <varname>IdleHint</varname> property reflects the idle hint state of the system. If the
index 8d9bdb48584fdc06c752bcb6cf3ed384839d6809..42db1074700de4ea82b1f6d4a495ffb6549e6dd7 100644 (file)
 
     <para><function>sd_bus_default_flush_close()</function> is similar to
     <function>sd_bus_flush_close_unref</function>, but does not take a bus pointer argument and
-    instead iterates over any of the "default" busses opened by
+    instead iterates over any of the "default" buses opened by
     <citerefentry><refentrytitle>sd_bus_default</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
     <citerefentry><refentrytitle>sd_bus_default_user</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
     <citerefentry><refentrytitle>sd_bus_default_system</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
     and similar calls. <function>sd_bus_default_flush_close()</function> is particularly useful to
-    clean up any busses opened using those calls before the program exits.</para>
+    clean up any buses opened using those calls before the program exits.</para>
   </refsect1>
 
   <refsect1>
index 20cb2b88a21d2ea3525c2738f52deae8a2edd505..b87d5c63a358d886eecee8ab75f8fdbea8d352a0 100644 (file)
@@ -308,6 +308,7 @@ meson_build_sh = find_program('tools/meson-build.sh')
 
 want_tests = get_option('tests')
 slow_tests = want_tests != 'false' and get_option('slow-tests')
+fuzz_tests = want_tests != 'false' and get_option('fuzz-tests')
 install_tests = get_option('install-tests')
 
 if add_languages('cpp', required : fuzzer_build)
@@ -3350,7 +3351,7 @@ foreach tuple : sanitizers
                         if name != prev
                                 if want_tests == 'false'
                                         message('Not compiling @0@ because tests is set to false'.format(name))
-                                elif slow_tests
+                                elif slow_tests or fuzz_tests
                                         exe = custom_target(
                                                 name,
                                                 output : name,
@@ -3360,12 +3361,12 @@ foreach tuple : sanitizers
                                                            '@OUTPUT@'],
                                                 build_by_default : true)
                                 else
-                                        message('Not compiling @0@ because slow-tests is set to false'.format(name))
+                                        message('Not compiling @0@ because slow-tests/fuzz-tests is set to false'.format(name))
                                 endif
                         endif
                         prev = name
 
-                        if want_tests != 'false' and slow_tests
+                        if want_tests != 'false' and (slow_tests or fuzz_tests)
                                 test('@0@:@1@:@2@'.format(b, c, sanitizer),
                                      env,
                                      env : ['UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1'],
index e9fff1660c8884b16ac87ac9e89be0419e43f251..d5ed2a7a421f457f5558d289b3f0adfed5af531c 100644 (file)
@@ -351,6 +351,8 @@ option('tests', type : 'combo', choices : ['true', 'unsafe', 'false'],
        description : 'enable extra tests with =unsafe')
 option('slow-tests', type : 'boolean', value : 'false',
        description : 'run the slow tests by default')
+option('fuzz-tests', type : 'boolean', value : 'false',
+       description : 'run the fuzzer regression tests by default')
 option('install-tests', type : 'boolean', value : 'false',
        description : 'install test executables')
 
index 01586690bdd3642a69112858023ebfa37b936659..821e9db86f00b5ef101aaa96e6dbde2e62ea0ba0 100644 (file)
@@ -93,6 +93,9 @@ ENV{DEVTYPE}=="disk", DEVPATH!="*/virtual/*", IMPORT{builtin}="path_id"
 KERNEL=="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-boot%n"
 KERNEL!="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}"
 ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
+# compatible links for ATA devices
+KERNEL!="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH_ATA_COMPAT}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH_ATA_COMPAT}"
+ENV{DEVTYPE}=="partition", ENV{ID_PATH_ATA_COMPAT}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH_ATA_COMPAT}-part%n"
 
 # legacy virtio-pci by-path links (deprecated)
 KERNEL=="vd*[!0-9]", ENV{ID_PATH}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID_PATH}"
index c34b60621683831271b5342b0eb1f0dbd1628d83..1c60eec587040252ca41e9018372ac2e939e49b2 100644 (file)
@@ -49,6 +49,7 @@ SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsys
 SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/bluetooth/devices/%k"
 
 SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_WANTS}+="bluetooth.target", ENV{SYSTEMD_USER_WANTS}+="bluetooth.target"
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0b????:*", ENV{ID_SMARTCARD_READER}="1"
 ENV{ID_SMARTCARD_READER}=="?*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="smartcard.target", ENV{SYSTEMD_USER_WANTS}+="smartcard.target"
 SUBSYSTEM=="sound", KERNEL=="card*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sound.target", ENV{SYSTEMD_USER_WANTS}+="sound.target"
 
index 7458f436a54b4297e56a9bcacbcbedae2b83448f..3ac069c6b0a73fe9e00945afe7079ed793d3b1c4 100644 (file)
         openpgp:"Retrieve openpgp keys for an email"
         query:"Resolve domain names, IPv4 and IPv6 addresses"
         reset-server-features:"Flushes all feature level information the resolver has learned about specific servers"
-        reset-statistics:"Resets the statistics counter show in statistics to zero"
+        reset-statistics:"Resets the statistics counter shown in statistics to zero"
         revert:"Revert the per-interfce DNS configuration"
         service:"Resolve DNS-SD and SRV services"
+        statistics:"Show resolver statistics"
         status:"Show the global and per-link DNS settings currently in effect"
         tlsa:"Query tlsa public keys stored as TLSA resource records"
     )
@@ -78,10 +79,6 @@ _arguments \
     '--service[Resolve services]' \
     '--service-address=no[Do not resolve address for services]' \
     '--service-txt=no[Do not resolve TXT records for services]' \
-    '--openpgp[Query OpenPGP public key]' \
-    '--tlsa[Query TLS public key]' \
     '--cname=no[Do not follow CNAME redirects]' \
     '--search=no[Do not use search domains]' \
-    '--statistics[Show resolver statistics]' \
-    '--reset-statistics[Reset resolver statistics]' \
     '*::default: _resolvectl_commands'
index 6b84d1462438033900801bc97c16c01900fb2049..00dce02064f579884a4feb1458fa6defeba29c7c 100644 (file)
@@ -202,6 +202,13 @@ static int write_string_file_atomic(
                 goto fail;
         }
 
+        if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) {
+                /* Sync the rename, too */
+                r = fsync_directory_of_file(fileno(f));
+                if (r < 0)
+                        return r;
+        }
+
         return 0;
 
 fail:
index 2c5bfb3263f8e35d929a9170aafacf166aae17c6..7bbcb6051e0c96dcc54e0d3350bb43b3a50168b9 100644 (file)
@@ -1365,7 +1365,7 @@ int unlinkat_deallocate(int fd, const char *name, UnlinkDeallocateFlags flags) {
                  * it. This isn't going to give you shred(1) semantics, but hopefully should be good enough
                  * for stuff backed by tmpfs at least.
                  *
-                 * Note that we only erase like this if the link count of the file is zero. If it is higer it
+                 * Note that we only erase like this if the link count of the file is zero. If it is higher it
                  * is still linked by someone else and we'll leave it to them to remove it securely
                  * eventually! */
 
index d8d30b0f1df44a93c3572a2fc80ee385fe8a7f80..eb45682f3a4a6cdaf10422649cc5e75f552d73ab 100644 (file)
@@ -119,15 +119,18 @@ int proc_cmdline_parse(proc_cmdline_parse_t parse_item, void *data, ProcCmdlineF
 
         /* We parse the EFI variable first, because later settings have higher priority. */
 
-        r = systemd_efi_options_variable(&line);
-        if (r < 0 && r != -ENODATA)
-                log_debug_errno(r, "Failed to get SystemdOptions EFI variable, ignoring: %m");
+        if (!FLAGS_SET(flags, PROC_CMDLINE_IGNORE_EFI_OPTIONS)) {
+                r = systemd_efi_options_variable(&line);
+                if (r < 0 && r != -ENODATA)
+                        log_debug_errno(r, "Failed to get SystemdOptions EFI variable, ignoring: %m");
 
-        r = proc_cmdline_parse_given(line, parse_item, data, flags);
-        if (r < 0)
-                return r;
+                r = proc_cmdline_parse_given(line, parse_item, data, flags);
+                if (r < 0)
+                        return r;
+
+                line = mfree(line);
+        }
 
-        line = mfree(line);
         r = proc_cmdline(&line);
         if (r < 0)
                 return r;
@@ -218,7 +221,7 @@ static int cmdline_get_key(const char *line, const char *key, ProcCmdlineFlags f
 }
 
 int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **ret_value) {
-        _cleanup_free_ char *line = NULL;
+        _cleanup_free_ char *line = NULL, *v = NULL;
         int r;
 
         /* Looks for a specific key on the kernel command line and (with lower priority) the EFI variable.
@@ -245,14 +248,27 @@ int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **ret_val
         if (r < 0)
                 return r;
 
-        r = cmdline_get_key(line, key, flags, ret_value);
-        if (r != 0) /* Either error or true if found. */
+        if (FLAGS_SET(flags, PROC_CMDLINE_IGNORE_EFI_OPTIONS)) /* Shortcut */
+                return cmdline_get_key(line, key, flags, ret_value);
+
+        r = cmdline_get_key(line, key, flags, ret_value ? &v : NULL);
+        if (r < 0)
                 return r;
+        if (r > 0) {
+                if (ret_value)
+                        *ret_value = TAKE_PTR(v);
+
+                return r;
+        }
 
         line = mfree(line);
         r = systemd_efi_options_variable(&line);
-        if (r == -ENODATA)
+        if (r == -ENODATA) {
+                if (ret_value)
+                        *ret_value = NULL;
+
                 return false; /* Not found */
+        }
         if (r < 0)
                 return r;
 
@@ -286,6 +302,7 @@ int proc_cmdline_get_bool(const char *key, bool *ret) {
 
 int proc_cmdline_get_key_many_internal(ProcCmdlineFlags flags, ...) {
         _cleanup_free_ char *line = NULL;
+        bool processing_efi = true;
         const char *p;
         va_list ap;
         int r, ret = 0;
@@ -296,9 +313,11 @@ int proc_cmdline_get_key_many_internal(ProcCmdlineFlags flags, ...) {
 
         /* This call may clobber arguments on failure! */
 
-        r = proc_cmdline(&line);
-        if (r < 0)
-                return r;
+        if (!FLAGS_SET(flags, PROC_CMDLINE_IGNORE_EFI_OPTIONS)) {
+                r = systemd_efi_options_variable(&line);
+                if (r < 0 && r != -ENODATA)
+                        log_debug_errno(r, "Failed to get SystemdOptions EFI variable, ignoring: %m");
+        }
 
         p = line;
         for (;;) {
@@ -307,8 +326,22 @@ int proc_cmdline_get_key_many_internal(ProcCmdlineFlags flags, ...) {
                 r = proc_cmdline_extract_first(&p, &word, flags);
                 if (r < 0)
                         return r;
-                if (r == 0)
+                if (r == 0) {
+                        /* We finished with this command line. If this was the EFI one, then let's proceed with the regular one */
+                        if (processing_efi) {
+                                processing_efi = false;
+
+                                line = mfree(line);
+                                r = proc_cmdline(&line);
+                                if (r < 0)
+                                        return r;
+
+                                p = line;
+                                continue;
+                        }
+
                         break;
+                }
 
                 va_start(ap, flags);
 
index 275f46c89ec22987ec77eff2beb182de60683c0b..077d3a99fb91e72fc66aa55eb92a02576358a2d2 100644 (file)
@@ -6,9 +6,10 @@
 #include "log.h"
 
 typedef enum ProcCmdlineFlags {
-        PROC_CMDLINE_STRIP_RD_PREFIX = 1 << 0, /* automatically strip "rd." prefix if it is set (and we are in the initrd, since otherwise we'd not consider it anyway) */
-        PROC_CMDLINE_VALUE_OPTIONAL  = 1 << 1, /* the value is optional (for boolean switches that can omit the value) */
-        PROC_CMDLINE_RD_STRICT       = 1 << 2, /* ignore this in the initrd */
+        PROC_CMDLINE_STRIP_RD_PREFIX    = 1 << 0, /* automatically strip "rd." prefix if it is set (and we are in the initrd, since otherwise we'd not consider it anyway) */
+        PROC_CMDLINE_VALUE_OPTIONAL     = 1 << 1, /* the value is optional (for boolean switches that can omit the value) */
+        PROC_CMDLINE_RD_STRICT          = 1 << 2, /* ignore this in the initrd */
+        PROC_CMDLINE_IGNORE_EFI_OPTIONS = 1 << 3, /* don't check systemd's private EFI variable */
 } ProcCmdlineFlags;
 
 typedef int (*proc_cmdline_parse_t)(const char *key, const char *value, void *data);
index be1a710ccc13f113acc2417e27392dcd0ddc61ac..47ee7d23281c5e80936b6ee0fa85dc4c71c3c808 100644 (file)
@@ -292,7 +292,7 @@ int home_save_record(Home *h) {
 
         fn = strjoina("/var/lib/systemd/home/", h->user_name, ".identity");
 
-        r = write_string_file(fn, text, WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MODE_0600);
+        r = write_string_file(fn, text, WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MODE_0600|WRITE_STRING_FILE_SYNC);
         if (r < 0)
                 return r;
 
@@ -471,6 +471,8 @@ static int convert_worker_errno(Home *h, int e, sd_bus_error *error) {
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_ACTIVE, "Home %s is currently not active", h->user_name);
         case -ENOSPC:
                 return sd_bus_error_setf(error, BUS_ERROR_NO_DISK_SPACE, "Not enough disk space for home %s", h->user_name);
+        case -EKEYREVOKED:
+                return sd_bus_error_setf(error, BUS_ERROR_HOME_CANT_AUTHENTICATE, "Home %s has no password or other authentication mechanism defined.", h->user_name);
         }
 
         return 0;
index df0ed2f4f36f550b6a7d6fc3e2f53f43fde8a155..7d951bee3b1189be626fae638b4721228137deac 100644 (file)
@@ -329,21 +329,36 @@ static int manager_add_home_by_record(
         _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
         unsigned line, column;
         int r, is_signed;
+        struct stat st;
         Home *h;
 
         assert(m);
         assert(name);
         assert(fname);
 
+        if (fstatat(dir_fd, fname, &st, 0) < 0)
+                return log_error_errno(errno, "Failed to stat identity record %s: %m", fname);
+
+        if (!S_ISREG(st.st_mode)) {
+                log_debug("Identity record file %s is not a regular file, ignoring.", fname);
+                return 0;
+        }
+
+        if (st.st_size == 0)
+                goto unlink_this_file;
+
         r = json_parse_file_at(NULL, dir_fd, fname, JSON_PARSE_SENSITIVE, &v, &line, &column);
         if (r < 0)
                 return log_error_errno(r, "Failed to parse identity record at %s:%u%u: %m", fname, line, column);
 
+        if (json_variant_is_blank_object(v))
+                goto unlink_this_file;
+
         hr = user_record_new();
         if (!hr)
                 return log_oom();
 
-        r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET);
+        r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG);
         if (r < 0)
                 return r;
 
@@ -394,6 +409,19 @@ static int manager_add_home_by_record(
         h->signed_locally = is_signed == USER_RECORD_SIGNED_EXCLUSIVE;
 
         return 1;
+
+unlink_this_file:
+        /* If this is an empty file, then let's just remove it. An empty file is not useful in any case, and
+         * apparently xfs likes to leave empty files around when not unmounted cleanly (see
+         * https://github.com/systemd/systemd/issues/15178 for example). Note that we don't delete non-empty
+         * files even if they are invalid, because that's just too risky, we might delete data the user still
+         * needs. But empty files are never useful, hence let's just remove them. */
+
+        if (unlinkat(dir_fd, fname, 0) < 0)
+                return log_error_errno(errno, "Failed to remove empty user record file %s: %m", fname);
+
+        log_notice("Discovered empty user record file /var/lib/systemd/home/%s, removed automatically.", fname);
+        return 0;
 }
 
 static int manager_enumerate_records(Manager *m) {
@@ -485,7 +513,7 @@ static int search_quota(uid_t uid, const char *exclude_quota_path) {
                         if (ERRNO_IS_NOT_SUPPORTED(r))
                                 log_debug_errno(r, "No UID quota support on %s, ignoring.", where);
                         else
-                                log_warning_errno(r, "Failed to query quota on %s, ignoring.", where);
+                                log_warning_errno(r, "Failed to query quota on %s, ignoring: %m", where);
 
                         continue;
                 }
@@ -1309,7 +1337,7 @@ static int manager_generate_key_pair(Manager *m) {
         if (PEM_write_PUBKEY(fpublic, m->private_key) <= 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key.");
 
-        r = fflush_and_check(fpublic);
+        r = fflush_sync_and_check(fpublic);
         if (r < 0)
                 return log_error_errno(r, "Failed to write private key: %m");
 
@@ -1323,7 +1351,7 @@ static int manager_generate_key_pair(Manager *m) {
         if (PEM_write_PrivateKey(fprivate, m->private_key, NULL, NULL, 0, NULL, 0) <= 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write private key pair.");
 
-        r = fflush_and_check(fprivate);
+        r = fflush_sync_and_check(fprivate);
         if (r < 0)
                 return log_error_errno(r, "Failed to write private key: %m");
 
@@ -1337,10 +1365,14 @@ static int manager_generate_key_pair(Manager *m) {
 
         if (rename(temp_private, "/var/lib/systemd/home/local.private") < 0) {
                 (void) unlink_noerrno("/var/lib/systemd/home/local.public"); /* try to remove the file we already created */
-                return log_error_errno(errno, "Failed to move privtate key file into place: %m");
+                return log_error_errno(errno, "Failed to move private key file into place: %m");
         }
         temp_private = mfree(temp_private);
 
+        r = fsync_path_at(AT_FDCWD, "/var/lib/systemd/home/");
+        if (r < 0)
+                log_warning_errno(r, "Failed to sync /var/lib/systemd/home/, ignoring: %m");
+
         return 1;
 }
 
index 1510031a38a3dfcfaf0d263fb9970f06b8a77568..27c92e16e7281895b29b1c99a17a6e0f9bdfb0d5 100644 (file)
@@ -28,7 +28,7 @@ int home_prepare_cifs(
                 char **pw;
                 int r;
 
-                r = home_unshare_and_mount(NULL, NULL, false);
+                r = home_unshare_and_mount(NULL, NULL, false, user_record_mount_flags(h));
                 if (r < 0)
                         return r;
 
index caa4168265a0a2ef50f74119f98a1fef74415f40..e9b2fc0c0da00ea9ab6c0b7dda7a825a4247fafc 100644 (file)
@@ -727,9 +727,10 @@ static int luks_validate_home_record(
                 if (!user_record_compatible(h, lhr))
                         return log_error_errno(SYNTHETIC_ERRNO(EREMCHG), "LUKS home record not compatible with host record, refusing.");
 
-                r = user_record_authenticate(lhr, h, pkcs11_decrypted_passwords);
+                r = user_record_authenticate(lhr, h, pkcs11_decrypted_passwords, /* strict_verify= */ true);
                 if (r < 0)
                         return r;
+                assert(r > 0); /* Insist that a password was verified */
 
                 *ret_luks_home_record = TAKE_PTR(lhr);
                 return 0;
@@ -1155,7 +1156,7 @@ int home_prepare_luks(
                 if (r < 0)
                         goto fail;
 
-                r = home_unshare_and_mount(setup->dm_node, fstype, user_record_luks_discard(h));
+                r = home_unshare_and_mount(setup->dm_node, fstype, user_record_luks_discard(h), user_record_mount_flags(h));
                 if (r < 0)
                         goto fail;
 
@@ -2078,7 +2079,7 @@ int home_create_luks(
 
         log_info("Formatting file system completed.");
 
-        r = home_unshare_and_mount(dm_node, fstype, user_record_luks_discard(h));
+        r = home_unshare_and_mount(dm_node, fstype, user_record_luks_discard(h), user_record_mount_flags(h));
         if (r < 0)
                 goto fail;
 
@@ -2283,7 +2284,7 @@ static int can_resize_fs(int fd, uint64_t old_size, uint64_t new_size) {
         return CAN_RESIZE_ONLINE;
 }
 
-static int ext4_offline_resize_fs(HomeSetup *setup, uint64_t new_size, bool discard) {
+static int ext4_offline_resize_fs(HomeSetup *setup, uint64_t new_size, bool discard, unsigned long flags) {
         _cleanup_free_ char *size_str = NULL;
         bool re_open = false, re_mount = false;
         pid_t resize_pid, fsck_pid;
@@ -2353,7 +2354,7 @@ static int ext4_offline_resize_fs(HomeSetup *setup, uint64_t new_size, bool disc
 
         /* Re-establish mounts and reopen the directory */
         if (re_mount) {
-                r = home_mount_node(setup->dm_node, "ext4", discard);
+                r = home_mount_node(setup->dm_node, "ext4", discard, flags);
                 if (r < 0)
                         return r;
 
@@ -2773,7 +2774,7 @@ int home_resize_luks(
         if (resize_type == CAN_RESIZE_ONLINE)
                 r = resize_fs(setup->root_fd, new_fs_size, NULL);
         else
-                r = ext4_offline_resize_fs(setup, new_fs_size, user_record_luks_discard(h));
+                r = ext4_offline_resize_fs(setup, new_fs_size, user_record_luks_discard(h), user_record_mount_flags(h));
         if (r < 0)
                 return log_error_errno(r, "Failed to resize file system: %m");
 
index 9e1116840de2f6a789adf92c28960f38f3b9f150..51c0a3864945190b0a8a1741b43a735f295fc880 100644 (file)
@@ -20,7 +20,7 @@ static const char *mount_options_for_fstype(const char *fstype) {
         return NULL;
 }
 
-int home_mount_node(const char *node, const char *fstype, bool discard) {
+int home_mount_node(const char *node, const char *fstype, bool discard, unsigned long flags) {
         _cleanup_free_ char *joined = NULL;
         const char *options, *discard_option;
         int r;
@@ -38,7 +38,7 @@ int home_mount_node(const char *node, const char *fstype, bool discard) {
         } else
                 options = discard_option;
 
-        r = mount_verbose(LOG_ERR, node, "/run/systemd/user-home-mount", fstype, MS_NODEV|MS_NOSUID|MS_RELATIME, strempty(options));
+        r = mount_verbose(LOG_ERR, node, "/run/systemd/user-home-mount", fstype, flags|MS_RELATIME, strempty(options));
         if (r < 0)
                 return r;
 
@@ -46,7 +46,7 @@ int home_mount_node(const char *node, const char *fstype, bool discard) {
         return 0;
 }
 
-int home_unshare_and_mount(const char *node, const char *fstype, bool discard) {
+int home_unshare_and_mount(const char *node, const char *fstype, bool discard, unsigned long flags) {
         int r;
 
         if (unshare(CLONE_NEWNS) < 0)
@@ -59,7 +59,7 @@ int home_unshare_and_mount(const char *node, const char *fstype, bool discard) {
         (void) mkdir_p("/run/systemd/user-home-mount", 0700);
 
         if (node)
-                return home_mount_node(node, fstype, discard);
+                return home_mount_node(node, fstype, discard, flags);
 
         return 0;
 }
index d926756f7bc9886f074a82e0121fe61ee3ce194c..cf7c8cfcab4bd848ed98d6c71d4115cd479c76e1 100644 (file)
@@ -3,6 +3,6 @@
 
 #include <stdbool.h>
 
-int home_mount_node(const char *node, const char *fstype, bool discard);
-int home_unshare_and_mount(const char *node, const char *fstype, bool discard);
+int home_mount_node(const char *node, const char *fstype, bool discard, unsigned long flags);
+int home_unshare_and_mount(const char *node, const char *fstype, bool discard, unsigned long flags);
 int home_move_mount(const char *user_name_and_realm, const char *target);
index 76fd79fc2a02ded993f478f6ef863da59bbf2e9d..316933cf4ebf69b3be051d050a874e6e97e250ed 100644 (file)
@@ -35,7 +35,8 @@
 int user_record_authenticate(
                 UserRecord *h,
                 UserRecord *secret,
-                char ***pkcs11_decrypted_passwords) {
+                char ***pkcs11_decrypted_passwords,
+                bool strict_verify) {
 
         bool need_password = false, need_token = false, need_pin = false, need_protected_authentication_path_permitted = false,
                 pin_locked = false, pin_incorrect = false, pin_incorrect_few_tries_left = false, pin_incorrect_one_try_left = false;
@@ -66,7 +67,7 @@ int user_record_authenticate(
                 return log_error_errno(r, "Failed to validate password of record: %m");
         else {
                 log_info("Provided password unlocks user record.");
-                return 0;
+                return 1;
         }
 
         /* Second, let's see if any of the PKCS#11 security tokens are plugged in and help us */
@@ -86,7 +87,7 @@ int user_record_authenticate(
                                 return log_error_errno(r, "Failed to check supplied PKCS#11 password: %m");
                         if (r > 0) {
                                 log_info("Previously acquired PKCS#11 password unlocks user record.");
-                                return 0;
+                                return 1;
                         }
                 }
 
@@ -129,7 +130,7 @@ int user_record_authenticate(
                         if (r < 0)
                                 return log_oom();
 
-                        return 0;
+                        return 1;
                 }
 #else
                 need_token = true;
@@ -156,7 +157,18 @@ int user_record_authenticate(
                 return -ENOKEY;
 
         /* Hmm, this means neither PCKS#11 nor classic hashed passwords were supplied, we cannot authenticate this reasonably */
-        return log_debug_errno(SYNTHETIC_ERRNO(EKEYREVOKED), "No hashed passwords and no PKCS#11 tokens defined, cannot authenticate user record.");
+        if (strict_verify)
+                return log_debug_errno(SYNTHETIC_ERRNO(EKEYREVOKED),
+                                       "No hashed passwords and no PKCS#11 tokens defined, cannot authenticate user record, refusing.");
+
+        /* If strict verification is off this means we are possibly in the case where we encountered an
+         * unfixated record, i.e. a synthetic one that accordingly lacks any authentication data. In this
+         * case, allow the authentication to pass for now, so that the second (or third) authentication level
+         * (the ones of the user record in the LUKS header or inside the home directory) will then catch
+         * invalid passwords. The second/third authentication always runs in strict verification mode. */
+        log_debug("No hashed passwords and no PKCS#11 tokens defined in record, cannot authenticate user record. "
+                  "Deferring to embedded user record.");
+        return 0;
 }
 
 int home_setup_undo(HomeSetup *setup) {
@@ -402,9 +414,10 @@ int home_load_embedded_identity(
                 return log_error_errno(SYNTHETIC_ERRNO(EREMCHG), "Embedded home record not compatible with host record, refusing.");
 
         /* Insist that credentials the user supplies also unlocks any embedded records. */
-        r = user_record_authenticate(embedded_home, h, pkcs11_decrypted_passwords);
+        r = user_record_authenticate(embedded_home, h, pkcs11_decrypted_passwords, /* strict_verify= */ true);
         if (r < 0)
                 return r;
+        assert(r > 0); /* Insist that a password was verified */
 
         /* At this point we have three records to deal with:
          *
@@ -615,7 +628,7 @@ static int home_activate(UserRecord *h, UserRecord **ret_home) {
         if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
                 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Activating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
 
-        r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords);
+        r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords, /* strict_verify= */ false);
         if (r < 0)
                 return r;
 
@@ -1177,9 +1190,10 @@ static int home_update(UserRecord *h, UserRecord **ret) {
         assert(h);
         assert(ret);
 
-        r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords);
+        r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords, /* strict_verify= */ true);
         if (r < 0)
                 return r;
+        assert(r > 0); /* Insist that a password was verified */
 
         r = home_validate_update(h, &setup);
         if (r < 0)
@@ -1233,9 +1247,10 @@ static int home_resize(UserRecord *h, UserRecord **ret) {
         if (h->disk_size == UINT64_MAX)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No target size specified, refusing.");
 
-        r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords);
+        r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords, /* strict_verify= */ true);
         if (r < 0)
                 return r;
+        assert(r > 0); /* Insist that a password was verified */
 
         r = home_validate_update(h, &setup);
         if (r < 0)
@@ -1343,7 +1358,7 @@ static int home_inspect(UserRecord *h, UserRecord **ret_home) {
         assert(h);
         assert(ret_home);
 
-        r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords);
+        r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords, /* strict_verify= */ false);
         if (r < 0)
                 return r;
 
@@ -1413,7 +1428,7 @@ static int home_unlock(UserRecord *h) {
         /* Note that we don't check if $HOME is actually mounted, since we want to avoid disk accesses on
          * that mount until we have resumed the device. */
 
-        r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords);
+        r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords, /* strict_verify= */ false);
         if (r < 0)
                 return r;
 
@@ -1489,6 +1504,7 @@ static int run(int argc, char *argv[]) {
          * EBUSY           → file system is currently active
          * ENOEXEC         → file system is currently not active
          * ENOSPC          → not enough disk space for operation
+         * EKEYREVOKED     → user record has not suitable hashed password or pkcs#11 entry, we cannot authenticate
          */
 
         if (streq(argv[1], "activate"))
index 3bcf3ad9b01a0ac43fbd4253edd2354cecc5a4c5..46641172a421e2e5fab5243b3455f94adc95cb4d 100644 (file)
@@ -56,6 +56,6 @@ int home_load_embedded_identity(UserRecord *h, int root_fd, UserRecord *header_h
 int home_store_embedded_identity(UserRecord *h, int root_fd, uid_t uid, UserRecord *old_home);
 int home_extend_embedded_identity(UserRecord *h, UserRecord *used, HomeSetup *setup);
 
-int user_record_authenticate(UserRecord *h, UserRecord *secret, char ***pkcs11_decrypted_passwords);
+int user_record_authenticate(UserRecord *h, UserRecord *secret, char ***pkcs11_decrypted_passwords, bool strict_verify);
 
 int home_sync_and_statfs(int root_fd, struct statfs *ret);
index b07bb592add44df9e485c9c74a7df374fdc99cbd..bbb1c206c5d15f321074a41ae3ae27062dd06801 100644 (file)
@@ -94,7 +94,7 @@ _public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
         if (len >= (int)LONG_LINE_MAX - 8)
                 return -ENOBUFS;
 
-        /* Allocate large buffer to accomodate big message */
+        /* Allocate large buffer to accommodate big message */
         if (len >= LINE_MAX) {
                 int rlen;
                 buffer = alloca(len + 9);
@@ -472,7 +472,7 @@ _public_ int sd_journal_printv_with_location(int priority, const char *file, con
         if (len >= (int)LONG_LINE_MAX - 8)
                 return -ENOBUFS;
 
-        /* Allocate large buffer to accomodate big message */
+        /* Allocate large buffer to accommodate big message */
         if (len >= LINE_MAX) {
                 int rlen;
                 buffer = alloca(len + 9);
index 174f1228af29fdc35cdbd2c14322de7543fb105f..28f98cebce97472e9455d1844a317414a68bdfb8 100644 (file)
@@ -134,6 +134,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
         SD_BUS_ERROR_MAP(BUS_ERROR_HOME_NOT_LOCKED,              ENOEXEC),
         SD_BUS_ERROR_MAP(BUS_ERROR_TOO_MANY_OPERATIONS,          ENOBUFS),
         SD_BUS_ERROR_MAP(BUS_ERROR_AUTHENTICATION_LIMIT_HIT,     ETOOMANYREFS),
+        SD_BUS_ERROR_MAP(BUS_ERROR_HOME_CANT_AUTHENTICATE,       EKEYREVOKED),
 
         SD_BUS_ERROR_MAP_END
 };
index dc58f88bbd5cc667712e295dea9d2bf170e4f87c..68ecbd65ddddb5425a1e05b7ccda27d741ac6363 100644 (file)
 #define BUS_ERROR_NO_DISK_SPACE "org.freedesktop.home1.NoDiskSpace"
 #define BUS_ERROR_TOO_MANY_OPERATIONS "org.freedesktop.home1.TooManyOperations"
 #define BUS_ERROR_AUTHENTICATION_LIMIT_HIT "org.freedesktop.home1.AuthenticationLimitHit"
+#define BUS_ERROR_HOME_CANT_AUTHENTICATE "org.freedesktop.home1.HomeCantAuthenticate"
 
 BUS_ERROR_MAP_ELF_USE(bus_common_errors);
index a9006d746a0df4615d7ac232ef383852abab844c..c160f546bca7cc95e96eb5d0505d0781c0fdac3e 100644 (file)
@@ -55,6 +55,7 @@ void manager_reset_config(Manager *m) {
         m->idle_action = HANDLE_IGNORE;
 
         m->runtime_dir_size = physical_memory_scale(10U, 100U); /* 10% */
+        m->runtime_dir_inodes = DIV_ROUND_UP(m->runtime_dir_size, 4096); /* 4k per inode */
         m->sessions_max = 8192;
         m->inhibitors_max = 8192;
 
index 451fe2875487a04b19a6ac5f7116cfe57aae0b89..a88605232c40428c8441604e681ab38719184059 100644 (file)
@@ -3359,6 +3359,7 @@ static const sd_bus_vtable manager_vtable[] = {
         SD_BUS_PROPERTY("OnExternalPower", "b", property_get_on_external_power, 0, 0),
         SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(Manager, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RuntimeDirectorySize", "t", NULL, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RuntimeDirectoryInodesMax", "t", NULL, offsetof(Manager, runtime_dir_inodes), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("InhibitorsMax", "t", NULL, offsetof(Manager, inhibitors_max), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_hashmap_size, offsetof(Manager, inhibitors), 0),
         SD_BUS_PROPERTY("SessionsMax", "t", NULL, offsetof(Manager, sessions_max), SD_BUS_VTABLE_PROPERTY_CONST),
index 983795da40d598a93f8ce33aac902c77a56e4bb6..73d96ff4367c6a7c4e739c8af94e20c68e37bed6 100644 (file)
@@ -38,6 +38,7 @@ Login.HoldoffTimeoutSec,            config_parse_sec,                   0, offse
 Login.IdleAction,                   config_parse_handle_action,         0, offsetof(Manager, idle_action)
 Login.IdleActionSec,                config_parse_sec,                   0, offsetof(Manager, idle_action_usec)
 Login.RuntimeDirectorySize,         config_parse_tmpfs_size,            0, offsetof(Manager, runtime_dir_size)
+Login.RuntimeDirectoryInodesMax,    config_parse_uint64,                0, offsetof(Manager, runtime_dir_inodes)
 Login.RemoveIPC,                    config_parse_bool,                  0, offsetof(Manager, remove_ipc)
 Login.InhibitorsMax,                config_parse_uint64,                0, offsetof(Manager, inhibitors_max)
 Login.SessionsMax,                  config_parse_uint64,                0, offsetof(Manager, sessions_max)
index 1029e29bc73565f064fc521b0caf63051fbff354..ed1084b06e295578a628fda374716cbc73b1f80b 100644 (file)
@@ -32,6 +32,7 @@
 #IdleAction=ignore
 #IdleActionSec=30min
 #RuntimeDirectorySize=10%
+#RuntimeDirectoryInodes=400k
 #RemoveIPC=yes
 #InhibitorsMax=8192
 #SessionsMax=8192
index d3f5b28078e83d271e3db433df495eac56b5c06a..e1d57277fa1bd20adea1fc90a3b79d292119d924 100644 (file)
@@ -120,6 +120,7 @@ struct Manager {
         sd_event_source *lid_switch_ignore_event_source;
 
         uint64_t runtime_dir_size;
+        uint64_t runtime_dir_inodes;
         uint64_t sessions_max;
         uint64_t inhibitors_max;
 };
index 1f98898b695e778a3bfe206741aa6a5d04a83e2d..4055c910c2d468fe840b35f1cfb5ec46eaa067c0 100644 (file)
@@ -22,7 +22,7 @@
 #include "strv.h"
 #include "user-util.h"
 
-static int acquire_runtime_dir_size(uint64_t *ret) {
+static int acquire_runtime_dir_properties(uint64_t *size, uint64_t *inodes) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         int r;
@@ -31,10 +31,14 @@ static int acquire_runtime_dir_size(uint64_t *ret) {
         if (r < 0)
                 return log_error_errno(r, "Failed to connect to system bus: %m");
 
-        r = sd_bus_get_property_trivial(bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "RuntimeDirectorySize", &error, 't', ret);
+        r = sd_bus_get_property_trivial(bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "RuntimeDirectorySize", &error, 't', size);
         if (r < 0)
                 return log_error_errno(r, "Failed to acquire runtime directory size: %s", bus_error_message(&error, r));
 
+        r = sd_bus_get_property_trivial(bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "RuntimeDirectoryInodesMax", &error, 't', inodes);
+        if (r < 0)
+                return log_error_errno(r, "Failed to acquire number of inodes for runtime directory: %s", bus_error_message(&error, r));
+
         return 0;
 }
 
@@ -42,7 +46,8 @@ static int user_mkdir_runtime_path(
                 const char *runtime_path,
                 uid_t uid,
                 gid_t gid,
-                uint64_t runtime_dir_size) {
+                uint64_t runtime_dir_size,
+                uint64_t runtime_dir_inodes) {
 
         int r;
 
@@ -58,14 +63,15 @@ static int user_mkdir_runtime_path(
         if (path_is_mount_point(runtime_path, NULL, 0) >= 0)
                 log_debug("%s is already a mount point", runtime_path);
         else {
-                char options[sizeof("mode=0700,uid=,gid=,size=,smackfsroot=*")
+                char options[sizeof("mode=0700,uid=,gid=,size=,nr_inodes=,smackfsroot=*")
                              + DECIMAL_STR_MAX(uid_t)
                              + DECIMAL_STR_MAX(gid_t)
+                             + DECIMAL_STR_MAX(uint64_t)
                              + DECIMAL_STR_MAX(uint64_t)];
 
                 xsprintf(options,
-                         "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%" PRIu64 "%s",
-                         uid, gid, runtime_dir_size,
+                         "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%" PRIu64 ",nr_inodes=%" PRIu64 "%s",
+                         uid, gid, runtime_dir_size, runtime_dir_inodes,
                          mac_smack_use() ? ",smackfsroot=*" : "");
 
                 (void) mkdir_label(runtime_path, 0700);
@@ -127,7 +133,7 @@ static int user_remove_runtime_path(const char *runtime_path) {
 
 static int do_mount(const char *user) {
         char runtime_path[sizeof("/run/user") + DECIMAL_STR_MAX(uid_t)];
-        uint64_t runtime_dir_size;
+        uint64_t runtime_dir_size, runtime_dir_inodes;
         uid_t uid;
         gid_t gid;
         int r;
@@ -140,14 +146,14 @@ static int do_mount(const char *user) {
                                                     : "Failed to look up user \"%s\": %m",
                                        user);
 
-        r = acquire_runtime_dir_size(&runtime_dir_size);
+        r = acquire_runtime_dir_properties(&runtime_dir_size, &runtime_dir_inodes);
         if (r < 0)
                 return r;
 
         xsprintf(runtime_path, "/run/user/" UID_FMT, uid);
 
         log_debug("Will mount %s owned by "UID_FMT":"GID_FMT, runtime_path, uid, gid);
-        return user_mkdir_runtime_path(runtime_path, uid, gid, runtime_dir_size);
+        return user_mkdir_runtime_path(runtime_path, uid, gid, runtime_dir_size, runtime_dir_inodes);
 }
 
 static int do_umount(const char *user) {
index 55191849d8c89e121762d33079fe0a9ec5227713..3d9dab7e3c1abaa5bf31d5240396c90e1fc9cf7f 100644 (file)
@@ -499,7 +499,7 @@ int config_parse_dhcp_send_option(
         r = extract_first_word(&p, &word, ":", 0);
         if (r == -ENOMEM)
                 return log_oom();
-        if (r <= 0) {
+        if (r <= 0 || isempty(p)) {
                 log_syntax(unit, LOG_ERR, filename, line, r,
                            "Invalid DHCP option, ignoring assignment: %s", rvalue);
                 return 0;
index cbaef5e49c65f986b6530774c419df1ef094249f..6fa5e734bbb024c06bdd5d4e9d8c0b681bf31db8 100644 (file)
@@ -167,7 +167,7 @@ void manager_verify_all(Manager *m);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
 
-/* For some reason we need some extra cmsg space on some kernels/archs. One of those days we ned to figure out why */
+/* For some reason we need some extra cmsg space on some kernels/archs. One of those days we need to figure out why */
 #define EXTRA_CMSG_SPACE 1024
 
 int manager_is_own_hostname(Manager *m, const char *name);
index c7611a6e851db1db5293463169e67689f0ba7388..379aecf73078697bbbcdfbc9a9f52cd4d5dd2107 100644 (file)
@@ -1591,6 +1591,12 @@ int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, voi
                                                impl->path);
         }
 
+        if (impl->manager) {
+                r = sd_bus_add_object_manager(bus, NULL, impl->path);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to add object manager for %s: %m", impl->path);
+        }
+
         for (size_t i = 0; impl->children && impl->children[i]; i++) {
                 r = bus_add_implementation(bus, impl->children[i], userdata);
                 if (r < 0)
index 21ad5aab36a6bc0485efd26f601bf521c911e13c..60005967e79feb614e2f036671b36889f2e86414 100644 (file)
@@ -227,7 +227,7 @@ static int path_is_runtime(const LookupPaths *p, const char *path, bool check_pa
                path_equal_ptr(path, p->runtime_control);
 }
 
-static int path_is_vendor(const LookupPaths *p, const char *path) {
+static int path_is_vendor_or_generator(const LookupPaths *p, const char *path) {
         const char *rpath;
 
         assert(p);
@@ -245,6 +245,9 @@ static int path_is_vendor(const LookupPaths *p, const char *path) {
                 return true;
 #endif
 
+        if (path_is_generator(p, rpath))
+                return true;
+
         return path_equal(rpath, SYSTEM_DATA_UNIT_PATH);
 }
 
@@ -2374,7 +2377,7 @@ int unit_file_revert(
                                         return -errno;
                         } else if (S_ISREG(st.st_mode)) {
                                 /* Check if there's a vendor version */
-                                r = path_is_vendor(&paths, path);
+                                r = path_is_vendor_or_generator(&paths, path);
                                 if (r < 0)
                                         return r;
                                 if (r > 0)
index ca38f56087911f283165d6207ca69e67ec616c1c..48e95005483b853290b24e2cedda03c250d9fbec 100644 (file)
@@ -253,14 +253,20 @@ static sd_device *handle_scsi_iscsi(sd_device *parent, char **path) {
         return parent;
 }
 
-static sd_device *handle_scsi_ata(sd_device *parent, char **path) {
+static sd_device *handle_scsi_ata(sd_device *parent, char **path, char **compat_path) {
         sd_device *targetdev, *target_parent;
         _cleanup_(sd_device_unrefp) sd_device *atadev = NULL;
-        const char *port_no, *sysname;
+        const char *port_no, *sysname, *name;
+        unsigned host, bus, target, lun;
 
         assert(parent);
         assert(path);
 
+        if (sd_device_get_sysname(parent, &name) < 0)
+                return NULL;
+        if (sscanf(name, "%u:%u:%u:%u", &host, &bus, &target, &lun) != 4)
+                return NULL;
+
         if (sd_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host", &targetdev) < 0)
                 return NULL;
 
@@ -275,7 +281,17 @@ static sd_device *handle_scsi_ata(sd_device *parent, char **path) {
         if (sd_device_get_sysattr_value(atadev, "port_no", &port_no) < 0)
                 return NULL;
 
-        path_prepend(path, "ata-%s", port_no);
+        if (bus != 0)
+                /* Devices behind port multiplier have a bus != 0*/
+                path_prepend(path, "ata-%s.%u.0", port_no, bus);
+        else
+                /* Master/slave are distinguished by target id */
+                path_prepend(path, "ata-%s.%u", port_no, target);
+
+        /* old compatible persistent link for ATA devices */
+        if (compat_path)
+                path_prepend(compat_path, "ata-%s", port_no);
+
         return parent;
 }
 
@@ -392,7 +408,7 @@ static sd_device *handle_scsi_hyperv(sd_device *parent, char **path, size_t guid
         return parent;
 }
 
-static sd_device *handle_scsi(sd_device *parent, char **path, bool *supported_parent) {
+static sd_device *handle_scsi(sd_device *parent, char **path, char **compat_path, bool *supported_parent) {
         const char *devtype, *id, *name;
 
         if (sd_device_get_devtype(parent, &devtype) < 0 ||
@@ -426,7 +442,7 @@ static sd_device *handle_scsi(sd_device *parent, char **path, bool *supported_pa
         }
 
         if (strstr(name, "/ata"))
-                return handle_scsi_ata(parent, path);
+                return handle_scsi_ata(parent, path, compat_path);
 
         if (strstr(name, "/vmbus_"))
                 return handle_scsi_hyperv(parent, path, 37);
@@ -520,6 +536,7 @@ static sd_device *handle_ap(sd_device *parent, char **path) {
 static int builtin_path_id(sd_device *dev, int argc, char *argv[], bool test) {
         sd_device *parent;
         _cleanup_free_ char *path = NULL;
+        _cleanup_free_ char *compat_path = NULL;
         bool supported_transport = false;
         bool supported_parent = false;
         const char *subsystem;
@@ -537,7 +554,7 @@ static int builtin_path_id(sd_device *dev, int argc, char *argv[], bool test) {
                 } else if (streq(subsys, "scsi_tape")) {
                         handle_scsi_tape(parent, &path);
                 } else if (streq(subsys, "scsi")) {
-                        parent = handle_scsi(parent, &path, &supported_parent);
+                        parent = handle_scsi(parent, &path, &compat_path, &supported_parent);
                         supported_transport = true;
                 } else if (streq(subsys, "cciss")) {
                         parent = handle_cciss(parent, &path);
@@ -557,19 +574,27 @@ static int builtin_path_id(sd_device *dev, int argc, char *argv[], bool test) {
                         }
                 } else if (streq(subsys, "pci")) {
                         path_prepend(&path, "pci-%s", sysname);
+                        if (compat_path)
+                                path_prepend(&compat_path, "pci-%s", sysname);
                         parent = skip_subsystem(parent, "pci");
                         supported_parent = true;
                 } else if (streq(subsys, "platform")) {
                         path_prepend(&path, "platform-%s", sysname);
+                        if (compat_path)
+                                path_prepend(&compat_path, "platform-%s", sysname);
                         parent = skip_subsystem(parent, "platform");
                         supported_transport = true;
                         supported_parent = true;
                 } else if (streq(subsys, "acpi")) {
                         path_prepend(&path, "acpi-%s", sysname);
+                        if (compat_path)
+                                path_prepend(&compat_path, "acpi-%s", sysname);
                         parent = skip_subsystem(parent, "acpi");
                         supported_parent = true;
                 } else if (streq(subsys, "xen")) {
                         path_prepend(&path, "xen-%s", sysname);
+                        if (compat_path)
+                                path_prepend(&compat_path, "xen-%s", sysname);
                         parent = skip_subsystem(parent, "xen");
                         supported_parent = true;
                 } else if (streq(subsys, "virtio")) {
@@ -577,16 +602,22 @@ static int builtin_path_id(sd_device *dev, int argc, char *argv[], bool test) {
                         supported_transport = true;
                 } else if (streq(subsys, "scm")) {
                         path_prepend(&path, "scm-%s", sysname);
+                        if (compat_path)
+                                path_prepend(&compat_path, "scm-%s", sysname);
                         parent = skip_subsystem(parent, "scm");
                         supported_transport = true;
                         supported_parent = true;
                 } else if (streq(subsys, "ccw")) {
                         path_prepend(&path, "ccw-%s", sysname);
+                        if (compat_path)
+                                path_prepend(&compat_path, "ccw-%s", sysname);
                         parent = skip_subsystem(parent, "ccw");
                         supported_transport = true;
                         supported_parent = true;
                 } else if (streq(subsys, "ccwgroup")) {
                         path_prepend(&path, "ccwgroup-%s", sysname);
+                        if (compat_path)
+                                path_prepend(&compat_path, "ccwgroup-%s", sysname);
                         parent = skip_subsystem(parent, "ccwgroup");
                         supported_transport = true;
                         supported_parent = true;
@@ -596,6 +627,8 @@ static int builtin_path_id(sd_device *dev, int argc, char *argv[], bool test) {
                         supported_parent = true;
                 } else if (streq(subsys, "iucv")) {
                         path_prepend(&path, "iucv-%s", sysname);
+                        if (compat_path)
+                                path_prepend(&compat_path, "iucv-%s", sysname);
                         parent = skip_subsystem(parent, "iucv");
                         supported_transport = true;
                         supported_parent = true;
@@ -604,6 +637,8 @@ static int builtin_path_id(sd_device *dev, int argc, char *argv[], bool test) {
 
                         if (sd_device_get_sysattr_value(dev, "nsid", &nsid) >= 0) {
                                 path_prepend(&path, "nvme-%s", nsid);
+                                if (compat_path)
+                                        path_prepend(&compat_path, "nvme-%s", nsid);
                                 parent = skip_subsystem(parent, "nvme");
                                 supported_parent = true;
                                 supported_transport = true;
@@ -671,6 +706,14 @@ static int builtin_path_id(sd_device *dev, int argc, char *argv[], bool test) {
                 udev_builtin_add_property(dev, test, "ID_PATH_TAG", tag);
         }
 
+        /*
+         * Compatible link generation for ATA devices
+         * we assign compat_link to the env variable
+         * ID_PATH_ATA_COMPAT
+         */
+        if (compat_path)
+                udev_builtin_add_property(dev, test, "ID_PATH_ATA_COMPAT", compat_path);
+
         return 0;
 }
 
index 4c955b0c079c3ee0a67db3a3001d681800ba871f..e9975030aae3cf518ed44a7cb2d54150b432efe1 100644 (file)
@@ -1814,7 +1814,7 @@ static int udev_rule_apply_token_to_event(
         case TK_M_IMPORT_CMDLINE: {
                 _cleanup_free_ char *value = NULL;
 
-                r = proc_cmdline_get_key(token->value, PROC_CMDLINE_VALUE_OPTIONAL, &value);
+                r = proc_cmdline_get_key(token->value, PROC_CMDLINE_VALUE_OPTIONAL|PROC_CMDLINE_IGNORE_EFI_OPTIONS, &value);
                 if (r < 0)
                         return log_rule_error_errno(dev, rules, r,
                                                     "Failed to read '%s' option from /proc/cmdline: %m",
index 33a1fb6fd09a480bd9fad341e3531eb681084cf4..221a18682a9f90820db8357ee837716c7b13bdbe 100755 (executable)
@@ -2,6 +2,7 @@
 set -e
 TEST_DESCRIPTION="Job-related tests"
 TEST_NO_QEMU=1
+IMAGE_NAME="default"
 
 . $TEST_BASE_DIR/test-functions
 
index 4a08cfd4ec0a5e74883877dd4d43227bece1be72..fbe52296cec9e955eeec756d7d4a627614a5e0cb 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/env bash
 set -e
 TEST_DESCRIPTION="systemd-nspawn smoke test"
-IMAGE_NAME=nspawn
+IMAGE_NAME="nspawn"
 TEST_NO_NSPAWN=1
 
 . $TEST_BASE_DIR/test-functions
index d1486f0aae0ae9aeb7c4918dfc7cfb317d8d2e24..e8dbf23c580c954de3306d4a37ef9d12e9f61cc9 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/env bash
 set -e
 TEST_DESCRIPTION="/etc/machine-id testing"
-IMAGE_NAME=badid
+IMAGE_NAME="badid"
 TEST_NO_NSPAWN=1
 
 . $TEST_BASE_DIR/test-functions
index f7dbbbf47b236cb7574efd3af179a25e5f39c96a..527db85b072a9e6e0c242bf8a685d573e1fa58b1 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/env bash
 set -e
 TEST_DESCRIPTION="Sysuser-related tests"
-IMAGE_NAME=sysusers
+IMAGE_NAME="sysusers"
 . $TEST_BASE_DIR/test-functions
 
 test_setup() {
diff --git a/test/fuzz/fuzz-network-parser/github-15885 b/test/fuzz/fuzz-network-parser/github-15885
new file mode 100644 (file)
index 0000000..9bbdcb2
--- /dev/null
@@ -0,0 +1,9 @@
+[DHCPv4]
+SendOption=1:string:
+SendOption=1:uint8:
+SendOption=1:uint16:
+SendOption=1:uint32:
+SendOption=1:ipv4address:
+SendOption=1:ipv4address:127.0.0.1
+SendOption=1:ipv6address:
+SendOption=1:ipv6address:52:54:00:b9:b5:61
index 6fa96e1d588457c9787344058c1dcc0f7531ba26..048bd34e9e2b05894508ad1cd6ffbfc8c6b100a1 100644 (file)
@@ -865,6 +865,7 @@ RestrictNamespaces=
 RestrictRealtime=
 RestrictSUIDSGID=
 RuntimeDirectory=
+RuntimeDirectoryInodesMax=
 RuntimeDirectoryMode=
 RuntimeDirectoryPreserve=
 RuntimeDirectorySize=
index 7d61e270fd9643c86b7eecb41f986e30114a55fd..b0305bdd0ec05457cb58851ce25943d552f27ea9 100644 (file)
@@ -7,7 +7,8 @@ sanitize_address_undefined = custom_target(
                    project_source_root,
                    '@OUTPUT@',
                    'fuzzers',
-                   '-Db_lundef=false -Db_sanitize=address,undefined',
+                   '-Db_lundef=false -Db_sanitize=address,undefined ' +
+                   '--optimization=@0@'.format(get_option('optimization')),
                    ' '.join(cc.cmd_array()),
                    cxx_cmd])
 
index 79130c3984dd1af7709171c01d874c99e001fe9c..f5a798b4b83cad560a216069873dfa8961cbe979 100644 (file)
@@ -18,6 +18,7 @@ EFI_MOUNT="${EFI_MOUNT:-$(bootctl -x 2>/dev/null || echo /boot)}"
 QEMU_MEM="${QEMU_MEM:-512M}"
 IMAGE_NAME=${IMAGE_NAME:-default}
 TEST_REQUIRE_INSTALL_TESTS="${TEST_REQUIRE_INSTALL_TESTS:-1}"
+TEST_PARALLELIZE="${TEST_PARALLELIZE:-0}"
 LOOPDEV=
 
 # Decide if we can (and want to) run QEMU with KVM acceleration.
@@ -329,12 +330,13 @@ systemd.wants=testsuite-$1.service ${_end} \
 $KERNEL_APPEND \
 "
 
+    [ -e "$IMAGE_PRIVATE" ] && image="$IMAGE_PRIVATE" || image="$IMAGE_PUBLIC"
     QEMU_OPTIONS="-smp $QEMU_SMP \
 -net none \
 -m $QEMU_MEM \
 -nographic \
 -kernel $KERNEL_BIN \
--drive format=raw,cache=unsafe,file=${IMAGESTATEDIR}/${IMAGE_NAME}.img \
+-drive format=raw,cache=unsafe,file=$image \
 $QEMU_OPTIONS \
 "
 
@@ -692,16 +694,14 @@ create_empty_image() {
         _size=$((4*_size))
     fi
 
-    image="${TESTDIR}/${IMAGE_NAME}.img"
-    public="$IMAGESTATEDIR/${IMAGE_NAME}.img"
-    echo "Setting up $public (${_size} MB)"
-    rm -f "$image" "$public"
+    echo "Setting up $IMAGE_PUBLIC (${_size} MB)"
+    rm -f "$IMAGE_PRIVATE" "$IMAGE_PUBLIC"
 
     # Create the blank file to use as a root filesystem
-    truncate -s "${_size}M" "$image"
-    ln -vs "$(realpath $image)" "$public"
+    truncate -s "${_size}M" "$IMAGE_PRIVATE"
+    ln -vs "$(realpath $IMAGE_PRIVATE)" "$IMAGE_PUBLIC"
 
-    LOOPDEV=$(losetup --show -P -f "$public")
+    LOOPDEV=$(losetup --show -P -f "$IMAGE_PUBLIC")
     [ -b "$LOOPDEV" ] || return 1
     sfdisk "$LOOPDEV" <<EOF
 ,$((_size-50))M
@@ -722,7 +722,7 @@ EOF
 
 mount_initdir() {
     if [ -z "${LOOPDEV}" ]; then
-        image="${IMAGESTATEDIR}/${IMAGE_NAME}.img"
+        [ -e "$IMAGE_PRIVATE" ] && image="$IMAGE_PRIVATE" || image="$IMAGE_PUBLIC"
         LOOPDEV=$(losetup --show -P -f "$image")
         [ -b "$LOOPDEV" ] || return 1
 
@@ -744,8 +744,7 @@ cleanup_initdir() {
 umount_loopback() {
     # unmount the loopback device from all places. Otherwise we risk file
     # system corruption.
-    image="${IMAGESTATEDIR}/${IMAGE_NAME}.img"
-    for device in $(losetup -l | awk '$6=="'"$image"'" {print $1}'); do
+    for device in $(losetup -l | awk '$6=="'"$IMAGE_PUBLIC"'" {print $1}'); do
         ddebug "Unmounting all uses of $device"
         mount | awk '/^'"${device}"'p/{print $1}' | xargs --no-run-if-empty umount -v
     done
@@ -1215,6 +1214,9 @@ TESTDIR="$TESTDIR"
 EOF
         export TESTDIR
     fi
+
+    IMAGE_PRIVATE="${TESTDIR}/${IMAGE_NAME}.img"
+    IMAGE_PUBLIC="${IMAGESTATEDIR}/${IMAGE_NAME}.img"
 }
 
 import_initdir() {
@@ -1964,7 +1966,7 @@ _test_cleanup() {
     (
         set +e
         _umount_dir $initdir
-        rm -vf "${IMAGESTATEDIR}/${IMAGE_NAME}.img"
+        rm -vf "$IMAGE_PUBLIC"
         rm -vfr "$TESTDIR"
         rm -vf "$STATEFILE"
     ) || :
@@ -2000,14 +2002,16 @@ test_setup() {
         exit 1
     fi
 
-    image="${TESTDIR}/${IMAGE_NAME}.img"
-    public="${IMAGESTATEDIR}/${IMAGE_NAME}.img"
-    if [ -e "$image" ]; then
-        echo "Reusing existing image $PWD/$image → $(realpath $image)"
+    if [ -e "$IMAGE_PRIVATE" ]; then
+        echo "Reusing existing image $IMAGE_PRIVATE → $(realpath $IMAGE_PRIVATE)"
         mount_initdir
-    elif [ -e "$public" ]; then
-        echo "Reusing existing cached image $PWD/$public → $(realpath $public)"
-        ln -s "$(realpath $public)" "$image"
+    elif [ -e "$IMAGE_PUBLIC" ]; then
+        echo "Reusing existing cached image $IMAGE_PUBLIC → $(realpath $IMAGE_PUBLIC)"
+        if [ ${TEST_PARALLELIZE} -ne 0 ]; then
+            cp -v "$(realpath $IMAGE_PUBLIC)" "$IMAGE_PRIVATE"
+        else
+            ln -sv "$(realpath $IMAGE_PUBLIC)" "$IMAGE_PRIVATE"
+        fi
         mount_initdir
     else
         test_create_image
index 79846f87879cfadc7be758e29fbf669ce0983cec..5b8690b687fe199d8e8dd121aab3f06129068f43 100755 (executable)
@@ -27,9 +27,15 @@ build=$WORK/build
 rm -rf $build
 mkdir -p $build
 
-fuzzflag="oss-fuzz=true"
 if [ -z "$FUZZING_ENGINE" ]; then
     fuzzflag="llvm-fuzz=true"
+else
+    fuzzflag="oss-fuzz=true"
+    if [[ "$SANITIZER" == undefined ]]; then
+        UBSAN_FLAGS="-fsanitize=pointer-overflow -fno-sanitize-recover=pointer-overflow"
+        CFLAGS="$CFLAGS $UBSAN_FLAGS"
+        CXXFLAGS="$CXXFLAGS $UBSAN_FLAGS"
+    fi
 fi
 
 meson $build -D$fuzzflag -Db_lundef=false
index 2851d9229da57a416829f33781517c22d06f1e16..60f6237606f6269d8edc7bdb3254ae6ab731820a 100755 (executable)
@@ -65,7 +65,10 @@ for phase in "${PHASES[@]}"; do
         RUN_ASAN|RUN_CLANG_ASAN)
             if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then
                 ENV_VARS="-e CC=clang -e CXX=clang++"
-                MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764
+                # Build fuzzer regression tests only with clang (for now),
+                # see: https://github.com/systemd/systemd/pull/15886#issuecomment-632689604
+                # -Db_lundef=false: See https://github.com/mesonbuild/meson/issues/764
+                MESON_ARGS="-Db_lundef=false -Dfuzz-tests=true --optimization=1"
             fi
             docker exec $ENV_VARS -it $CONT_NAME meson --werror -Dtests=unsafe -Db_sanitize=address,undefined -Dsplit-usr=true $MESON_ARGS build
             $DOCKER_EXEC ninja -v -C build