From 5fc298f755d654c9adf78e9948c3204366768c88 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Feb 28 2023 07:54:12 +0000 Subject: import systemd-250-12.el9_1.3 --- diff --git a/SOURCES/0353-coredump-adjust-whitespace.patch b/SOURCES/0353-coredump-adjust-whitespace.patch new file mode 100644 index 0000000..8d8e54c --- /dev/null +++ b/SOURCES/0353-coredump-adjust-whitespace.patch @@ -0,0 +1,101 @@ +From 6415f270c3733d3c80e4d5bdc2e67f9ffb108308 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 29 Nov 2022 09:00:16 +0100 +Subject: [PATCH] coredump: adjust whitespace + +(cherry picked from commit 510a146634f3e095b34e2a26023b1b1f99dcb8c0) + +Related: #2155516 +--- + src/coredump/coredump.c | 56 ++++++++++++++++++++--------------------- + 1 file changed, 28 insertions(+), 28 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index fd156370b2..5f315b9a79 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -109,16 +109,16 @@ enum { + }; + + static const char * const meta_field_names[_META_MAX] = { +- [META_ARGV_PID] = "COREDUMP_PID=", +- [META_ARGV_UID] = "COREDUMP_UID=", +- [META_ARGV_GID] = "COREDUMP_GID=", +- [META_ARGV_SIGNAL] = "COREDUMP_SIGNAL=", +- [META_ARGV_TIMESTAMP] = "COREDUMP_TIMESTAMP=", +- [META_ARGV_RLIMIT] = "COREDUMP_RLIMIT=", +- [META_ARGV_HOSTNAME] = "COREDUMP_HOSTNAME=", +- [META_COMM] = "COREDUMP_COMM=", +- [META_EXE] = "COREDUMP_EXE=", +- [META_UNIT] = "COREDUMP_UNIT=", ++ [META_ARGV_PID] = "COREDUMP_PID=", ++ [META_ARGV_UID] = "COREDUMP_UID=", ++ [META_ARGV_GID] = "COREDUMP_GID=", ++ [META_ARGV_SIGNAL] = "COREDUMP_SIGNAL=", ++ [META_ARGV_TIMESTAMP] = "COREDUMP_TIMESTAMP=", ++ [META_ARGV_RLIMIT] = "COREDUMP_RLIMIT=", ++ [META_ARGV_HOSTNAME] = "COREDUMP_HOSTNAME=", ++ [META_COMM] = "COREDUMP_COMM=", ++ [META_EXE] = "COREDUMP_EXE=", ++ [META_UNIT] = "COREDUMP_UNIT=", + }; + + typedef struct Context { +@@ -137,9 +137,9 @@ typedef enum CoredumpStorage { + } CoredumpStorage; + + static const char* const coredump_storage_table[_COREDUMP_STORAGE_MAX] = { +- [COREDUMP_STORAGE_NONE] = "none", ++ [COREDUMP_STORAGE_NONE] = "none", + [COREDUMP_STORAGE_EXTERNAL] = "external", +- [COREDUMP_STORAGE_JOURNAL] = "journal", ++ [COREDUMP_STORAGE_JOURNAL] = "journal", + }; + + DEFINE_PRIVATE_STRING_TABLE_LOOKUP(coredump_storage, CoredumpStorage); +@@ -155,13 +155,13 @@ static uint64_t arg_max_use = UINT64_MAX; + + static int parse_config(void) { + static const ConfigTableItem items[] = { +- { "Coredump", "Storage", config_parse_coredump_storage, 0, &arg_storage }, +- { "Coredump", "Compress", config_parse_bool, 0, &arg_compress }, +- { "Coredump", "ProcessSizeMax", config_parse_iec_uint64, 0, &arg_process_size_max }, +- { "Coredump", "ExternalSizeMax", config_parse_iec_uint64_infinity, 0, &arg_external_size_max }, +- { "Coredump", "JournalSizeMax", config_parse_iec_size, 0, &arg_journal_size_max }, +- { "Coredump", "KeepFree", config_parse_iec_uint64, 0, &arg_keep_free }, +- { "Coredump", "MaxUse", config_parse_iec_uint64, 0, &arg_max_use }, ++ { "Coredump", "Storage", config_parse_coredump_storage, 0, &arg_storage }, ++ { "Coredump", "Compress", config_parse_bool, 0, &arg_compress }, ++ { "Coredump", "ProcessSizeMax", config_parse_iec_uint64, 0, &arg_process_size_max }, ++ { "Coredump", "ExternalSizeMax", config_parse_iec_uint64_infinity, 0, &arg_external_size_max }, ++ { "Coredump", "JournalSizeMax", config_parse_iec_size, 0, &arg_journal_size_max }, ++ { "Coredump", "KeepFree", config_parse_iec_uint64, 0, &arg_keep_free }, ++ { "Coredump", "MaxUse", config_parse_iec_uint64, 0, &arg_max_use }, + {} + }; + +@@ -207,15 +207,15 @@ static int fix_acl(int fd, uid_t uid) { + static int fix_xattr(int fd, const Context *context) { + + static const char * const xattrs[_META_MAX] = { +- [META_ARGV_PID] = "user.coredump.pid", +- [META_ARGV_UID] = "user.coredump.uid", +- [META_ARGV_GID] = "user.coredump.gid", +- [META_ARGV_SIGNAL] = "user.coredump.signal", +- [META_ARGV_TIMESTAMP] = "user.coredump.timestamp", +- [META_ARGV_RLIMIT] = "user.coredump.rlimit", +- [META_ARGV_HOSTNAME] = "user.coredump.hostname", +- [META_COMM] = "user.coredump.comm", +- [META_EXE] = "user.coredump.exe", ++ [META_ARGV_PID] = "user.coredump.pid", ++ [META_ARGV_UID] = "user.coredump.uid", ++ [META_ARGV_GID] = "user.coredump.gid", ++ [META_ARGV_SIGNAL] = "user.coredump.signal", ++ [META_ARGV_TIMESTAMP] = "user.coredump.timestamp", ++ [META_ARGV_RLIMIT] = "user.coredump.rlimit", ++ [META_ARGV_HOSTNAME] = "user.coredump.hostname", ++ [META_COMM] = "user.coredump.comm", ++ [META_EXE] = "user.coredump.exe", + }; + + int r = 0; diff --git a/SOURCES/0354-basic-add-STRERROR-wrapper-for-strerror_r.patch b/SOURCES/0354-basic-add-STRERROR-wrapper-for-strerror_r.patch new file mode 100644 index 0000000..fb351b7 --- /dev/null +++ b/SOURCES/0354-basic-add-STRERROR-wrapper-for-strerror_r.patch @@ -0,0 +1,99 @@ +From f42e15fdfba61fe6dee0bfb0a6a7f44fd9ca9dd3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 7 Oct 2022 12:28:31 +0200 +Subject: [PATCH] basic: add STRERROR() wrapper for strerror_r() + +(cherry picked from commit 2c5d05b3cd986568105d67891e4010b868dea24f) + +Related: #2155516 +--- + src/basic/errno-util.h | 10 +++++++++ + src/test/meson.build | 2 ++ + src/test/test-errno-util.c | 44 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 56 insertions(+) + create mode 100644 src/test/test-errno-util.c + +diff --git a/src/basic/errno-util.h b/src/basic/errno-util.h +index 09abf0b751..a2d9876c15 100644 +--- a/src/basic/errno-util.h ++++ b/src/basic/errno-util.h +@@ -6,6 +6,16 @@ + + #include "macro.h" + ++/* strerror(3) says that glibc uses a maximum length of 1024 bytes. */ ++#define ERRNO_BUF_LEN 1024 ++ ++/* Note: the lifetime of the compound literal is the immediately surrounding block, ++ * see C11 §6.5.2.5, and ++ * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks ++ * ++ * Note that we use the GNU variant of strerror_r() here. */ ++#define STRERROR(errnum) strerror_r(abs(errnum), (char[ERRNO_BUF_LEN]){}, ERRNO_BUF_LEN) ++ + static inline void _reset_errno_(int *saved_errno) { + if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */ + return; +diff --git a/src/test/meson.build b/src/test/meson.build +index 14b7939b1f..032800dd85 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -580,6 +580,8 @@ tests += [ + [files('test-errno-list.c') + + generated_gperf_headers], + ++ [files('test-errno-util.c')], ++ + [files('test-ip-protocol-list.c') + + shared_generated_gperf_headers], + +diff --git a/src/test/test-errno-util.c b/src/test/test-errno-util.c +new file mode 100644 +index 0000000000..284f451002 +--- /dev/null ++++ b/src/test/test-errno-util.c +@@ -0,0 +1,44 @@ ++/* SPDX-License-Identifier: LGPL-2.1-or-later */ ++ ++#include "errno-util.h" ++#include "stdio-util.h" ++#include "string-util.h" ++#include "tests.h" ++ ++TEST(strerror_not_threadsafe) { ++ /* Just check that strerror really is not thread-safe. */ ++ log_info("strerror(%d) → %s", 200, strerror(200)); ++ log_info("strerror(%d) → %s", 201, strerror(201)); ++ log_info("strerror(%d) → %s", INT_MAX, strerror(INT_MAX)); ++ ++ log_info("strerror(%d), strerror(%d) → %p, %p", 200, 201, strerror(200), strerror(201)); ++ ++ /* This call is not allowed, because the first returned string becomes invalid when ++ * we call strerror the second time: ++ * ++ * log_info("strerror(%d), strerror(%d) → %s, %s", 200, 201, strerror(200), strerror(201)); ++ */ ++} ++ ++TEST(STRERROR) { ++ /* Just check that STRERROR really is thread-safe. */ ++ log_info("STRERROR(%d) → %s", 200, STRERROR(200)); ++ log_info("STRERROR(%d) → %s", 201, STRERROR(201)); ++ log_info("STRERROR(%d), STRERROR(%d) → %s, %s", 200, 201, STRERROR(200), STRERROR(201)); ++ ++ const char *a = STRERROR(200), *b = STRERROR(201); ++ assert_se(strstr(a, "200")); ++ assert_se(strstr(b, "201")); ++ ++ /* Check with negative values */ ++ assert_se(streq(a, STRERROR(-200))); ++ assert_se(streq(b, STRERROR(-201))); ++ ++ const char *c = STRERROR(INT_MAX); ++ char buf[DECIMAL_STR_MAX(int)]; ++ xsprintf(buf, "%d", INT_MAX); /* INT_MAX is hexadecimal, use printf to convert to decimal */ ++ log_info("STRERROR(%d) → %s", INT_MAX, c); ++ assert_se(strstr(c, buf)); ++} ++ ++DEFINE_TEST_MAIN(LOG_INFO); diff --git a/SOURCES/0355-coredump-do-not-allow-user-to-access-coredumps-with-.patch b/SOURCES/0355-coredump-do-not-allow-user-to-access-coredumps-with-.patch new file mode 100644 index 0000000..8732578 --- /dev/null +++ b/SOURCES/0355-coredump-do-not-allow-user-to-access-coredumps-with-.patch @@ -0,0 +1,384 @@ +From d133e7f71d4530a25971eb99cd1a108f3ede72b9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 28 Nov 2022 12:12:55 +0100 +Subject: [PATCH] coredump: do not allow user to access coredumps with changed + uid/gid/capabilities + +When the user starts a program which elevates its permissions via setuid, +setgid, or capabilities set on the file, it may access additional information +which would then be visible in the coredump. We shouldn't make the the coredump +visible to the user in such cases. + +Reported-by: Matthias Gerstner + +This reads the /proc//auxv file and attaches it to the process metadata as +PROC_AUXV. Before the coredump is submitted, it is parsed and if either +at_secure was set (which the kernel will do for processes that are setuid, +setgid, or setcap), or if the effective uid/gid don't match uid/gid, the file +is not made accessible to the user. If we can't access this data, we assume the +file should not be made accessible either. In principle we could also access +the auxv data from a note in the core file, but that is much more complex and +it seems better to use the stand-alone file that is provided by the kernel. + +Attaching auxv is both convient for this patch (because this way it's passed +between the stages along with other fields), but I think it makes sense to save +it in general. + +We use the information early in the core file to figure out if the program was +32-bit or 64-bit and its endianness. This way we don't need heuristics to guess +whether the format of the auxv structure. This test might reject some cases on +fringe architecutes. But the impact would be limited: we just won't grant the +user permissions to view the coredump file. If people report that we're missing +some cases, we can always enhance this to support more architectures. + +I tested auxv parsing on amd64, 32-bit program on amd64, arm64, arm32, and +ppc64el, but not the whole coredump handling. + +(cherry picked from commit 3e4d0f6cf99f8677edd6a237382a65bfe758de03) + +Resolves: #2155516 +--- + src/basic/io-util.h | 9 ++ + src/coredump/coredump.c | 197 +++++++++++++++++++++++++++++++++++++--- + 2 files changed, 193 insertions(+), 13 deletions(-) + +diff --git a/src/basic/io-util.h b/src/basic/io-util.h +index 39728e06bc..3afb134266 100644 +--- a/src/basic/io-util.h ++++ b/src/basic/io-util.h +@@ -91,7 +91,16 @@ struct iovec_wrapper *iovw_new(void); + struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw); + struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw); + void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors); ++ + int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len); ++static inline int iovw_consume(struct iovec_wrapper *iovw, void *data, size_t len) { ++ /* Move data into iovw or free on error */ ++ int r = iovw_put(iovw, data, len); ++ if (r < 0) ++ free(data); ++ return r; ++} ++ + int iovw_put_string_field(struct iovec_wrapper *iovw, const char *field, const char *value); + int iovw_put_string_field_free(struct iovec_wrapper *iovw, const char *field, char *value); + void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new); +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 5f315b9a79..48911522f2 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -105,6 +106,7 @@ enum { + + META_EXE = _META_MANDATORY_MAX, + META_UNIT, ++ META_PROC_AUXV, + _META_MAX + }; + +@@ -119,10 +121,12 @@ static const char * const meta_field_names[_META_MAX] = { + [META_COMM] = "COREDUMP_COMM=", + [META_EXE] = "COREDUMP_EXE=", + [META_UNIT] = "COREDUMP_UNIT=", ++ [META_PROC_AUXV] = "COREDUMP_PROC_AUXV=", + }; + + typedef struct Context { + const char *meta[_META_MAX]; ++ size_t meta_size[_META_MAX]; + pid_t pid; + bool is_pid1; + bool is_journald; +@@ -184,13 +188,16 @@ static uint64_t storage_size_max(void) { + return 0; + } + +-static int fix_acl(int fd, uid_t uid) { ++static int fix_acl(int fd, uid_t uid, bool allow_user) { ++ assert(fd >= 0); ++ assert(uid_is_valid(uid)); + + #if HAVE_ACL + int r; + +- assert(fd >= 0); +- assert(uid_is_valid(uid)); ++ /* We don't allow users to read coredumps if the uid or capabilities were changed. */ ++ if (!allow_user) ++ return 0; + + if (uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY) + return 0; +@@ -250,7 +257,8 @@ static int fix_permissions( + const char *filename, + const char *target, + const Context *context, +- uid_t uid) { ++ uid_t uid, ++ bool allow_user) { + + int r; + +@@ -260,7 +268,7 @@ static int fix_permissions( + + /* Ignore errors on these */ + (void) fchmod(fd, 0640); +- (void) fix_acl(fd, uid); ++ (void) fix_acl(fd, uid, allow_user); + (void) fix_xattr(fd, context); + + r = fsync_full(fd); +@@ -330,6 +338,154 @@ static int make_filename(const Context *context, char **ret) { + return 0; + } + ++static int parse_auxv64( ++ const uint64_t *auxv, ++ size_t size_bytes, ++ int *at_secure, ++ uid_t *uid, ++ uid_t *euid, ++ gid_t *gid, ++ gid_t *egid) { ++ ++ assert(auxv || size_bytes == 0); ++ ++ if (size_bytes % (2 * sizeof(uint64_t)) != 0) ++ return log_warning_errno(SYNTHETIC_ERRNO(EIO), "Incomplete auxv structure (%zu bytes).", size_bytes); ++ ++ size_t words = size_bytes / sizeof(uint64_t); ++ ++ /* Note that we set output variables even on error. */ ++ ++ for (size_t i = 0; i + 1 < words; i += 2) ++ switch (auxv[i]) { ++ case AT_SECURE: ++ *at_secure = auxv[i + 1] != 0; ++ break; ++ case AT_UID: ++ *uid = auxv[i + 1]; ++ break; ++ case AT_EUID: ++ *euid = auxv[i + 1]; ++ break; ++ case AT_GID: ++ *gid = auxv[i + 1]; ++ break; ++ case AT_EGID: ++ *egid = auxv[i + 1]; ++ break; ++ case AT_NULL: ++ if (auxv[i + 1] != 0) ++ goto error; ++ return 0; ++ } ++ error: ++ return log_warning_errno(SYNTHETIC_ERRNO(ENODATA), ++ "AT_NULL terminator not found, cannot parse auxv structure."); ++} ++ ++static int parse_auxv32( ++ const uint32_t *auxv, ++ size_t size_bytes, ++ int *at_secure, ++ uid_t *uid, ++ uid_t *euid, ++ gid_t *gid, ++ gid_t *egid) { ++ ++ assert(auxv || size_bytes == 0); ++ ++ size_t words = size_bytes / sizeof(uint32_t); ++ ++ if (size_bytes % (2 * sizeof(uint32_t)) != 0) ++ return log_warning_errno(SYNTHETIC_ERRNO(EIO), "Incomplete auxv structure (%zu bytes).", size_bytes); ++ ++ /* Note that we set output variables even on error. */ ++ ++ for (size_t i = 0; i + 1 < words; i += 2) ++ switch (auxv[i]) { ++ case AT_SECURE: ++ *at_secure = auxv[i + 1] != 0; ++ break; ++ case AT_UID: ++ *uid = auxv[i + 1]; ++ break; ++ case AT_EUID: ++ *euid = auxv[i + 1]; ++ break; ++ case AT_GID: ++ *gid = auxv[i + 1]; ++ break; ++ case AT_EGID: ++ *egid = auxv[i + 1]; ++ break; ++ case AT_NULL: ++ if (auxv[i + 1] != 0) ++ goto error; ++ return 0; ++ } ++ error: ++ return log_warning_errno(SYNTHETIC_ERRNO(ENODATA), ++ "AT_NULL terminator not found, cannot parse auxv structure."); ++} ++ ++static int grant_user_access(int core_fd, const Context *context) { ++ int at_secure = -1; ++ uid_t uid = UID_INVALID, euid = UID_INVALID; ++ uid_t gid = GID_INVALID, egid = GID_INVALID; ++ int r; ++ ++ assert(core_fd >= 0); ++ assert(context); ++ ++ if (!context->meta[META_PROC_AUXV]) ++ return log_warning_errno(SYNTHETIC_ERRNO(ENODATA), "No auxv data, not adjusting permissions."); ++ ++ uint8_t elf[EI_NIDENT]; ++ errno = 0; ++ if (pread(core_fd, &elf, sizeof(elf), 0) != sizeof(elf)) ++ return log_warning_errno(errno > 0 ? -errno : -EIO, ++ "Failed to pread from coredump fd: %s", ++ errno > 0 ? STRERROR(errno) : "Unexpected EOF"); ++ ++ if (elf[EI_MAG0] != ELFMAG0 || ++ elf[EI_MAG1] != ELFMAG1 || ++ elf[EI_MAG2] != ELFMAG2 || ++ elf[EI_MAG3] != ELFMAG3 || ++ elf[EI_VERSION] != EV_CURRENT) ++ return log_info_errno(SYNTHETIC_ERRNO(EUCLEAN), ++ "Core file does not have ELF header, not adjusting permissions."); ++ if (!IN_SET(elf[EI_CLASS], ELFCLASS32, ELFCLASS64) || ++ !IN_SET(elf[EI_DATA], ELFDATA2LSB, ELFDATA2MSB)) ++ return log_info_errno(SYNTHETIC_ERRNO(EUCLEAN), ++ "Core file has strange ELF class, not adjusting permissions."); ++ ++ if ((elf[EI_DATA] == ELFDATA2LSB) != (__BYTE_ORDER == __LITTLE_ENDIAN)) ++ return log_info_errno(SYNTHETIC_ERRNO(EUCLEAN), ++ "Core file has non-native endianness, not adjusting permissions."); ++ ++ if (elf[EI_CLASS] == ELFCLASS64) ++ r = parse_auxv64((const uint64_t*) context->meta[META_PROC_AUXV], ++ context->meta_size[META_PROC_AUXV], ++ &at_secure, &uid, &euid, &gid, &egid); ++ else ++ r = parse_auxv32((const uint32_t*) context->meta[META_PROC_AUXV], ++ context->meta_size[META_PROC_AUXV], ++ &at_secure, &uid, &euid, &gid, &egid); ++ if (r < 0) ++ return r; ++ ++ /* We allow access if we got all the data and at_secure is not set and ++ * the uid/gid matches euid/egid. */ ++ bool ret = ++ at_secure == 0 && ++ uid != UID_INVALID && euid != UID_INVALID && uid == euid && ++ gid != GID_INVALID && egid != GID_INVALID && gid == egid; ++ log_debug("Will %s access (uid="UID_FMT " euid="UID_FMT " gid="GID_FMT " egid="GID_FMT " at_secure=%s)", ++ ret ? "permit" : "restrict", ++ uid, euid, gid, egid, yes_no(at_secure)); ++ return ret; ++} ++ + static int save_external_coredump( + const Context *context, + int input_fd, +@@ -452,6 +608,8 @@ static int save_external_coredump( + context->meta[META_ARGV_PID], context->meta[META_COMM]); + truncated = r == 1; + ++ bool allow_user = grant_user_access(fd, context) > 0; ++ + #if HAVE_COMPRESSION + if (arg_compress) { + _cleanup_(unlink_and_freep) char *tmp_compressed = NULL; +@@ -489,7 +647,7 @@ static int save_external_coredump( + uncompressed_size += partial_uncompressed_size; + } + +- r = fix_permissions(fd_compressed, tmp_compressed, fn_compressed, context, uid); ++ r = fix_permissions(fd_compressed, tmp_compressed, fn_compressed, context, uid, allow_user); + if (r < 0) + return r; + +@@ -516,7 +674,7 @@ static int save_external_coredump( + "SIZE_LIMIT=%zu", max_size, + "MESSAGE_ID=" SD_MESSAGE_TRUNCATED_CORE_STR); + +- r = fix_permissions(fd, tmp, fn, context, uid); ++ r = fix_permissions(fd, tmp, fn, context, uid, allow_user); + if (r < 0) + return log_error_errno(r, "Failed to fix permissions and finalize coredump %s into %s: %m", coredump_tmpfile_name(tmp), fn); + +@@ -764,7 +922,7 @@ static int change_uid_gid(const Context *context) { + } + + static int submit_coredump( +- Context *context, ++ const Context *context, + struct iovec_wrapper *iovw, + int input_fd) { + +@@ -925,16 +1083,15 @@ static int save_context(Context *context, const struct iovec_wrapper *iovw) { + struct iovec *iovec = iovw->iovec + n; + + for (size_t i = 0; i < ELEMENTSOF(meta_field_names); i++) { +- char *p; +- + /* Note that these strings are NUL terminated, because we made sure that a + * trailing NUL byte is in the buffer, though not included in the iov_len + * count (see process_socket() and gather_pid_metadata_*()) */ + assert(((char*) iovec->iov_base)[iovec->iov_len] == 0); + +- p = startswith(iovec->iov_base, meta_field_names[i]); ++ const char *p = startswith(iovec->iov_base, meta_field_names[i]); + if (p) { + context->meta[i] = p; ++ context->meta_size[i] = iovec->iov_len - strlen(meta_field_names[i]); + count++; + break; + } +@@ -1176,6 +1333,7 @@ static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) { + uid_t owner_uid; + pid_t pid; + char *t; ++ size_t size; + const char *p; + int r; + +@@ -1240,13 +1398,26 @@ static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) { + (void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_LIMITS=", t); + + p = procfs_file_alloca(pid, "cgroup"); +- if (read_full_virtual_file(p, &t, NULL) >=0) ++ if (read_full_virtual_file(p, &t, NULL) >= 0) + (void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_CGROUP=", t); + + p = procfs_file_alloca(pid, "mountinfo"); +- if (read_full_virtual_file(p, &t, NULL) >=0) ++ if (read_full_virtual_file(p, &t, NULL) >= 0) + (void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_MOUNTINFO=", t); + ++ /* We attach /proc/auxv here. ELF coredumps also contain a note for this (NT_AUXV), see elf(5). */ ++ p = procfs_file_alloca(pid, "auxv"); ++ if (read_full_virtual_file(p, &t, &size) >= 0) { ++ char *buf = malloc(strlen("COREDUMP_PROC_AUXV=") + size + 1); ++ if (buf) { ++ /* Add a dummy terminator to make save_context() happy. */ ++ *((uint8_t*) mempcpy(stpcpy(buf, "COREDUMP_PROC_AUXV="), t, size)) = '\0'; ++ (void) iovw_consume(iovw, buf, size + strlen("COREDUMP_PROC_AUXV=")); ++ } ++ ++ free(t); ++ } ++ + if (get_process_cwd(pid, &t) >= 0) + (void) iovw_put_string_field_free(iovw, "COREDUMP_CWD=", t); + diff --git a/SOURCES/0356-Packit-build-SRPMs-in-Copr.patch b/SOURCES/0356-Packit-build-SRPMs-in-Copr.patch new file mode 100644 index 0000000..3cd833c --- /dev/null +++ b/SOURCES/0356-Packit-build-SRPMs-in-Copr.patch @@ -0,0 +1,27 @@ +From 43ca4cb2cb81e4107710e8a8c48df31d022a1136 Mon Sep 17 00:00:00 2001 +From: Laura Barcziova +Date: Wed, 9 Mar 2022 07:50:29 +0100 +Subject: [PATCH] Packit: build SRPMs in Copr + +Add srpm_build_deps key to the Packit config to specify needed dependencies for SRPM build +and indicate to build SRPM in Copr. + +(cherry picked from commit d15e1a29e3aab04ee79d5e3ec8e1e65fca78e165) + +Related: #2155516 +--- + .packit.yml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.packit.yml b/.packit.yml +index ce8782aae2..e1cbea3b3a 100644 +--- a/.packit.yml ++++ b/.packit.yml +@@ -13,6 +13,7 @@ downstream_package_name: systemd + # `git describe` returns in systemd's case 'v245-xxx' which breaks RPM version + # detection (that expects 245-xxxx'). Let's tweak the version string accordingly + upstream_tag_template: "v{version}" ++srpm_build_deps: [] + + actions: + post-upstream-clone: diff --git a/SOURCES/0357-test-support-non-summer-time.patch b/SOURCES/0357-test-support-non-summer-time.patch new file mode 100644 index 0000000..9c98742 --- /dev/null +++ b/SOURCES/0357-test-support-non-summer-time.patch @@ -0,0 +1,27 @@ +From 1e034561de36b0eda6356b15b5433bf8571d4067 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 30 Oct 2022 11:59:10 +0900 +Subject: [PATCH] test: support non-summer time + +Follow-up for 759ed0a2533da8840dea315d07f92e6bb0272cdd. + +(cherry picked from commit 59ab79a73d030a49bfdffd85897b6b30a2b132c5) + +Related: #2155516 +--- + test/units/testsuite-45.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/units/testsuite-45.sh b/test/units/testsuite-45.sh +index 75e07bc09a..38017a43ea 100755 +--- a/test/units/testsuite-45.sh ++++ b/test/units/testsuite-45.sh +@@ -39,7 +39,7 @@ test_timezone() { + if [[ -f /etc/timezone ]]; then + assert_eq "$(cat /etc/timezone)" "Europe/Kiev" + fi +- assert_in "Time zone: Europe/Kiev \(EEST, \+0[0-9]00\)" "$(timedatectl)" ++ assert_in "Time zone: Europe/Kiev \(EES*T, \+0[0-9]00\)" "$(timedatectl)" + + if [[ -n "$ORIG_TZ" ]]; then + echo 'reset timezone to original' diff --git a/SOURCES/0358-test-bump-the-base-VM-memory-to-768M.patch b/SOURCES/0358-test-bump-the-base-VM-memory-to-768M.patch new file mode 100644 index 0000000..91ee41d --- /dev/null +++ b/SOURCES/0358-test-bump-the-base-VM-memory-to-768M.patch @@ -0,0 +1,42 @@ +From c518597dddb9b8a0b8d895b28ebb4792c8a32c6e Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 25 Aug 2022 14:52:30 +0200 +Subject: [PATCH] test: bump the base VM memory to 768M + +as with 512M some tests occasionally trip off OOM-killer (e.g. +TEST-64 + multipath). + +(cherry picked from commit 6a9c4977683a30fcd36baf64e35255e9846028c6) + +Related: #2155516 +--- + test/TEST-36-NUMAPOLICY/test.sh | 2 +- + test/test-functions | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/test/TEST-36-NUMAPOLICY/test.sh b/test/TEST-36-NUMAPOLICY/test.sh +index 7909b1dce3..a0bfd4079a 100755 +--- a/test/TEST-36-NUMAPOLICY/test.sh ++++ b/test/TEST-36-NUMAPOLICY/test.sh +@@ -9,7 +9,7 @@ TEST_NO_NSPAWN=1 + . "${TEST_BASE_DIR:?}/test-functions" + + if qemu_min_version "5.2.0"; then +- QEMU_OPTIONS="-object memory-backend-ram,id=mem0,size=${QEMU_MEM:-512M} -numa node,memdev=mem0,nodeid=0" ++ QEMU_OPTIONS="-object memory-backend-ram,id=mem0,size=${QEMU_MEM:-768M} -numa node,memdev=mem0,nodeid=0" + else + QEMU_OPTIONS="-numa node,nodeid=0" + fi +diff --git a/test/test-functions b/test/test-functions +index 8ea2f97b71..f9a80884e8 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -450,7 +450,7 @@ run_qemu() { + qemu_options+=( + -smp "$QEMU_SMP" + -net none +- -m "${QEMU_MEM:-512M}" ++ -m "${QEMU_MEM:-768M}" + -nographic + -kernel "$KERNEL_BIN" + -drive "format=raw,cache=unsafe,file=$image" diff --git a/SOURCES/0359-test-don-t-overwrite-existing-QEMU_OPTIONS.patch b/SOURCES/0359-test-don-t-overwrite-existing-QEMU_OPTIONS.patch new file mode 100644 index 0000000..6a29b5f --- /dev/null +++ b/SOURCES/0359-test-don-t-overwrite-existing-QEMU_OPTIONS.patch @@ -0,0 +1,42 @@ +From 58b82abb17fd5c40b5c990a36c43ad558ef3cae1 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 20 Sep 2022 19:12:18 +0200 +Subject: [PATCH] test: don't overwrite existing $QEMU_OPTIONS + +(cherry picked from commit 761b1d83145a6f9f41ad9aafcb5f28d452582864) + +Related: #2155516 +--- + test/TEST-36-NUMAPOLICY/test.sh | 4 ++-- + test/TEST-53-ISSUE-16347/test.sh | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/test/TEST-36-NUMAPOLICY/test.sh b/test/TEST-36-NUMAPOLICY/test.sh +index a0bfd4079a..5c39b7c6d8 100755 +--- a/test/TEST-36-NUMAPOLICY/test.sh ++++ b/test/TEST-36-NUMAPOLICY/test.sh +@@ -9,9 +9,9 @@ TEST_NO_NSPAWN=1 + . "${TEST_BASE_DIR:?}/test-functions" + + if qemu_min_version "5.2.0"; then +- QEMU_OPTIONS="-object memory-backend-ram,id=mem0,size=${QEMU_MEM:-768M} -numa node,memdev=mem0,nodeid=0" ++ QEMU_OPTIONS+=" -object memory-backend-ram,id=mem0,size=${QEMU_MEM:-768M} -numa node,memdev=mem0,nodeid=0" + else +- QEMU_OPTIONS="-numa node,nodeid=0" ++ QEMU_OPTIONS+=" -numa node,nodeid=0" + fi + + do_test "$@" +diff --git a/test/TEST-53-ISSUE-16347/test.sh b/test/TEST-53-ISSUE-16347/test.sh +index 7f44c66bff..6d4821d2c1 100755 +--- a/test/TEST-53-ISSUE-16347/test.sh ++++ b/test/TEST-53-ISSUE-16347/test.sh +@@ -5,7 +5,7 @@ set -e + TEST_DESCRIPTION="test timer units when initial clock is ahead" + TEST_NO_NSPAWN=1 + +-QEMU_OPTIONS="-rtc base=$(date -u +%Y-%m-%dT%H:%M:%S -d '+3 days')" ++QEMU_OPTIONS+=" -rtc base=$(date -u +%Y-%m-%dT%H:%M:%S -d '+3 days')" + + # shellcheck source=test/test-functions + . "${TEST_BASE_DIR:?}/test-functions" diff --git a/SOURCES/0360-shared-json-allow-json_variant_dump-to-return-an-err.patch b/SOURCES/0360-shared-json-allow-json_variant_dump-to-return-an-err.patch new file mode 100644 index 0000000..0028708 --- /dev/null +++ b/SOURCES/0360-shared-json-allow-json_variant_dump-to-return-an-err.patch @@ -0,0 +1,52 @@ +From 022cb8bb2028571b9119fd4ae95c87c96f816d6c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 18 Oct 2022 18:09:06 +0200 +Subject: [PATCH] shared/json: allow json_variant_dump() to return an error + +(cherry picked from commit 7922ead507e0d83e4ec72a8cbd2b67194766e58c) + +Related: #2149074 +--- + src/shared/json.c | 7 ++++--- + src/shared/json.h | 2 +- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/shared/json.c b/src/shared/json.c +index bcc109abc2..f91738227b 100644 +--- a/src/shared/json.c ++++ b/src/shared/json.c +@@ -1768,9 +1768,9 @@ int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) { + return (int) sz - 1; + } + +-void json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix) { ++int json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix) { + if (!v) +- return; ++ return 0; + + if (!f) + f = stdout; +@@ -1796,7 +1796,8 @@ void json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const cha + fputc('\n', f); /* In case of SSE add a second newline */ + + if (flags & JSON_FORMAT_FLUSH) +- fflush(f); ++ return fflush_and_check(f); ++ return 0; + } + + int json_variant_filter(JsonVariant **v, char **to_remove) { +diff --git a/src/shared/json.h b/src/shared/json.h +index dd73c1e497..e4bfeae8f5 100644 +--- a/src/shared/json.h ++++ b/src/shared/json.h +@@ -195,7 +195,7 @@ typedef enum JsonFormatFlags { + } JsonFormatFlags; + + int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret); +-void json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix); ++int json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix); + + int json_variant_filter(JsonVariant **v, char **to_remove); + diff --git a/SOURCES/0361-shared-json-use-different-return-code-for-empty-inpu.patch b/SOURCES/0361-shared-json-use-different-return-code-for-empty-inpu.patch new file mode 100644 index 0000000..12859fd --- /dev/null +++ b/SOURCES/0361-shared-json-use-different-return-code-for-empty-inpu.patch @@ -0,0 +1,89 @@ +From ffed186cce8e5a20187f6f652be94e3135b74eed Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 19 Oct 2022 08:41:13 +0200 +Subject: [PATCH] shared/json: use different return code for empty input + +It is useful to distinguish if json_parse_file() got no input or invalid input. +Use different return codes for the two cases. + +(cherry picked from commit 87a16eb8b54002a49f12944fc09ce45d0cbadf45) + +Related: #2149074 +--- + src/shared/elf-util.c | 2 +- + src/shared/json.c | 6 ++++-- + src/test/test-json.c | 18 ++++++++++++++++++ + 3 files changed, 23 insertions(+), 3 deletions(-) + +diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c +index 6d9fcfbbf2..392ed9f31b 100644 +--- a/src/shared/elf-util.c ++++ b/src/shared/elf-util.c +@@ -800,7 +800,7 @@ int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, cha + return -errno; + + r = json_parse_file(json_in, NULL, 0, &package_metadata, NULL, NULL); +- if (r < 0 && r != -EINVAL) /* EINVAL: json was empty, so we got nothing, but that's ok */ ++ if (r < 0 && r != -ENODATA) /* ENODATA: json was empty, so we got nothing, but that's ok */ + return r; + } + +diff --git a/src/shared/json.c b/src/shared/json.c +index f91738227b..70e46fabb1 100644 +--- a/src/shared/json.c ++++ b/src/shared/json.c +@@ -3170,7 +3170,6 @@ int json_parse_continue(const char **p, JsonParseFlags flags, JsonVariant **ret, + int json_parse_file_at(FILE *f, int dir_fd, const char *path, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) { + _cleanup_(json_source_unrefp) JsonSource *source = NULL; + _cleanup_free_ char *text = NULL; +- const char *p; + int r; + + if (f) +@@ -3182,13 +3181,16 @@ int json_parse_file_at(FILE *f, int dir_fd, const char *path, JsonParseFlags fla + if (r < 0) + return r; + ++ if (isempty(text)) ++ return -ENODATA; ++ + if (path) { + source = json_source_new(path); + if (!source) + return -ENOMEM; + } + +- p = text; ++ const char *p = text; + return json_parse_internal(&p, source, flags, ret, ret_line, ret_column, false); + } + +diff --git a/src/test/test-json.c b/src/test/test-json.c +index b385edc269..2256492fb2 100644 +--- a/src/test/test-json.c ++++ b/src/test/test-json.c +@@ -346,6 +346,24 @@ TEST(build) { + assert_se(json_variant_equal(a, b)); + } + ++TEST(json_parse_file_empty) { ++ _cleanup_fclose_ FILE *f = NULL; ++ _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; ++ ++ assert_se(fopen_unlocked("/dev/null", "re", &f) >= 0); ++ assert_se(json_parse_file(f, "waldo", 0, &v, NULL, NULL) == -ENODATA); ++ assert_se(v == NULL); ++} ++ ++TEST(json_parse_file_invalid) { ++ _cleanup_fclose_ FILE *f = NULL; ++ _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; ++ ++ assert_se(f = fmemopen_unlocked((void*) "kookoo", 6, "r")); ++ assert_se(json_parse_file(f, "waldo", 0, &v, NULL, NULL) == -EINVAL); ++ assert_se(v == NULL); ++} ++ + TEST(source) { + static const char data[] = + "\n" diff --git a/SOURCES/0362-coredump-avoid-deadlock-when-passing-processed-backt.patch b/SOURCES/0362-coredump-avoid-deadlock-when-passing-processed-backt.patch new file mode 100644 index 0000000..589ddb9 --- /dev/null +++ b/SOURCES/0362-coredump-avoid-deadlock-when-passing-processed-backt.patch @@ -0,0 +1,121 @@ +From 35a233228ff0105892b3edc86a0cdda06282a9ac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 18 Oct 2022 18:23:53 +0200 +Subject: [PATCH] coredump: avoid deadlock when passing processed backtrace + data + +We would deadlock when passing the data back from the forked-off process that +was doing backtrace generation back to the coredump parent. This is because we +fork the child and wait for it to exit. The child tries to write too much data +to the output pipe, and and after the first 64k blocks on the parent because +the pipe is full. The bug surfaced in Fedora because of a combination of four +factors: +- 87707784c70dc9894ec613df0a6e75e732a362a3 was backported to v251.5, which + allowed coredump processing to be successful. +- 1a0281a3ebf4f8c16d40aa9e63103f16cd23bb2a was NOT backported, so the output + was very verbose. +- Fedora has the ELF package metadata available, so a lot of output can be + generated. Most other distros just don't have the information. +- gnome-calendar crashes and has a bazillion modules and 69596 bytes of output + are generated for it. + +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=2135778. + +The code is changed to try to write data opportunistically. If we get partial +information, that is still logged. In is generally better to log partial +backtrace information than nothing at all. + +(cherry picked from commit 076b807be472630692c5348c60d0c2b7b28ad437) + +Resolves: #2149074 +--- + src/shared/elf-util.c | 37 +++++++++++++++++++++++++++++++------ + 1 file changed, 31 insertions(+), 6 deletions(-) + +diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c +index 392ed9f31b..644fbae9ce 100644 +--- a/src/shared/elf-util.c ++++ b/src/shared/elf-util.c +@@ -30,6 +30,9 @@ + #define THREADS_MAX 64 + #define ELF_PACKAGE_METADATA_ID 0xcafe1a7e + ++/* The amount of data we're willing to write to each of the output pipes. */ ++#define COREDUMP_PIPE_MAX (1024*1024U) ++ + static void *dw_dl = NULL; + static void *elf_dl = NULL; + +@@ -700,13 +703,13 @@ int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, cha + return r; + + if (ret) { +- r = RET_NERRNO(pipe2(return_pipe, O_CLOEXEC)); ++ r = RET_NERRNO(pipe2(return_pipe, O_CLOEXEC|O_NONBLOCK)); + if (r < 0) + return r; + } + + if (ret_package_metadata) { +- r = RET_NERRNO(pipe2(json_pipe, O_CLOEXEC)); ++ r = RET_NERRNO(pipe2(json_pipe, O_CLOEXEC|O_NONBLOCK)); + if (r < 0) + return r; + } +@@ -750,8 +753,24 @@ int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, cha + goto child_fail; + + if (buf) { +- r = loop_write(return_pipe[1], buf, strlen(buf), false); +- if (r < 0) ++ size_t len = strlen(buf); ++ ++ if (len > COREDUMP_PIPE_MAX) { ++ /* This is iffy. A backtrace can be a few hundred kilobytes, but too much is ++ * too much. Let's log a warning and ignore the rest. */ ++ log_warning("Generated backtrace is %zu bytes (more than the limit of %u bytes), backtrace will be truncated.", ++ len, COREDUMP_PIPE_MAX); ++ len = COREDUMP_PIPE_MAX; ++ } ++ ++ /* Bump the space for the returned string. ++ * Failure is ignored, because partial output is still useful. */ ++ (void) fcntl(return_pipe[1], F_SETPIPE_SZ, len); ++ ++ r = loop_write(return_pipe[1], buf, len, false); ++ if (r == -EAGAIN) ++ log_warning("Write failed, backtrace will be truncated."); ++ else if (r < 0) + goto child_fail; + + return_pipe[1] = safe_close(return_pipe[1]); +@@ -760,13 +779,19 @@ int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, cha + if (package_metadata) { + _cleanup_fclose_ FILE *json_out = NULL; + ++ /* Bump the space for the returned string. We don't know how much space we'll need in ++ * advance, so we'll just try to write as much as possible and maybe fail later. */ ++ (void) fcntl(json_pipe[1], F_SETPIPE_SZ, COREDUMP_PIPE_MAX); ++ + json_out = take_fdopen(&json_pipe[1], "w"); + if (!json_out) { + r = -errno; + goto child_fail; + } + +- json_variant_dump(package_metadata, JSON_FORMAT_FLUSH, json_out, NULL); ++ r = json_variant_dump(package_metadata, JSON_FORMAT_FLUSH, json_out, NULL); ++ if (r < 0) ++ log_warning_errno(r, "Failed to write JSON package metadata, ignoring: %m"); + } + + _exit(EXIT_SUCCESS); +@@ -801,7 +826,7 @@ int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, cha + + r = json_parse_file(json_in, NULL, 0, &package_metadata, NULL, NULL); + if (r < 0 && r != -ENODATA) /* ENODATA: json was empty, so we got nothing, but that's ok */ +- return r; ++ log_warning_errno(r, "Failed to read or parse json metadata, ignoring: %m"); + } + + if (ret) diff --git a/SOURCES/0363-test-disable-flaky-subtests-that-require-udevadm-wai.patch b/SOURCES/0363-test-disable-flaky-subtests-that-require-udevadm-wai.patch new file mode 100644 index 0000000..d87223e --- /dev/null +++ b/SOURCES/0363-test-disable-flaky-subtests-that-require-udevadm-wai.patch @@ -0,0 +1,34 @@ +From a71653b20b889a71c6643171603e65b0ca945ea4 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 30 Nov 2022 15:24:33 +0100 +Subject: [PATCH] test: disable flaky subtests that require udevadm wait/lock + +Certain TEST-64-UDEV-STORAGE tests require `udevadm wait` and `udevadm +lock` verbs to work reliably. Since we don't plan to backport the verbs +to RHEL 9.1 and older, let's skip the tests to make CIs a bit more +reliable when dealing with z-streams. + +Necessary only on RHEL 9.1 and 9.0. + +rhel-only +Related: #2149074 +--- + test/TEST-64-UDEV-STORAGE/test.sh | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/test/TEST-64-UDEV-STORAGE/test.sh b/test/TEST-64-UDEV-STORAGE/test.sh +index 2a5b5b2dd3..659b03e07b 100755 +--- a/test/TEST-64-UDEV-STORAGE/test.sh ++++ b/test/TEST-64-UDEV-STORAGE/test.sh +@@ -310,6 +310,11 @@ EOF + + # Test case for issue https://github.com/systemd/systemd/issues/19946 + testcase_simultaneous_events() { ++ if ! "$BUILD_DIR/udevadm" lock --version >/dev/null; then ++ echo "This test is flaky without udevadm wait/lock, skipping the test..." ++ return 77 ++ fi ++ + local qemu_opts=("-device virtio-scsi-pci,id=scsi") + local partdisk="${TESTDIR:?}/simultaneousevents.img" + diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index ba201c6..717927e 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -21,7 +21,7 @@ Name: systemd Url: https://www.freedesktop.org/wiki/Software/systemd Version: 250 -Release: 12%{?dist}.1 +Release: 12%{?dist}.3 # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -430,6 +430,17 @@ Patch0349: 0349-test-do-not-restart-getty-tty2-automatically.patch Patch0350: 0350-tests-add-test-for-StopIdleSessionSec-option.patch Patch0351: 0351-logind-schedule-idle-check-full-interval-from-now-if.patch Patch0352: 0352-time-util-fix-buffer-over-run.patch +Patch0353: 0353-coredump-adjust-whitespace.patch +Patch0354: 0354-basic-add-STRERROR-wrapper-for-strerror_r.patch +Patch0355: 0355-coredump-do-not-allow-user-to-access-coredumps-with-.patch +Patch0356: 0356-Packit-build-SRPMs-in-Copr.patch +Patch0357: 0357-test-support-non-summer-time.patch +Patch0358: 0358-test-bump-the-base-VM-memory-to-768M.patch +Patch0359: 0359-test-don-t-overwrite-existing-QEMU_OPTIONS.patch +Patch0360: 0360-shared-json-allow-json_variant_dump-to-return-an-err.patch +Patch0361: 0361-shared-json-use-different-return-code-for-empty-inpu.patch +Patch0362: 0362-coredump-avoid-deadlock-when-passing-processed-backt.patch +Patch0363: 0363-test-disable-flaky-subtests-that-require-udevadm-wai.patch # Downstream-only patches (9000–9999) @@ -1211,6 +1222,21 @@ getent passwd systemd-oom &>/dev/null || useradd -r -l -g systemd-oom -d / -s /s %files standalone-sysusers -f .file-list-standalone-sysusers %changelog +* Mon Feb 13 2023 systemd maintenance team - 250-12.3 +- shared/json: allow json_variant_dump() to return an error (#2149074) +- shared/json: use different return code for empty input (#2149074) +- coredump: avoid deadlock when passing processed backtrace data (#2149074) +- test: disable flaky subtests that require udevadm wait/lock (#2149074) + +* Mon Jan 16 2023 systemd maintenance team - 250-12.2 +- coredump: adjust whitespace (#2155516) +- basic: add STRERROR() wrapper for strerror_r() (#2155516) +- coredump: do not allow user to access coredumps with changed uid/gid/capabilities (#2155516) +- Packit: build SRPMs in Copr (#2155516) +- test: support non-summer time (#2155516) +- test: bump the base VM memory to 768M (#2155516) +- test: don't overwrite existing $QEMU_OPTIONS (#2155516) + * Mon Nov 07 2022 systemd maintenance team - 250-12.1 - time-util: fix buffer-over-run (#2139388)