]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #29687 from yuwata/network-state-file-sync
authorFrantisek Sumsal <frantisek@sumsal.cz>
Wed, 25 Oct 2023 08:29:58 +0000 (08:29 +0000)
committerGitHub <noreply@github.com>
Wed, 25 Oct 2023 08:29:58 +0000 (08:29 +0000)
network: several fixlets for state file

39 files changed:
TODO
man/systemd-sleep.conf.xml
src/basic/argv-util.c
src/basic/io-util.c
src/basic/macro.h
src/basic/memory-util.h
src/boot/bootctl-install.c
src/core/execute.c
src/core/main.c
src/coredump/coredump.c
src/cryptenroll/cryptenroll.c
src/fundamental/macro-fundamental.h
src/home/homed-home.c
src/import/import-raw.c
src/import/pull-job.c
src/import/pull-raw.c
src/journal-remote/journal-gatewayd.c
src/journal/journald-native.c
src/libsystemd/sd-bus/bus-kernel.c
src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-journal/journal-authenticate.c
src/libsystemd/sd-journal/journal-file.c
src/libsystemd/sd-journal/mmap-cache.c
src/machine/machined-dbus.c
src/partition/repart.c
src/shared/copy.c
src/shared/elf-util.c
src/shared/machine-id-setup.c
src/shared/mount-util.c
src/shared/rm-rf.c
src/shared/rm-rf.h
src/shared/sleep-config.c
src/shared/tpm2-util.c
src/sleep/sleep.conf
src/test/test-macro.c
src/test/test-memory-util.c
test/TEST-69-SHUTDOWN/test.sh
test/TEST-82-SOFTREBOOT/test.sh
test/test-functions

diff --git a/TODO b/TODO
index 122965599d441ebe389ea939b22ffe31ff4f4982..ad9645bd29d35a85c5960d8ac82278e807471103 100644 (file)
--- a/TODO
+++ b/TODO
@@ -133,6 +133,19 @@ Deprecations and removals:
 
 Features:
 
+* add a new systemd-project@.service that is very similar to user@.service but
+  uses DynamicUser=1 and no PAMName= to invoke an unprivileged somewhat
+  light-weight service manager. Use HOME=/var/lib/systemd/projects/%i as home
+  dir. Similar for $XDG_RUNTIME_DIR. Start project@%i.target. Use LogField= to
+  add a field identifying the project.
+
+* logind: add a new dbus call Sleep() which automatically redirects to one of
+  Suspend(), Hibernate(), SuspendThenHibernate() depending on what is
+  available, and also subject to some local configuration in
+  logind.conf. Should default to SuspendThenHibernate() if available, and then
+  fallback to Suspend() and finally Hibernate() if not. Then expose this as
+  "systemctl sleep", and tell DEs to default to this.
+
 * in sd-boot and sd-stub measure the SMBIOS vendor strings to some PCR (at
   least some subset of them that look like systemd stuff), because apparently
   some firmware does not, but systemd honours it. avoid duplicate measurement
index b33699b6c56f81c6d2a5dc9f5d4614f6369fa358..91ea909afe9bd932838b92744fc4f667f060904a 100644 (file)
 
       <varlistentry>
         <term><varname>HibernateMode=</varname></term>
-        <term><varname>HybridSleepMode=</varname></term>
 
-        <listitem><para>The string to be written to <filename>/sys/power/disk</filename> by, respectively,
-        <citerefentry><refentrytitle>systemd-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-        and
-        <citerefentry><refentrytitle>systemd-hybrid-sleep.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+        <listitem><para>The string to be written to <filename>/sys/power/disk</filename> by <citerefentry>
+        <refentrytitle>systemd-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
         More than one value can be specified by separating multiple values with whitespace. They will be
         tried in turn, until one is written without error. If none of the writes succeed, the operation will
         be aborted.</para>
         url="https://www.kernel.org/doc/html/latest/admin-guide/pm/sleep-states.html#basic-sysfs-interfaces-for-system-suspend-and-hibernation">the
         kernel documentation</ulink> for more details.</para>
 
-        <para>Note that hybrid sleep corresponds to the <literal>suspend</literal> disk mode. If <varname>HybridSleepMode=</varname>
-        is overridden, you might get plain hibernation instead.</para>
-
         <para>
         <citerefentry><refentrytitle>systemd-suspend-then-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
         uses the value of <varname>SuspendMode=</varname> when suspending and the value of
index 6c88dcc2ee98d7d4967219ccaafad59c01be031b..a2bcc446787cbaa1d54d561d9ac7a350056d8ce3 100644 (file)
@@ -81,6 +81,9 @@ static int update_argv(const char name[], size_t l) {
         static int can_do = -1;
         int r;
 
+        assert(name);
+        assert(l < SIZE_MAX);
+
         if (can_do == 0)
                 return 0;
         can_do = false; /* We'll set it to true only if the whole process works */
@@ -102,6 +105,9 @@ static int update_argv(const char name[], size_t l) {
                 char *nn;
 
                 nn_size = PAGE_ALIGN(l+1);
+                if (nn_size >= SIZE_MAX)
+                        return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "The requested argument is too long.");
+
                 nn = mmap(NULL, nn_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
                 if (nn == MAP_FAILED)
                         return log_debug_errno(errno, "mmap() failed: %m");
index ede959fabcf51f6fd54f5d5ea63875f8da371df7..dee59947aa1e19c733764feea2ba9c2d70b5e492 100644 (file)
@@ -284,7 +284,7 @@ ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
                                         return -EIO;
                         }
 
-                        if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
+                        if (lseek(fd, n, SEEK_CUR) < 0)
                                 return -errno;
 
                         q += n;
index dcd1ca96fd48c58e409d7daaec8150fb305f0060..d3eb980abd3a0f5b7861e0e4b056057afe53c3ac 100644 (file)
 #error "neither int nor long are four bytes long?!?"
 #endif
 
+static inline uint64_t u64_multiply_safe(uint64_t a, uint64_t b) {
+        if (_unlikely_(a != 0 && b > (UINT64_MAX / a)))
+                return 0; /* overflow */
+
+        return a * b;
+}
+
 /* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */
 static inline unsigned long ALIGN_POWER2(unsigned long u) {
 
index b5e3984a09ae241656fea32c5c0f9865c3e8f33e..11795135f9d6f89091895b7de92e4b0be4df0113 100644 (file)
 #include "memory-util-fundamental.h"
 
 size_t page_size(void) _pure_;
-#define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
-#define PAGE_ALIGN_DOWN(l) ((l) & ~(page_size() - 1))
-#define PAGE_OFFSET(l) ((l) & (page_size() - 1))
+#define PAGE_ALIGN(l)          ALIGN_TO(l, page_size())
+#define PAGE_ALIGN_U64(l)      ALIGN_TO_U64(l, page_size())
+#define PAGE_ALIGN_DOWN(l)     ALIGN_DOWN(l, page_size())
+#define PAGE_ALIGN_DOWN_U64(l) ALIGN_DOWN_U64(l, page_size())
+#define PAGE_OFFSET(l)         ALIGN_OFFSET(l, page_size())
+#define PAGE_OFFSET_U64(l)     ALIGN_OFFSET_U64(l, page_size())
 
 /* Normal memcpy() requires src to be nonnull. We do nothing if n is 0. */
 static inline void *memcpy_safe(void *dst, const void *src, size_t n) {
index e6f66deeab08396f2a725eab08d184033c93359c..fb7cda7df565223a284e27fd57ae8702870d9c07 100644 (file)
@@ -233,7 +233,7 @@ static int copy_file_with_version_check(const char *from, const char *to, bool f
                         if (r < 0)
                                 return r;
 
-                        if (lseek(fd_from, 0, SEEK_SET) == (off_t) -1)
+                        if (lseek(fd_from, 0, SEEK_SET) < 0)
                                 return log_error_errno(errno, "Failed to seek in \"%s\": %m", from);
 
                         fd_to = safe_close(fd_to);
index 11513b267dd96fa1f5a8f81ac1827f6004ecd292..da416842cea8cc9955cb689fda267a0ef48afbce 100644 (file)
@@ -108,22 +108,24 @@ int exec_context_tty_size(const ExecContext *context, unsigned *ret_rows, unsign
 
 void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p) {
         _cleanup_close_ int _fd = -EBADF, lock_fd = -EBADF;
-        const char *path = exec_context_tty_path(ASSERT_PTR(context));
         int fd;
 
+        assert(context);
+
+        const char *path = exec_context_tty_path(context);
+
         if (p && p->stdin_fd >= 0)
                 fd = p->stdin_fd;
         else if (path) {
                 fd = _fd = open_terminal(path, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
                 if (fd < 0)
-                        return;
+                        return (void) log_debug_errno(fd, "Failed to open terminal '%s', ignoring: %m", path);
         } else
                 return;   /* nothing to do */
 
         /* Take a synchronization lock for the duration of the setup that we do here.
-         * systemd-vconsole-setup.service also takes the lock to avoid being interrupted.
-         * We open a new fd that will be closed automatically, and operate on it for convenience.
-         */
+         * systemd-vconsole-setup.service also takes the lock to avoid being interrupted. We open a new fd
+         * that will be closed automatically, and operate on it for convenience. */
         lock_fd = lock_dev_console();
         if (lock_fd < 0)
                 return (void) log_debug_errno(lock_fd,
@@ -405,7 +407,7 @@ int exec_spawn(Unit *unit,
         if (r < 0)
                 return log_unit_error_errno(unit, r, "Failed to serialize parameters: %m");
 
-        if (fseeko(f, 0, SEEK_SET) == (off_t) -1)
+        if (fseeko(f, 0, SEEK_SET) < 0)
                 return log_unit_error_errno(unit, errno, "Failed to reseek on serialization stream: %m");
 
         r = fd_cloexec(fileno(f), false);
index cbcf3ddeeae2ef5ef504b185921b0b116bfb92c1..cfa29f3a58655534a91f404e7a5c0133e3039338 100644 (file)
@@ -1108,7 +1108,7 @@ static int prepare_reexecute(
         if (r < 0)
                 return r;
 
-        if (fseeko(f, 0, SEEK_SET) == (off_t) -1)
+        if (fseeko(f, 0, SEEK_SET) < 0)
                 return log_error_errno(errno, "Failed to rewind serialization fd: %m");
 
         r = fd_cloexec(fileno(f), false);
index 1a49c8d777751f678251728b485185d925bc43e0..40505e35f319491d68f1bd949487d7f538d56ef1 100644 (file)
@@ -531,7 +531,7 @@ static int save_external_coredump(
                 _cleanup_close_ int fd_compressed = -EBADF;
                 uint64_t uncompressed_size = 0;
 
-                if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
+                if (lseek(fd, 0, SEEK_SET) < 0)
                         return log_error_errno(errno, "Failed to seek on coredump %s: %m", fn);
 
                 fn_compressed = strjoin(fn, default_compression_extension());
@@ -595,7 +595,7 @@ static int save_external_coredump(
         if (fstat(fd, &st) < 0)
                 return log_error_errno(errno, "Failed to fstat core file %s: %m", coredump_tmpfile_name(tmp));
 
-        if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
+        if (lseek(fd, 0, SEEK_SET) < 0)
                 return log_error_errno(errno, "Failed to seek on coredump %s: %m", fn);
 
         *ret_filename = TAKE_PTR(fn);
@@ -614,7 +614,7 @@ static int allocate_journal_field(int fd, size_t size, char **ret, size_t *ret_s
         assert(ret);
         assert(ret_size);
 
-        if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
+        if (lseek(fd, 0, SEEK_SET) < 0)
                 return log_warning_errno(errno, "Failed to seek: %m");
 
         field = malloc(9 + size);
index 6c90c7d843fd763cadfe5d65dbe149b0f7ccf3fd..a3332f5e7d1d423c1f940c9c04ab32fd9e3be5ea 100644 (file)
@@ -39,11 +39,9 @@ static char *arg_tpm2_device = NULL;
 static uint32_t arg_tpm2_seal_key_handle = 0;
 static Tpm2PCRValue *arg_tpm2_hash_pcr_values = NULL;
 static size_t arg_tpm2_n_hash_pcr_values = 0;
-static bool arg_tpm2_hash_pcr_values_use_default = true;
 static bool arg_tpm2_pin = false;
 static char *arg_tpm2_public_key = NULL;
 static uint32_t arg_tpm2_public_key_pcr_mask = 0;
-static bool arg_tpm2_public_key_pcr_mask_use_default = true;
 static char *arg_tpm2_signature = NULL;
 static char *arg_node = NULL;
 static int *arg_wipe_slots = NULL;
@@ -199,6 +197,7 @@ static int parse_argv(int argc, char *argv[]) {
                 {}
         };
 
+        bool auto_hash_pcr_values = true, auto_public_key_pcr_mask = true;
         int c, r;
 
         assert(argc >= 0);
@@ -370,7 +369,7 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_TPM2_PCRS:
-                        arg_tpm2_hash_pcr_values_use_default = false;
+                        auto_hash_pcr_values = false;
                         r = tpm2_parse_pcr_argument_append(optarg, &arg_tpm2_hash_pcr_values, &arg_tpm2_n_hash_pcr_values);
                         if (r < 0)
                                 return r;
@@ -392,7 +391,7 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_TPM2_PUBLIC_KEY_PCRS:
-                        arg_tpm2_public_key_pcr_mask_use_default = false;
+                        auto_public_key_pcr_mask = false;
                         r = tpm2_parse_pcr_argument_to_mask(optarg, &arg_tpm2_public_key_pcr_mask);
                         if (r < 0)
                                 return r;
@@ -468,16 +467,18 @@ static int parse_argv(int argc, char *argv[]) {
                 }
         }
 
-        if ((arg_enroll_type == ENROLL_FIDO2 && arg_unlock_type == UNLOCK_FIDO2)
-                        && !(arg_fido2_device && arg_unlock_fido2_device))
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "When both enrolling and unlocking with FIDO2 tokens, automatic discovery is unsupported. "
-                                       "Please specify device paths for enrolling and unlocking respectively.");
+        if (arg_enroll_type == ENROLL_FIDO2) {
 
-        if (arg_enroll_type == ENROLL_FIDO2 && !arg_fido2_device) {
-                r = fido2_find_device_auto(&arg_fido2_device);
-                if (r < 0)
-                        return r;
+                if (arg_unlock_type == UNLOCK_FIDO2 && !(arg_fido2_device && arg_unlock_fido2_device))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "When both enrolling and unlocking with FIDO2 tokens, automatic discovery is unsupported. "
+                                               "Please specify device paths for enrolling and unlocking respectively.");
+
+                if (!arg_fido2_device) {
+                        r = fido2_find_device_auto(&arg_fido2_device);
+                        if (r < 0)
+                                return r;
+                }
         }
 
         if (optind >= argc)
@@ -492,10 +493,10 @@ static int parse_argv(int argc, char *argv[]) {
         if (r < 0)
                 return r;
 
-        if (arg_tpm2_public_key_pcr_mask_use_default && arg_tpm2_public_key)
+        if (auto_public_key_pcr_mask && arg_tpm2_public_key)
                 arg_tpm2_public_key_pcr_mask = INDEX_TO_MASK(uint32_t, TPM2_PCR_KERNEL_BOOT);
 
-        if (arg_tpm2_hash_pcr_values_use_default && !GREEDY_REALLOC_APPEND(
+        if (auto_hash_pcr_values && !GREEDY_REALLOC_APPEND(
                         arg_tpm2_hash_pcr_values,
                         arg_tpm2_n_hash_pcr_values,
                         &TPM2_PCR_VALUE_MAKE(TPM2_PCR_INDEX_DEFAULT, /* hash= */ 0, /* value= */ {}),
index fa9aeafb98ec28be38e47ed620fab904a96bbf78..797330dd97d6cabb2da7fc30fcb9999afc3b804f 100644 (file)
@@ -376,7 +376,40 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
         if (l > SIZE_MAX - (ali - 1))
                 return SIZE_MAX; /* indicate overflow */
 
-        return ((l + ali - 1) & ~(ali - 1));
+        return ((l + (ali - 1)) & ~(ali - 1));
+}
+
+static inline uint64_t ALIGN_TO_U64(uint64_t l, uint64_t ali) {
+        assert(ISPOWEROF2(ali));
+
+        if (l > UINT64_MAX - (ali - 1))
+                return UINT64_MAX; /* indicate overflow */
+
+        return ((l + (ali - 1)) & ~(ali - 1));
+}
+
+static inline size_t ALIGN_DOWN(size_t l, size_t ali) {
+        assert(ISPOWEROF2(ali));
+
+        return l & ~(ali - 1);
+}
+
+static inline uint64_t ALIGN_DOWN_U64(uint64_t l, uint64_t ali) {
+        assert(ISPOWEROF2(ali));
+
+        return l & ~(ali - 1);
+}
+
+static inline size_t ALIGN_OFFSET(size_t l, size_t ali) {
+        assert(ISPOWEROF2(ali));
+
+        return l & (ali - 1);
+}
+
+static inline uint64_t ALIGN_OFFSET_U64(uint64_t l, uint64_t ali) {
+        assert(ISPOWEROF2(ali));
+
+        return l & (ali - 1);
 }
 
 #define ALIGN2(l) ALIGN_TO(l, 2)
index 206f6480acac0a830c9a22a8d9427f1c216c4df3..749670f94bea17b626224b9edcccca1d0fdbab42 100644 (file)
@@ -519,7 +519,7 @@ static int home_parse_worker_stdout(int _fd, UserRecord **ret) {
                 return 0;
         }
 
-        if (lseek(fd, SEEK_SET, 0) == (off_t) -1)
+        if (lseek(fd, SEEK_SET, 0) < 0)
                 return log_error_errno(errno, "Failed to seek to beginning of memfd: %m");
 
         f = take_fdopen(&fd, "r");
index feb6ac1bdda024302868dc09747a8399f72fd07a..2db3198ba6123fa32c7580ba3e3a9ffe6a15ae9f 100644 (file)
@@ -303,7 +303,7 @@ static int raw_import_open_disk(RawImport *i) {
                                        "Target file is not a regular file or block device");
 
         if (i->offset != UINT64_MAX) {
-                if (lseek(i->output_fd, i->offset, SEEK_SET) == (off_t) -1)
+                if (lseek(i->output_fd, i->offset, SEEK_SET) < 0)
                         return log_error_errno(errno, "Failed to seek to offset: %m");
         }
 
@@ -328,7 +328,7 @@ static int raw_import_try_reflink(RawImport *i) {
                 return 0;
 
         p = lseek(i->input_fd, 0, SEEK_CUR);
-        if (p == (off_t) -1)
+        if (p < 0)
                 return log_error_errno(errno, "Failed to read file offset of input file: %m");
 
         /* Let's only try a btrfs reflink, if we are reading from the beginning of the file */
index d05bf3cd4974081cb19ed846b7d4308c9d55c20b..bed7e6403057057c986a16f1a26baf38fb1064f9 100644 (file)
@@ -415,7 +415,7 @@ static int pull_job_open_disk(PullJob *j) {
                         return log_error_errno(errno, "Failed to stat disk file: %m");
 
                 if (j->offset != UINT64_MAX) {
-                        if (lseek(j->disk_fd, j->offset, SEEK_SET) == (off_t) -1)
+                        if (lseek(j->disk_fd, j->offset, SEEK_SET) < 0)
                                 return log_error_errno(errno, "Failed to seek on file descriptor: %m");
                 }
         }
index 3befa96a042cb45d6e0718f1025d1e400fe54a5e..e96be4dd7dbb6de241c51fbb1478b2ddc82b30b2 100644 (file)
@@ -370,7 +370,7 @@ static int raw_pull_make_local_copy(RawPull *i) {
                 assert(i->raw_job->disk_fd >= 0);
                 assert(i->offset == UINT64_MAX);
 
-                if (lseek(i->raw_job->disk_fd, SEEK_SET, 0) == (off_t) -1)
+                if (lseek(i->raw_job->disk_fd, SEEK_SET, 0) < 0)
                         return log_error_errno(errno, "Failed to seek to beginning of vendor image: %m");
         }
 
index 980b98137e6fbbe604bd4a002865f453997c0c95..09194710cb60e9f5d5d5a553e081f30c9b913fb3 100644 (file)
@@ -233,7 +233,7 @@ static ssize_t request_reader_entries(
                 }
 
                 sz = ftello(m->tmp);
-                if (sz == (off_t) -1) {
+                if (sz < 0) {
                         log_error_errno(errno, "Failed to retrieve file position: %m");
                         return MHD_CONTENT_READER_END_WITH_ERROR;
                 }
@@ -582,7 +582,7 @@ static ssize_t request_reader_fields(
                 }
 
                 sz = ftello(m->tmp);
-                if (sz == (off_t) -1) {
+                if (sz < 0) {
                         log_error_errno(errno, "Failed to retrieve file position: %m");
                         return MHD_CONTENT_READER_END_WITH_ERROR;
                 }
index 06073ac0a5d8e44d998289149552eb8eed5b206d..4f030dda86f4e31eee3d66c3a2aedf5e892398a4 100644 (file)
@@ -405,6 +405,7 @@ void server_process_native_file(
                 /* The file is sealed, we can just map it and use it. */
 
                 ps = PAGE_ALIGN(st.st_size);
+                assert(ps < SIZE_MAX);
                 p = mmap(NULL, ps, PROT_READ, MAP_PRIVATE, fd, 0);
                 if (p == MAP_FAILED) {
                         log_ratelimit_error_errno(errno, JOURNAL_LOG_RATELIMIT,
index b553f153968899cfe5f48d67871b420151c30f15..d7ff83441b78b496f5283cdf179e3b5b611d81cb 100644 (file)
 #include "memory-util.h"
 
 void close_and_munmap(int fd, void *address, size_t size) {
-        if (size > 0)
-                assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
+        if (size > 0) {
+                size = PAGE_ALIGN(size);
+                assert(size < SIZE_MAX);
+                assert_se(munmap(address, size) >= 0);
+        }
 
         safe_close(fd);
 }
index f0818b801ca006f71aca630ec56e82fe31ba8ec4..ff0228081fedbb4ca1034077b26fc8eb9d203a31 100644 (file)
@@ -2490,6 +2490,8 @@ int bus_body_part_map(struct bus_body_part *part) {
 
         shift = PAGE_OFFSET(part->memfd_offset);
         psz = PAGE_ALIGN(part->size + shift);
+        if (psz >= SIZE_MAX)
+                return -EFBIG;
 
         if (part->memfd >= 0)
                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, part->memfd_offset - shift);
index 42af483d22f309ae01951d66bc764c8afa0ee459..10e5eafbfcf5afb4f25eba4a345c9985138f621f 100644 (file)
@@ -379,7 +379,9 @@ int journal_file_fss_load(JournalFile *f) {
         if (le64toh(header->start_usec) <= 0 || le64toh(header->interval_usec) <= 0)
                 return -EBADMSG;
 
-        f->fss_file = mmap(NULL, PAGE_ALIGN(f->fss_file_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+        size_t sz = PAGE_ALIGN(f->fss_file_size);
+        assert(sz < SIZE_MAX);
+        f->fss_file = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
         if (f->fss_file == MAP_FAILED) {
                 f->fss_file = NULL;
                 return -errno;
index 5982938fb925ac907e7a21cc89d244b337caed39..334a28f9486ed6d75f98a842bb8858fc4d886464 100644 (file)
 #define DEFAULT_COMPRESS_THRESHOLD (512ULL)
 #define MIN_COMPRESS_THRESHOLD (8ULL)
 
+#define U64_KB UINT64_C(1024)
+#define U64_MB (UINT64_C(1024) * U64_KB)
+#define U64_GB (UINT64_C(1024) * U64_MB)
+
 /* This is the minimum journal file size */
-#define JOURNAL_FILE_SIZE_MIN (512 * 1024ULL)             /* 512 KiB */
-#define JOURNAL_COMPACT_SIZE_MAX UINT32_MAX               /* 4 GiB */
+#define JOURNAL_FILE_SIZE_MIN (512 * U64_KB)             /* 512 KiB */
+#define JOURNAL_COMPACT_SIZE_MAX ((uint64_t) UINT32_MAX) /* 4 GiB */
 
-/* These are the lower and upper bounds if we deduce the max_use value
- * from the file system size */
-#define MAX_USE_LOWER (1 * 1024 * 1024ULL)                /* 1 MiB */
-#define MAX_USE_UPPER (4 * 1024 * 1024 * 1024ULL)         /* 4 GiB */
+/* These are the lower and upper bounds if we deduce the max_use value from the file system size */
+#define MAX_USE_LOWER (1 * U64_MB)                       /* 1 MiB */
+#define MAX_USE_UPPER (4 * U64_GB)                       /* 4 GiB */
 
 /* Those are the lower and upper bounds for the minimal use limit,
  * i.e. how much we'll use even if keep_free suggests otherwise. */
-#define MIN_USE_LOW (1 * 1024 * 1024ULL)                  /* 1 MiB */
-#define MIN_USE_HIGH (16 * 1024 * 1024ULL)                /* 16 MiB */
+#define MIN_USE_LOW  (1  * U64_MB)                       /* 1 MiB */
+#define MIN_USE_HIGH (16 * U64_MB)                       /* 16 MiB */
 
 /* This is the upper bound if we deduce max_size from max_use */
-#define MAX_SIZE_UPPER (128 * 1024 * 1024ULL)             /* 128 MiB */
+#define MAX_SIZE_UPPER (128 * U64_MB)                    /* 128 MiB */
 
-/* This is the upper bound if we deduce the keep_free value from the
- * file system size */
-#define KEEP_FREE_UPPER (4 * 1024 * 1024 * 1024ULL)       /* 4 GiB */
+/* This is the upper bound if we deduce the keep_free value from the file system size */
+#define KEEP_FREE_UPPER (4 * U64_GB)                     /* 4 GiB */
 
-/* This is the keep_free value when we can't determine the system
- * size */
-#define DEFAULT_KEEP_FREE (1024 * 1024ULL)                /* 1 MB */
+/* This is the keep_free value when we can't determine the system size */
+#define DEFAULT_KEEP_FREE (1 * U64_MB)                   /* 1 MB */
 
 /* This is the default maximum number of journal files to keep around. */
 #define DEFAULT_N_MAX_FILES 100
@@ -82,7 +83,7 @@
 #define CHAIN_CACHE_MAX 20
 
 /* How much to increase the journal file size at once each time we allocate something new. */
-#define FILE_SIZE_INCREASE (8 * 1024 * 1024ULL)          /* 8MB */
+#define FILE_SIZE_INCREASE (8 * U64_MB)                  /* 8MB */
 
 /* Reread fstat() of the file for detecting deletions at least this often */
 #define LAST_STAT_REFRESH_USEC (5*USEC_PER_SEC)
@@ -301,9 +302,11 @@ JournalFile* journal_file_close(JournalFile *f) {
 #endif
 
 #if HAVE_GCRYPT
-        if (f->fss_file)
-                munmap(f->fss_file, PAGE_ALIGN(f->fss_file_size));
-        else
+        if (f->fss_file) {
+                size_t sz = PAGE_ALIGN(f->fss_file_size);
+                assert(sz < SIZE_MAX);
+                munmap(f->fss_file, sz);
+        } else
                 free(f->fsprg_state);
 
         free(f->fsprg_seed);
@@ -750,7 +753,7 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
         /* We assume that this file is not sparse, and we know that for sure, since we always call
          * posix_fallocate() ourselves */
 
-        if (size > PAGE_ALIGN_DOWN(UINT64_MAX) - offset)
+        if (size > PAGE_ALIGN_DOWN_U64(UINT64_MAX) - offset)
                 return -EINVAL;
 
         if (mmap_cache_fd_got_sigbus(f->cache_fd))
@@ -758,12 +761,12 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
 
         old_header_size = le64toh(READ_NOW(f->header->header_size));
         old_arena_size = le64toh(READ_NOW(f->header->arena_size));
-        if (old_arena_size > PAGE_ALIGN_DOWN(UINT64_MAX) - old_header_size)
+        if (old_arena_size > PAGE_ALIGN_DOWN_U64(UINT64_MAX) - old_header_size)
                 return -EBADMSG;
 
         old_size = old_header_size + old_arena_size;
 
-        new_size = MAX(PAGE_ALIGN(offset + size), old_header_size);
+        new_size = MAX(PAGE_ALIGN_U64(offset + size), old_header_size);
 
         if (new_size <= old_size) {
 
@@ -794,7 +797,7 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
                 if (fstatvfs(f->fd, &svfs) >= 0) {
                         uint64_t available;
 
-                        available = LESS_BY((uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize, f->metrics.keep_free);
+                        available = LESS_BY(u64_multiply_safe(svfs.f_bfree, svfs.f_bsize), f->metrics.keep_free);
 
                         if (new_size - old_size > available)
                                 return -E2BIG;
@@ -3880,19 +3883,19 @@ static void journal_default_metrics(JournalMetrics *m, int fd, bool compact) {
         assert(fd >= 0);
 
         if (fstatvfs(fd, &ss) >= 0)
-                fs_size = ss.f_frsize * ss.f_blocks;
+                fs_size = u64_multiply_safe(ss.f_frsize, ss.f_blocks);
         else
                 log_debug_errno(errno, "Failed to determine disk size: %m");
 
         if (m->max_use == UINT64_MAX) {
 
                 if (fs_size > 0)
-                        m->max_use = CLAMP(PAGE_ALIGN(fs_size / 10), /* 10% of file system size */
+                        m->max_use = CLAMP(PAGE_ALIGN_U64(fs_size / 10), /* 10% of file system size */
                                            MAX_USE_LOWER, MAX_USE_UPPER);
                 else
                         m->max_use = MAX_USE_LOWER;
         } else {
-                m->max_use = PAGE_ALIGN(m->max_use);
+                m->max_use = PAGE_ALIGN_U64(m->max_use);
 
                 if (m->max_use != 0 && m->max_use < JOURNAL_FILE_SIZE_MIN*2)
                         m->max_use = JOURNAL_FILE_SIZE_MIN*2;
@@ -3900,7 +3903,7 @@ static void journal_default_metrics(JournalMetrics *m, int fd, bool compact) {
 
         if (m->min_use == UINT64_MAX) {
                 if (fs_size > 0)
-                        m->min_use = CLAMP(PAGE_ALIGN(fs_size / 50), /* 2% of file system size */
+                        m->min_use = CLAMP(PAGE_ALIGN_U64(fs_size / 50), /* 2% of file system size */
                                            MIN_USE_LOW, MIN_USE_HIGH);
                 else
                         m->min_use = MIN_USE_LOW;
@@ -3910,10 +3913,10 @@ static void journal_default_metrics(JournalMetrics *m, int fd, bool compact) {
                 m->min_use = m->max_use;
 
         if (m->max_size == UINT64_MAX)
-                m->max_size = MIN(PAGE_ALIGN(m->max_use / 8), /* 8 chunks */
+                m->max_size = MIN(PAGE_ALIGN_U64(m->max_use / 8), /* 8 chunks */
                                   MAX_SIZE_UPPER);
         else
-                m->max_size = PAGE_ALIGN(m->max_size);
+                m->max_size = PAGE_ALIGN_U64(m->max_size);
 
         if (compact && m->max_size > JOURNAL_COMPACT_SIZE_MAX)
                 m->max_size = JOURNAL_COMPACT_SIZE_MAX;
@@ -3929,13 +3932,13 @@ static void journal_default_metrics(JournalMetrics *m, int fd, bool compact) {
         if (m->min_size == UINT64_MAX)
                 m->min_size = JOURNAL_FILE_SIZE_MIN;
         else
-                m->min_size = CLAMP(PAGE_ALIGN(m->min_size),
+                m->min_size = CLAMP(PAGE_ALIGN_U64(m->min_size),
                                     JOURNAL_FILE_SIZE_MIN,
                                     m->max_size ?: UINT64_MAX);
 
         if (m->keep_free == UINT64_MAX) {
                 if (fs_size > 0)
-                        m->keep_free = MIN(PAGE_ALIGN(fs_size / 20), /* 5% of file system size */
+                        m->keep_free = MIN(PAGE_ALIGN_U64(fs_size / 20), /* 5% of file system size */
                                            KEEP_FREE_UPPER);
                 else
                         m->keep_free = DEFAULT_KEEP_FREE;
index 8b3f644f2d3230c4eaeba2b825596bad58526f91..e5e03bf83cabcdef900ec2aa673ff27b5c9513d8 100644 (file)
@@ -71,7 +71,7 @@ struct MMapCache {
 /* Tiny windows increase mmap activity and the chance of exposing unsafe use. */
 # define WINDOW_SIZE (page_size())
 #else
-# define WINDOW_SIZE (8ULL*1024ULL*1024ULL)
+# define WINDOW_SIZE ((size_t) (UINT64_C(8) * UINT64_C(1024) * UINT64_C(1024)))
 #endif
 
 MMapCache* mmap_cache_new(void) {
@@ -269,7 +269,6 @@ static int add_mmap(
                 struct stat *st,
                 Window **ret) {
 
-        uint64_t woffset, wsize;
         Window *w;
         void *d;
         int r;
@@ -278,41 +277,42 @@ static int add_mmap(
         assert(size > 0);
         assert(ret);
 
-        woffset = offset & ~((uint64_t) page_size() - 1ULL);
-        wsize = size + (offset - woffset);
-        wsize = PAGE_ALIGN(wsize);
+        /* overflow check */
+        if (size > SIZE_MAX - PAGE_OFFSET_U64(offset))
+                return -EADDRNOTAVAIL;
 
-        if (wsize < WINDOW_SIZE) {
-                uint64_t delta;
-
-                delta = PAGE_ALIGN((WINDOW_SIZE - wsize) / 2);
+        size = PAGE_ALIGN(size + PAGE_OFFSET_U64(offset));
+        offset = PAGE_ALIGN_DOWN_U64(offset);
 
-                if (delta > offset)
-                        woffset = 0;
-                else
-                        woffset -= delta;
+        if (size < WINDOW_SIZE) {
+                uint64_t delta;
 
-                wsize = WINDOW_SIZE;
+                delta = PAGE_ALIGN((WINDOW_SIZE - size) / 2);
+                offset = LESS_BY(offset, delta);
+                size = WINDOW_SIZE;
         }
 
         if (st) {
                 /* Memory maps that are larger then the files underneath have undefined behavior. Hence,
                  * clamp things to the file size if we know it */
 
-                if (woffset >= (uint64_t) st->st_size)
+                if (offset >= (uint64_t) st->st_size)
                         return -EADDRNOTAVAIL;
 
-                if (woffset + wsize > (uint64_t) st->st_size)
-                        wsize = PAGE_ALIGN(st->st_size - woffset);
+                if (size > (uint64_t) st->st_size - offset)
+                        size = PAGE_ALIGN((uint64_t) st->st_size - offset);
         }
 
-        r = mmap_try_harder(f, NULL, MAP_SHARED, woffset, wsize, &d);
+        if (size >= SIZE_MAX)
+                return -EADDRNOTAVAIL;
+
+        r = mmap_try_harder(f, NULL, MAP_SHARED, offset, size, &d);
         if (r < 0)
                 return r;
 
-        w = window_add(f, woffset, wsize, d);
+        w = window_add(f, offset, size, d);
         if (!w) {
-                (void) munmap(d, wsize);
+                (void) munmap(d, size);
                 return -ENOMEM;
         }
 
index 979eb3cee78685e08252b89d48aba84c12b38264..a12eb516cc5069c74b74752f64beb4464f74f535 100644 (file)
@@ -613,7 +613,7 @@ static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) {
         assert(operation);
         assert(operation->extra_fd >= 0);
 
-        if (lseek(operation->extra_fd, 0, SEEK_SET) == (off_t) -1)
+        if (lseek(operation->extra_fd, 0, SEEK_SET) < 0)
                 return -errno;
 
         f = take_fdopen(&operation->extra_fd, "r");
index 9109ea18237d18b26da514ac98fd7834ac147b62..e8a492c7cea7479a86f08a7627c3e8fbab9c3fed 100644 (file)
@@ -3561,7 +3561,7 @@ static int partition_target_prepare(
         };
 
         if (!need_path) {
-                if (lseek(whole_fd, p->offset, SEEK_SET) == (off_t) -1)
+                if (lseek(whole_fd, p->offset, SEEK_SET) < 0)
                         return log_error_errno(errno, "Failed to seek to partition offset: %m");
 
                 t->whole_fd = whole_fd;
@@ -3637,10 +3637,10 @@ static int partition_target_sync(Context *context, Partition *p, PartitionTarget
         } else if (t->fd >= 0) {
                 struct stat st;
 
-                if (lseek(whole_fd, p->offset, SEEK_SET) == (off_t) -1)
+                if (lseek(whole_fd, p->offset, SEEK_SET) < 0)
                         return log_error_errno(errno, "Failed to seek to partition offset: %m");
 
-                if (lseek(t->fd, 0, SEEK_SET) == (off_t) -1)
+                if (lseek(t->fd, 0, SEEK_SET) < 0)
                         return log_error_errno(errno, "Failed to seek to start of temporary file: %m");
 
                 if (fstat(t->fd, &st) < 0)
@@ -4194,7 +4194,7 @@ static int partition_format_verity_sig(Context *context, Partition *p) {
         if (r < 0)
                 return log_error_errno(r, "Failed to pad string to %s", FORMAT_BYTES(p->new_size));
 
-        if (lseek(whole_fd, p->offset, SEEK_SET) == (off_t) -1)
+        if (lseek(whole_fd, p->offset, SEEK_SET) < 0)
                 return log_error_errno(errno, "Failed to seek to partition %s offset: %m", strna(hint));
 
         r = loop_write(whole_fd, text, p->new_size);
index a2740857e9a3906f8432e9a3372c73244c6e7ef2..c0e30cdc278f520c2184e674a3f5789c28591ca0 100644 (file)
@@ -638,6 +638,10 @@ static void hardlink_context_destroy(HardlinkContext *c) {
          * _cleanup_() so that we really delete this, even on failure. */
 
         if (c->dir_fd >= 0) {
+                /* <dir_fd> might be have already been used for reading, so we need to rewind it. */
+                if (lseek(c->dir_fd, 0, SEEK_SET) < 0)
+                        log_debug_errno(errno, "Failed to lseek on file descriptor, ignoring: %m");
+
                 r = rm_rf_children(TAKE_FD(c->dir_fd), REMOVE_PHYSICAL, NULL); /* consumes dir_fd in all cases, even on failure */
                 if (r < 0)
                         log_debug_errno(r, "Failed to remove hardlink store (%s) contents, ignoring: %m", c->subdir);
index 57a1bb9daa0564c7237b5ab91d1933433f59ee64..5a4d3bbb50ba46431273d9d6cf5420311e02d3a3 100644 (file)
@@ -588,7 +588,7 @@ static int parse_core(int fd, const char *executable, char **ret, JsonVariant **
 
         assert(fd >= 0);
 
-        if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
+        if (lseek(fd, 0, SEEK_SET) < 0)
                 return log_warning_errno(errno, "Failed to seek to beginning of the core file: %m");
 
         if (ret && !memstream_init(&c.m))
@@ -644,7 +644,7 @@ static int parse_elf(int fd, const char *executable, char **ret, JsonVariant **r
 
         assert(fd >= 0);
 
-        if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
+        if (lseek(fd, 0, SEEK_SET) < 0)
                 return log_warning_errno(errno, "Failed to seek to beginning of the ELF file: %m");
 
         if (ret && !memstream_init(&c.m))
index 7263b6a204e0970131b480b8bb5e8b260b951b59..d6aa667adacaf4e41a5ea8f292dd081344d57ba7 100644 (file)
@@ -151,7 +151,7 @@ int machine_id_setup(const char *root, bool force_transient, sd_id128_t machine_
         }
 
         if (writable) {
-                if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
+                if (lseek(fd, 0, SEEK_SET) < 0)
                         return log_error_errno(errno, "Failed to seek %s: %m", etc_machine_id);
 
                 if (ftruncate(fd, 0) < 0)
index b7ac03f5aeb0b28d8fcae9ee5f1648d0ba56ea0e..e497035d41a4c3521ee1ab157bc0050db02141eb 100644 (file)
@@ -1067,7 +1067,7 @@ finish:
 }
 
 static int mount_in_namespace(
-                PidRef *target,
+                const PidRef *target,
                 const char *propagate_path,
                 const char *incoming_path,
                 const char *src,
index e1dc4024dc68518e9afa14cc9d0f8b326390b5fc..4664215e906204123587d7b3b63e0b0f78aa5861 100644 (file)
@@ -365,10 +365,6 @@ static int rm_rf_children_impl(
                                                                strna(path));
                                 }
                         }
-
-                        /* Make sure we reset the iterator since we don't know the state the passed in file
-                         * descriptor is in. */
-                        rewinddir(d);
                 }
 
                 FOREACH_DIRENT_ALL(de, d, return -errno) {
index 9d93692e0a6e531123d078365a7efbb89b4d5947..6e52bbb41d4c198dc526b917ded2ff9a44b75912 100644 (file)
@@ -25,6 +25,8 @@ int fstatat_harder(int dfd,
                 int fstatat_flags,
                 RemoveFlags remove_flags);
 
+/* Note: directory file descriptors passed to the functions below must be
+ * positioned at the beginning. If the fd was already used for reading, rewind it. */
 int rm_rf_children(int fd, RemoveFlags flags, const struct stat *root_dev);
 int rm_rf_child(int fd, const char *name, RemoveFlags flags);
 int rm_rf_at(int dir_fd, const char *path, RemoveFlags flags);
index b63071a6928ed213f62890f315ee0c4395a0b38b..ab095303557e46631c474a75a9d23e960ee8f3f8 100644 (file)
@@ -42,7 +42,7 @@ static char* const* const sleep_default_state_table[_SLEEP_OPERATION_CONFIG_MAX]
 static char* const* const sleep_default_mode_table[_SLEEP_OPERATION_CONFIG_MAX] = {
         /* Not used by SLEEP_SUSPEND */
         [SLEEP_HIBERNATE]    = STRV_MAKE("platform", "shutdown"),
-        [SLEEP_HYBRID_SLEEP] = STRV_MAKE("suspend", "platform", "shutdown"),
+        [SLEEP_HYBRID_SLEEP] = STRV_MAKE("suspend"),
 };
 
 SleepConfig* sleep_config_free(SleepConfig *sc) {
@@ -76,10 +76,6 @@ static void sleep_config_validate_state_and_mode(SleepConfig *sc) {
         if (strv_contains(sc->modes[SLEEP_HIBERNATE], "suspend"))
                 log_warning("Sleep mode 'suspend' should not be used by operation %s. Please use %s instead.",
                             sleep_operation_to_string(SLEEP_HIBERNATE), sleep_operation_to_string(SLEEP_HYBRID_SLEEP));
-
-        if (!strv_contains(sc->modes[SLEEP_HYBRID_SLEEP], "suspend"))
-                log_warning("Sleep mode 'suspend' is not set for operation %s. This would likely result in a plain hibernation.",
-                            sleep_operation_to_string(SLEEP_HYBRID_SLEEP));
 }
 
 int parse_sleep_config(SleepConfig **ret) {
@@ -97,22 +93,22 @@ int parse_sleep_config(SleepConfig **ret) {
         };
 
         const ConfigTableItem items[] = {
-                { "Sleep", "AllowSuspend",              config_parse_tristate,    0,               &allow_suspend                 },
-                { "Sleep", "AllowHibernation",          config_parse_tristate,    0,               &allow_hibernate               },
-                { "Sleep", "AllowSuspendThenHibernate", config_parse_tristate,    0,               &allow_s2h                     },
-                { "Sleep", "AllowHybridSleep",          config_parse_tristate,    0,               &allow_hybrid_sleep            },
+                { "Sleep", "AllowSuspend",              config_parse_tristate,    0,               &allow_suspend               },
+                { "Sleep", "AllowHibernation",          config_parse_tristate,    0,               &allow_hibernate             },
+                { "Sleep", "AllowSuspendThenHibernate", config_parse_tristate,    0,               &allow_s2h                   },
+                { "Sleep", "AllowHybridSleep",          config_parse_tristate,    0,               &allow_hybrid_sleep          },
 
-                { "Sleep", "SuspendState",              config_parse_strv,        0,               sc->states + SLEEP_SUSPEND     },
-                { "Sleep", "SuspendMode",               config_parse_warn_compat, DISABLED_LEGACY, NULL                           },
+                { "Sleep", "SuspendState",              config_parse_strv,        0,               sc->states + SLEEP_SUSPEND   },
+                { "Sleep", "SuspendMode",               config_parse_warn_compat, DISABLED_LEGACY, NULL                         },
 
-                { "Sleep", "HibernateState",            config_parse_warn_compat, DISABLED_LEGACY, NULL                           },
-                { "Sleep", "HibernateMode",             config_parse_strv,        0,               sc->modes + SLEEP_HIBERNATE    },
+                { "Sleep", "HibernateState",            config_parse_warn_compat, DISABLED_LEGACY, NULL                         },
+                { "Sleep", "HibernateMode",             config_parse_strv,        0,               sc->modes + SLEEP_HIBERNATE  },
 
-                { "Sleep", "HybridSleepState",          config_parse_warn_compat, DISABLED_LEGACY, NULL                           },
-                { "Sleep", "HybridSleepMode",           config_parse_strv,        0,               sc->modes + SLEEP_HYBRID_SLEEP },
+                { "Sleep", "HybridSleepState",          config_parse_warn_compat, DISABLED_LEGACY, NULL                         },
+                { "Sleep", "HybridSleepMode",           config_parse_warn_compat, DISABLED_LEGACY, NULL                         },
 
-                { "Sleep", "HibernateDelaySec",         config_parse_sec,         0,               &sc->hibernate_delay_usec      },
-                { "Sleep", "SuspendEstimationSec",      config_parse_sec,         0,               &sc->suspend_estimation_usec   },
+                { "Sleep", "HibernateDelaySec",         config_parse_sec,         0,               &sc->hibernate_delay_usec    },
+                { "Sleep", "SuspendEstimationSec",      config_parse_sec,         0,               &sc->suspend_estimation_usec },
                 {}
         };
 
index 43e04c6518f56f5dba4f235b1abd5bdaf3a99722..8d5097135616cc730b5edcf77c45e907253543a5 100644 (file)
@@ -4594,7 +4594,7 @@ static int tpm2_userspace_log(
         if (r < 0)
                 return log_debug_errno(r, "Failed to format JSON: %m");
 
-        if (lseek(fd, 0, SEEK_END) == (off_t) -1)
+        if (lseek(fd, 0, SEEK_END) < 0)
                 return log_debug_errno(errno, "Failed to seek to end of JSON log: %m");
 
         r = loop_write(fd, f, SIZE_MAX);
index 06f7dc38a4c7eaa3f9e9ededa39951f2bc683d54..fad95b389779fbbddf3f246cd60b5907a8248277 100644 (file)
@@ -23,6 +23,5 @@
 #AllowHybridSleep=yes
 #SuspendState=mem standby freeze
 #HibernateMode=platform shutdown
-#HybridSleepMode=suspend platform shutdown
 #HibernateDelaySec=
 #SuspendEstimationSec=60min
index 810ebc580e7acb0d97b43b78ffa2fd6cf652d96e..63fe6ea95e76bdb7fdb6505338150453a660a06e 100644 (file)
@@ -513,6 +513,34 @@ TEST(align_to) {
         assert_se(ALIGN_TO(SIZE_MAX-1, 4) == SIZE_MAX); /* overflow */
         assert_se(ALIGN_TO(SIZE_MAX, 4) == SIZE_MAX);   /* overflow */
 
+        assert_se(ALIGN_TO_U64(0, 1) == 0);
+        assert_se(ALIGN_TO_U64(1, 1) == 1);
+        assert_se(ALIGN_TO_U64(2, 1) == 2);
+        assert_se(ALIGN_TO_U64(3, 1) == 3);
+        assert_se(ALIGN_TO_U64(4, 1) == 4);
+        assert_se(ALIGN_TO_U64(UINT64_MAX-1, 1) == UINT64_MAX-1);
+        assert_se(ALIGN_TO_U64(UINT64_MAX, 1) == UINT64_MAX);
+
+        assert_se(ALIGN_TO_U64(0, 2) == 0);
+        assert_se(ALIGN_TO_U64(1, 2) == 2);
+        assert_se(ALIGN_TO_U64(2, 2) == 2);
+        assert_se(ALIGN_TO_U64(3, 2) == 4);
+        assert_se(ALIGN_TO_U64(4, 2) == 4);
+        assert_se(ALIGN_TO_U64(UINT64_MAX-3, 2) == UINT64_MAX-3);
+        assert_se(ALIGN_TO_U64(UINT64_MAX-2, 2) == UINT64_MAX-1);
+        assert_se(ALIGN_TO_U64(UINT64_MAX-1, 2) == UINT64_MAX-1);
+        assert_se(ALIGN_TO_U64(UINT64_MAX, 2) == UINT64_MAX); /* overflow */
+
+        assert_se(ALIGN_TO_U64(0, 4) == 0);
+        assert_se(ALIGN_TO_U64(1, 4) == 4);
+        assert_se(ALIGN_TO_U64(2, 4) == 4);
+        assert_se(ALIGN_TO_U64(3, 4) == 4);
+        assert_se(ALIGN_TO_U64(4, 4) == 4);
+        assert_se(ALIGN_TO_U64(UINT64_MAX-3, 4) == UINT64_MAX-3);
+        assert_se(ALIGN_TO_U64(UINT64_MAX-2, 4) == UINT64_MAX); /* overflow */
+        assert_se(ALIGN_TO_U64(UINT64_MAX-1, 4) == UINT64_MAX); /* overflow */
+        assert_se(ALIGN_TO_U64(UINT64_MAX, 4) == UINT64_MAX);   /* overflow */
+
         assert_cc(CONST_ALIGN_TO(96, 512) == 512);
         assert_cc(CONST_ALIGN_TO(511, 512) == 512);
         assert_cc(CONST_ALIGN_TO(512, 512) == 512);
@@ -523,6 +551,106 @@ TEST(align_to) {
         assert_cc(__builtin_types_compatible_p(typeof(CONST_ALIGN_TO(SIZE_MAX, 512)), void));
 }
 
+TEST(align_down) {
+        assert_se(ALIGN_DOWN(0, 1) == 0);
+        assert_se(ALIGN_DOWN(1, 1) == 1);
+        assert_se(ALIGN_DOWN(2, 1) == 2);
+        assert_se(ALIGN_DOWN(3, 1) == 3);
+        assert_se(ALIGN_DOWN(4, 1) == 4);
+        assert_se(ALIGN_DOWN(SIZE_MAX-1, 1) == SIZE_MAX-1);
+        assert_se(ALIGN_DOWN(SIZE_MAX, 1) == SIZE_MAX);
+
+        assert_se(ALIGN_DOWN(0, 2) == 0);
+        assert_se(ALIGN_DOWN(1, 2) == 0);
+        assert_se(ALIGN_DOWN(2, 2) == 2);
+        assert_se(ALIGN_DOWN(3, 2) == 2);
+        assert_se(ALIGN_DOWN(4, 2) == 4);
+        assert_se(ALIGN_DOWN(SIZE_MAX-1, 2) == SIZE_MAX-1);
+        assert_se(ALIGN_DOWN(SIZE_MAX, 2) == SIZE_MAX-1);
+
+        assert_se(ALIGN_DOWN(0, 4) == 0);
+        assert_se(ALIGN_DOWN(1, 4) == 0);
+        assert_se(ALIGN_DOWN(2, 4) == 0);
+        assert_se(ALIGN_DOWN(3, 4) == 0);
+        assert_se(ALIGN_DOWN(4, 4) == 4);
+        assert_se(ALIGN_DOWN(SIZE_MAX-1, 4) == SIZE_MAX-3);
+        assert_se(ALIGN_DOWN(SIZE_MAX, 4) == SIZE_MAX-3);
+
+        assert_se(ALIGN_DOWN_U64(0, 1) == 0);
+        assert_se(ALIGN_DOWN_U64(1, 1) == 1);
+        assert_se(ALIGN_DOWN_U64(2, 1) == 2);
+        assert_se(ALIGN_DOWN_U64(3, 1) == 3);
+        assert_se(ALIGN_DOWN_U64(4, 1) == 4);
+        assert_se(ALIGN_DOWN_U64(UINT64_MAX-1, 1) == UINT64_MAX-1);
+        assert_se(ALIGN_DOWN_U64(UINT64_MAX, 1) == UINT64_MAX);
+
+        assert_se(ALIGN_DOWN_U64(0, 2) == 0);
+        assert_se(ALIGN_DOWN_U64(1, 2) == 0);
+        assert_se(ALIGN_DOWN_U64(2, 2) == 2);
+        assert_se(ALIGN_DOWN_U64(3, 2) == 2);
+        assert_se(ALIGN_DOWN_U64(4, 2) == 4);
+        assert_se(ALIGN_DOWN_U64(UINT64_MAX-1, 2) == UINT64_MAX-1);
+        assert_se(ALIGN_DOWN_U64(UINT64_MAX, 2) == UINT64_MAX-1);
+
+        assert_se(ALIGN_DOWN_U64(0, 4) == 0);
+        assert_se(ALIGN_DOWN_U64(1, 4) == 0);
+        assert_se(ALIGN_DOWN_U64(2, 4) == 0);
+        assert_se(ALIGN_DOWN_U64(3, 4) == 0);
+        assert_se(ALIGN_DOWN_U64(4, 4) == 4);
+        assert_se(ALIGN_DOWN_U64(UINT64_MAX-1, 4) == UINT64_MAX-3);
+        assert_se(ALIGN_DOWN_U64(UINT64_MAX, 4) == UINT64_MAX-3);
+}
+
+TEST(align_offset) {
+        assert_se(ALIGN_OFFSET(0, 1) == 0);
+        assert_se(ALIGN_OFFSET(1, 1) == 0);
+        assert_se(ALIGN_OFFSET(2, 1) == 0);
+        assert_se(ALIGN_OFFSET(3, 1) == 0);
+        assert_se(ALIGN_OFFSET(4, 1) == 0);
+        assert_se(ALIGN_OFFSET(SIZE_MAX-1, 1) == 0);
+        assert_se(ALIGN_OFFSET(SIZE_MAX, 1) == 0);
+
+        assert_se(ALIGN_OFFSET(0, 2) == 0);
+        assert_se(ALIGN_OFFSET(1, 2) == 1);
+        assert_se(ALIGN_OFFSET(2, 2) == 0);
+        assert_se(ALIGN_OFFSET(3, 2) == 1);
+        assert_se(ALIGN_OFFSET(4, 2) == 0);
+        assert_se(ALIGN_OFFSET(SIZE_MAX-1, 2) == 0);
+        assert_se(ALIGN_OFFSET(SIZE_MAX, 2) == 1);
+
+        assert_se(ALIGN_OFFSET(0, 4) == 0);
+        assert_se(ALIGN_OFFSET(1, 4) == 1);
+        assert_se(ALIGN_OFFSET(2, 4) == 2);
+        assert_se(ALIGN_OFFSET(3, 4) == 3);
+        assert_se(ALIGN_OFFSET(4, 4) == 0);
+        assert_se(ALIGN_OFFSET(SIZE_MAX-1, 4) == 2);
+        assert_se(ALIGN_OFFSET(SIZE_MAX, 4) == 3);
+
+        assert_se(ALIGN_OFFSET_U64(0, 1) == 0);
+        assert_se(ALIGN_OFFSET_U64(1, 1) == 0);
+        assert_se(ALIGN_OFFSET_U64(2, 1) == 0);
+        assert_se(ALIGN_OFFSET_U64(3, 1) == 0);
+        assert_se(ALIGN_OFFSET_U64(4, 1) == 0);
+        assert_se(ALIGN_OFFSET_U64(UINT64_MAX-1, 1) == 0);
+        assert_se(ALIGN_OFFSET_U64(UINT64_MAX, 1) == 0);
+
+        assert_se(ALIGN_OFFSET_U64(0, 2) == 0);
+        assert_se(ALIGN_OFFSET_U64(1, 2) == 1);
+        assert_se(ALIGN_OFFSET_U64(2, 2) == 0);
+        assert_se(ALIGN_OFFSET_U64(3, 2) == 1);
+        assert_se(ALIGN_OFFSET_U64(4, 2) == 0);
+        assert_se(ALIGN_OFFSET_U64(UINT64_MAX-1, 2) == 0);
+        assert_se(ALIGN_OFFSET_U64(UINT64_MAX, 2) == 1);
+
+        assert_se(ALIGN_OFFSET_U64(0, 4) == 0);
+        assert_se(ALIGN_OFFSET_U64(1, 4) == 1);
+        assert_se(ALIGN_OFFSET_U64(2, 4) == 2);
+        assert_se(ALIGN_OFFSET_U64(3, 4) == 3);
+        assert_se(ALIGN_OFFSET_U64(4, 4) == 0);
+        assert_se(ALIGN_OFFSET_U64(UINT64_MAX-1, 4) == 2);
+        assert_se(ALIGN_OFFSET_U64(UINT64_MAX, 4) == 3);
+}
+
 TEST(flags) {
         enum {
                 F1 = 1 << 0,
@@ -884,4 +1012,29 @@ TEST(round_up) {
         TEST_ROUND_UP_BY_TYPE(uint64_t, UINT64_MAX);
 }
 
+TEST(u64_multiply_safe) {
+        assert_se(u64_multiply_safe(0, 0) == 0);
+        assert_se(u64_multiply_safe(10, 0) == 0);
+        assert_se(u64_multiply_safe(0, 10) == 0);
+        assert_se(u64_multiply_safe(10, 10) == 100);
+
+        assert_se(u64_multiply_safe(UINT64_MAX, 0) == 0);
+        assert_se(u64_multiply_safe(UINT64_MAX, 1) == UINT64_MAX);
+        assert_se(u64_multiply_safe(UINT64_MAX, 2) == 0);
+        assert_se(u64_multiply_safe(0, UINT64_MAX) == 0);
+        assert_se(u64_multiply_safe(1, UINT64_MAX) == UINT64_MAX);
+        assert_se(u64_multiply_safe(2, UINT64_MAX) == 0);
+
+        assert_se(u64_multiply_safe(UINT64_MAX / 2, 0) == 0);
+        assert_se(u64_multiply_safe(UINT64_MAX / 2, 1) == UINT64_MAX / 2);
+        assert_se(u64_multiply_safe(UINT64_MAX / 2, 2) == UINT64_MAX - 1);
+        assert_se(u64_multiply_safe(UINT64_MAX / 2, 3) == 0);
+        assert_se(u64_multiply_safe(0, UINT64_MAX / 2) == 0);
+        assert_se(u64_multiply_safe(1, UINT64_MAX / 2) == UINT64_MAX / 2);
+        assert_se(u64_multiply_safe(2, UINT64_MAX / 2) == UINT64_MAX - 1);
+        assert_se(u64_multiply_safe(3, UINT64_MAX / 2) == 0);
+
+        assert_se(u64_multiply_safe(UINT64_MAX, UINT64_MAX) == 0);
+}
+
 DEFINE_TEST_MAIN(LOG_INFO);
index 2f8384ac09b26844d2e9a2c7957baa1eae0dcfb8..cd4b64ac164b4e6e8668640266705cfc1ced9285 100644 (file)
@@ -52,4 +52,74 @@ TEST(cleanup_array) {
         free(saved_iov);
 }
 
+TEST(page_align) {
+        assert_se(PAGE_ALIGN(page_size() - 1) == page_size());
+        assert_se(PAGE_ALIGN(page_size()    ) == page_size());
+        assert_se(PAGE_ALIGN(page_size() + 1) == page_size() * 2);
+        assert_se(PAGE_ALIGN(page_size() * 123 - 1) == page_size() * 123);
+        assert_se(PAGE_ALIGN(page_size() * 123    ) == page_size() * 123);
+        assert_se(PAGE_ALIGN(page_size() * 123 + 1) == page_size() * 124);
+        assert_se(PAGE_ALIGN(SIZE_MAX - page_size() - 1) == SIZE_MAX - page_size() + 1);
+        assert_se(PAGE_ALIGN(SIZE_MAX - page_size()    ) == SIZE_MAX - page_size() + 1);
+        assert_se(PAGE_ALIGN(SIZE_MAX - page_size() + 1) == SIZE_MAX - page_size() + 1);
+        assert_se(PAGE_ALIGN(SIZE_MAX - page_size() + 2) == SIZE_MAX); /* overflow */
+        assert_se(PAGE_ALIGN(SIZE_MAX) == SIZE_MAX); /* overflow */
+
+        assert_se(PAGE_ALIGN_U64(page_size() - 1) == page_size());
+        assert_se(PAGE_ALIGN_U64(page_size()    ) == page_size());
+        assert_se(PAGE_ALIGN_U64(page_size() + 1) == page_size() * 2);
+        assert_se(PAGE_ALIGN_U64(page_size() * 123 - 1) == page_size() * 123);
+        assert_se(PAGE_ALIGN_U64(page_size() * 123    ) == page_size() * 123);
+        assert_se(PAGE_ALIGN_U64(page_size() * 123 + 1) == page_size() * 124);
+        assert_se(PAGE_ALIGN_U64(UINT64_MAX - page_size() - 1) == UINT64_MAX - page_size() + 1);
+        assert_se(PAGE_ALIGN_U64(UINT64_MAX - page_size()    ) == UINT64_MAX - page_size() + 1);
+        assert_se(PAGE_ALIGN_U64(UINT64_MAX - page_size() + 1) == UINT64_MAX - page_size() + 1);
+        assert_se(PAGE_ALIGN_U64(UINT64_MAX - page_size() + 2) == UINT64_MAX); /* overflow */
+        assert_se(PAGE_ALIGN_U64(UINT64_MAX) == UINT64_MAX); /* overflow */
+
+        assert_se(PAGE_ALIGN_DOWN(page_size() - 1) == 0);
+        assert_se(PAGE_ALIGN_DOWN(page_size()    ) == page_size());
+        assert_se(PAGE_ALIGN_DOWN(page_size() + 1) == page_size());
+        assert_se(PAGE_ALIGN_DOWN(page_size() * 123 - 1) == page_size() * 122);
+        assert_se(PAGE_ALIGN_DOWN(page_size() * 123    ) == page_size() * 123);
+        assert_se(PAGE_ALIGN_DOWN(page_size() * 123 + 1) == page_size() * 123);
+        assert_se(PAGE_ALIGN_DOWN(SIZE_MAX - page_size() - 1) == SIZE_MAX - page_size() * 2 + 1);
+        assert_se(PAGE_ALIGN_DOWN(SIZE_MAX - page_size()    ) == SIZE_MAX - page_size() * 2 + 1);
+        assert_se(PAGE_ALIGN_DOWN(SIZE_MAX - page_size() + 1) == SIZE_MAX - page_size() + 1);
+        assert_se(PAGE_ALIGN_DOWN(SIZE_MAX - page_size() + 2) == SIZE_MAX - page_size() + 1);
+
+        assert_se(PAGE_ALIGN_DOWN_U64(page_size() - 1) == 0);
+        assert_se(PAGE_ALIGN_DOWN_U64(page_size()    ) == page_size());
+        assert_se(PAGE_ALIGN_DOWN_U64(page_size() + 1) == page_size());
+        assert_se(PAGE_ALIGN_DOWN_U64(page_size() * 123 - 1) == page_size() * 122);
+        assert_se(PAGE_ALIGN_DOWN_U64(page_size() * 123    ) == page_size() * 123);
+        assert_se(PAGE_ALIGN_DOWN_U64(page_size() * 123 + 1) == page_size() * 123);
+        assert_se(PAGE_ALIGN_DOWN_U64(SIZE_MAX - page_size() - 1) == SIZE_MAX - page_size() * 2 + 1);
+        assert_se(PAGE_ALIGN_DOWN_U64(SIZE_MAX - page_size()    ) == SIZE_MAX - page_size() * 2 + 1);
+        assert_se(PAGE_ALIGN_DOWN_U64(SIZE_MAX - page_size() + 1) == SIZE_MAX - page_size() + 1);
+        assert_se(PAGE_ALIGN_DOWN_U64(SIZE_MAX - page_size() + 2) == SIZE_MAX - page_size() + 1);
+
+        assert_se(PAGE_OFFSET(page_size() - 1) == page_size() - 1);
+        assert_se(PAGE_OFFSET(page_size()    ) == 0);
+        assert_se(PAGE_OFFSET(page_size() + 1) == 1);
+        assert_se(PAGE_OFFSET(page_size() * 123 - 1) == page_size() - 1);
+        assert_se(PAGE_OFFSET(page_size() * 123    ) == 0);
+        assert_se(PAGE_OFFSET(page_size() * 123 + 1) == 1);
+        assert_se(PAGE_OFFSET(SIZE_MAX - page_size() - 1) == page_size() - 2);
+        assert_se(PAGE_OFFSET(SIZE_MAX - page_size()    ) == page_size() - 1);
+        assert_se(PAGE_OFFSET(SIZE_MAX - page_size() + 1) == 0);
+        assert_se(PAGE_OFFSET(SIZE_MAX - page_size() + 2) == 1);
+
+        assert_se(PAGE_OFFSET_U64(page_size() - 1) == page_size() - 1);
+        assert_se(PAGE_OFFSET_U64(page_size()    ) == 0);
+        assert_se(PAGE_OFFSET_U64(page_size() + 1) == 1);
+        assert_se(PAGE_OFFSET_U64(page_size() * 123 - 1) == page_size() - 1);
+        assert_se(PAGE_OFFSET_U64(page_size() * 123    ) == 0);
+        assert_se(PAGE_OFFSET_U64(page_size() * 123 + 1) == 1);
+        assert_se(PAGE_OFFSET_U64(UINT64_MAX - page_size() - 1) == page_size() - 2);
+        assert_se(PAGE_OFFSET_U64(UINT64_MAX - page_size()    ) == page_size() - 1);
+        assert_se(PAGE_OFFSET_U64(UINT64_MAX - page_size() + 1) == 0);
+        assert_se(PAGE_OFFSET_U64(UINT64_MAX - page_size() + 2) == 1);
+}
+
 DEFINE_TEST_MAIN(LOG_INFO);
index c7f78fe3c9b8115a9eff68bda221eff7c8e0c691..8fdbaf81fe247ceb853a2f7227a3098cf283ad87 100755 (executable)
@@ -4,7 +4,9 @@ set -e
 
 TEST_DESCRIPTION="shutdown testing"
 IMAGE_NAME="shutdown"
-TEST_NO_QEMU=1
+TEST_NO_QEMU=yes
+# Prevent shutdown in test suite, the expect script does that manually.
+TEST_SKIP_SHUTDOWN=yes
 
 # shellcheck source=test/test-functions
 . "${TEST_BASE_DIR:?}/test-functions"
@@ -23,13 +25,17 @@ EOF
 
 test_append_files() {
     local workspace="${1:?}"
-    # prevent shutdown in test suite, the expect script does that manually.
-    mkdir -p "${workspace:?}/etc/systemd/system/end.service.d"
-    cat >"$workspace/etc/systemd/system/end.service.d/99-override.conf" <<EOF
-[Service]
-ExecStart=
-ExecStart=/bin/true
+
+    # Shorten the service stop/abort timeouts to let systemd SIGKILL stubborn
+    # processes as soon as possible, as we don't really care about them in this
+    # particular test
+    mkdir -p "$workspace/etc/systemd/system.conf.d"
+    cat >"$workspace/etc/systemd/system.conf.d/99-timeout.conf" <<EOF
+[Manager]
+DefaultTimeoutStopSec=30s
+DefaultTimeoutAbortSec=30s
 EOF
+
     inst /usr/bin/screen
     echo "PS1='screen\$WINDOW # '" >>"$workspace/root/.bashrc"
     echo 'startup_message off' >"$workspace/etc/screenrc"
index 101b25084269f7613e583ac0deedf7202bc79f71..049414918567804844a91146284ea26a1d8f0780 100755 (executable)
@@ -5,19 +5,10 @@ set -e
 TEST_DESCRIPTION="Test Soft-Rebooting"
 # We temporarily remount rootfs read-only, so ignore any missing coverage
 IGNORE_MISSING_COVERAGE=yes
+# Prevent shutdown in test suite, the expect script does that manually.
+TEST_SKIP_SHUTDOWN=yes
 
 # shellcheck source=test/test-functions
 . "$TEST_BASE_DIR/test-functions"
 
-test_append_files() {
-    local workspace="${1:?}"
-    # prevent shutdown in test suite, the expect script does that manually.
-    mkdir -p "${workspace:?}/etc/systemd/system/end.service.d"
-    cat >"$workspace/etc/systemd/system/end.service.d/99-override.conf" <<EOF
-[Service]
-ExecStart=
-ExecStart=/bin/true
-EOF
-}
-
 do_test "$@"
index 0c90a310a1af263c101aa10280e591adb2640824..60db47c86aa6908e46943711ecc1ad3a5c299cbe 100644 (file)
@@ -561,13 +561,13 @@ run_qemu() {
         "systemd.unit=testsuite.target"
         "systemd.wants=testsuite-$1.service"
         "noresume"
+        "oops=panic"
         ${TEST_MATCH_SUBTEST:+"systemd.setenv=TEST_MATCH_SUBTEST=$TEST_MATCH_SUBTEST"}
         ${TEST_MATCH_TESTCASE:+"systemd.setenv=TEST_MATCH_TESTCASE=$TEST_MATCH_TESTCASE"}
     )
 
-    if ! get_bool "$INTERACTIVE_DEBUG"; then
+    if ! get_bool "$INTERACTIVE_DEBUG" && ! get_bool "$TEST_SKIP_SHUTDOWN"; then
         kernel_params+=(
-            "oops=panic"
             "panic=1"
             "systemd.wants=end.service"
         )
@@ -666,7 +666,7 @@ run_nspawn() {
 
     if get_bool "$INTERACTIVE_DEBUG"; then
         nspawn_options+=("--console=interactive")
-    else
+    elif ! get_bool "$TEST_SKIP_SHUTDOWN"; then
         kernel_params+=("systemd.wants=end.service")
     fi