diff --git a/1274-man-fix-a-missing-word.patch b/1274-man-fix-a-missing-word.patch new file mode 100644 index 0000000..1c9ec88 --- /dev/null +++ b/1274-man-fix-a-missing-word.patch @@ -0,0 +1,27 @@ +From 5844efbf70321f5dd902f987947786d1ab4409c6 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 8 Oct 2025 17:23:31 +0200 +Subject: [PATCH] man: fix a missing word + +Follow-up for 6d48c7cf736ced70c1c2fef1e1f03618911d04bc. + +(cherry picked from commit 67111e1bd918f9e1b4b542d1e0fe84f1d571876e) + +Resolves: RHEL-115182 +--- + man/systemd.resource-control.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml +index 2a0e40a17d..9431fb20a1 100644 +--- a/man/systemd.resource-control.xml ++++ b/man/systemd.resource-control.xml +@@ -365,7 +365,7 @@ + an absolute number of tasks or a percentage value that is taken relative to the configured maximum + number of tasks on the system. If assigned the special value infinity, no tasks + limit is applied. This controls the pids.max control group attribute. For +- details about this control group attribute, the ++ details about this control group attribute, see the + pids controller + . + diff --git a/1275-cryptsetup-Add-optional-support-for-linking-volume-k.patch b/1275-cryptsetup-Add-optional-support-for-linking-volume-k.patch new file mode 100644 index 0000000..2823ca1 --- /dev/null +++ b/1275-cryptsetup-Add-optional-support-for-linking-volume-k.patch @@ -0,0 +1,167 @@ +From 26d6ea70cfb9232dc9ab66ee0927fb546fe0418b Mon Sep 17 00:00:00 2001 +From: Ondrej Kozina +Date: Wed, 31 Jan 2024 13:11:21 +0100 +Subject: [PATCH] cryptsetup: Add optional support for linking volume key in + keyring. + +cryptsetup 2.7.0 adds feature to link effective volume key in custom +kernel keyring during device activation. It can be used later to pass +linked volume key to other services. + +For example: kdump enabled systems installed on LUKS2 device. +This feature allows it to store volume key linked in a kernel keyring +to the kdump reserved memory and reuse it to reactivate LUKS2 device +in case of kernel crash. + +(cherry picked from commit c5daf14c88ba44cefabe052de93a29d28b6b0175) + +Resolves: RHEL-97175 +--- + man/crypttab.xml | 21 ++++++++++++ + meson.build | 3 +- + src/cryptsetup/cryptsetup.c | 65 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 88 insertions(+), 1 deletion(-) + +diff --git a/man/crypttab.xml b/man/crypttab.xml +index 1dd9bb1bb6..bd49e025fa 100644 +--- a/man/crypttab.xml ++++ b/man/crypttab.xml +@@ -239,6 +239,27 @@ + + + ++ ++ ++ ++ Specifies the kernel keyring and key description ++ (see keyrings7) ++ where LUKS2 volume key gets linked during device activation. The kernel keyring ++ description and key description must be separated by ::. ++ ++ The kernel keyring part can be a string description or a predefined ++ kernel keyring prefixed with @ (e.g.: to use @s session or ++ @u user keyring directly). The type prefix text in the kernel keyring description ++ is not required. The specified kernel keyring must already exist at the time of device activation. ++ ++ The key part is a string description optionally prefixed by a %key_type:. ++ If no type is specified, the user type key is linked by default. See ++ keyctl1 ++ for more information on key descriptions (KEY IDENTIFIERS section). ++ ++ Note that the linked volume key is not cleaned up automatically when the device is detached. ++ ++ + + + +diff --git a/meson.build b/meson.build +index cbde702211..684324c6d7 100644 +--- a/meson.build ++++ b/meson.build +@@ -1316,7 +1316,8 @@ if want_libcryptsetup != 'false' and not skip_deps + + foreach ident : ['crypt_set_metadata_size', + 'crypt_activate_by_signed_key', +- 'crypt_token_max'] ++ 'crypt_token_max', ++ 'crypt_set_keyring_to_link'] + have_ident = have and cc.has_function( + ident, + prefix : '#include ', +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 3f2cab1e41..f9130e2568 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -101,6 +101,9 @@ static bool arg_headless = false; + static usec_t arg_token_timeout_usec = 30*USEC_PER_SEC; + static unsigned arg_tpm2_measure_pcr = UINT_MAX; /* This and the following field is about measuring the unlocked volume key to the local TPM */ + static char **arg_tpm2_measure_banks = NULL; ++static char *arg_link_keyring = NULL; ++static char *arg_link_key_type = NULL; ++static char *arg_link_key_description = NULL; + + STATIC_DESTRUCTOR_REGISTER(arg_cipher, freep); + STATIC_DESTRUCTOR_REGISTER(arg_hash, freep); +@@ -113,6 +116,9 @@ STATIC_DESTRUCTOR_REGISTER(arg_fido2_rp_id, freep); + STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep); + STATIC_DESTRUCTOR_REGISTER(arg_tpm2_signature, freep); + STATIC_DESTRUCTOR_REGISTER(arg_tpm2_measure_banks, strv_freep); ++STATIC_DESTRUCTOR_REGISTER(arg_link_keyring, freep); ++STATIC_DESTRUCTOR_REGISTER(arg_link_key_type, freep); ++STATIC_DESTRUCTOR_REGISTER(arg_link_key_description, freep); + + static const char* const passphrase_type_table[_PASSPHRASE_TYPE_MAX] = { + [PASSPHRASE_REGULAR] = "passphrase", +@@ -486,6 +492,56 @@ static int parse_one_option(const char *option) { + if (r < 0) + log_warning_errno(r, "Failed to parse %s, ignoring: %m", option); + ++ } else if ((val = startswith(option, "link-volume-key="))) { ++#ifdef HAVE_CRYPT_SET_KEYRING_TO_LINK ++ const char *sep, *c; ++ _cleanup_free_ char *keyring = NULL, *key_type = NULL, *key_description = NULL; ++ ++ /* Stick with cryptsetup --link-vk-to-keyring format ++ * ::%:, ++ * where % is optional and defaults to 'user'. ++ */ ++ if (!(sep = strstr(val, "::"))) ++ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse link-volume-key= option value: %m"); ++ ++ /* cryptsetup (cli) supports passed in various formats: ++ * - well-known keyrings prefixed with '@' (@u user, @s session, etc) ++ * - text descriptions prefixed with "%:" or "%keyring:". ++ * - text desription with no prefix. ++ * - numeric keyring id (ignored in current patch set). */ ++ if (*val == '@' || *val == '%') ++ keyring = strndup(val, sep - val); ++ else ++ /* add type prefix if missing (crypt_set_keyring_to_link() expects it) */ ++ keyring = strnappend("%:", val, sep - val); ++ if (!keyring) ++ return log_oom(); ++ ++ sep += 2; ++ ++ /* % is optional (and defaults to 'user') */ ++ if (*sep == '%') { ++ /* must be separated by colon */ ++ if (!(c = strchr(sep, ':'))) ++ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse link-volume-key= option value: %m"); ++ ++ key_type = strndup(sep + 1, c - sep - 1); ++ if (!key_type) ++ return log_oom(); ++ ++ sep = c + 1; ++ } ++ ++ key_description = strdup(sep); ++ if (!key_description) ++ return log_oom(); ++ ++ free_and_replace(arg_link_keyring, keyring); ++ free_and_replace(arg_link_key_type, key_type); ++ free_and_replace(arg_link_key_description, key_description); ++#else ++ log_error("Build lacks libcryptsetup support for linking volume keys in user specified kernel keyrings upon device activation, ignoring: %s", option); ++#endif + } else if (!streq(option, "x-initrd.attach")) + log_warning("Encountered unknown /etc/crypttab option '%s', ignoring.", option); + +@@ -2207,6 +2263,15 @@ static int run(int argc, char *argv[]) { + if (r < 0) + return log_error_errno(r, "Failed to load LUKS superblock on device %s: %m", crypt_get_device_name(cd)); + ++/* since cryptsetup 2.7.0 (Jan 2024) */ ++#if HAVE_CRYPT_SET_KEYRING_TO_LINK ++ if (arg_link_key_description) { ++ r = crypt_set_keyring_to_link(cd, arg_link_key_description, NULL, arg_link_key_type, arg_link_keyring); ++ if (r < 0) ++ log_warning_errno(r, "Failed to set keyring or key description to link volume key in, ignoring: %m"); ++ } ++#endif ++ + if (arg_header) { + r = crypt_set_data_device(cd, source); + if (r < 0) diff --git a/1276-cryptsetup-fix-typo.patch b/1276-cryptsetup-fix-typo.patch new file mode 100644 index 0000000..a01aff9 --- /dev/null +++ b/1276-cryptsetup-fix-typo.patch @@ -0,0 +1,27 @@ +From 44f65e9b9a0f67a69886d25367875e9707affc81 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 14 Feb 2024 04:01:36 +0900 +Subject: [PATCH] cryptsetup: fix typo + +Follow-up for c5daf14c88ba44cefabe052de93a29d28b6b0175. + +(cherry picked from commit a14d3b48f7647676a0c43bceaecd56d9a77e3de6) + +Resolves: RHEL-97175 +--- + src/cryptsetup/cryptsetup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index f9130e2568..1f672f19f1 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -507,7 +507,7 @@ static int parse_one_option(const char *option) { + /* cryptsetup (cli) supports passed in various formats: + * - well-known keyrings prefixed with '@' (@u user, @s session, etc) + * - text descriptions prefixed with "%:" or "%keyring:". +- * - text desription with no prefix. ++ * - text description with no prefix. + * - numeric keyring id (ignored in current patch set). */ + if (*val == '@' || *val == '%') + keyring = strndup(val, sep - val); diff --git a/1277-cryptsetup-HAVE_CRYPT_SET_KEYRING_TO_LINK-is-always-.patch b/1277-cryptsetup-HAVE_CRYPT_SET_KEYRING_TO_LINK-is-always-.patch new file mode 100644 index 0000000..d459827 --- /dev/null +++ b/1277-cryptsetup-HAVE_CRYPT_SET_KEYRING_TO_LINK-is-always-.patch @@ -0,0 +1,27 @@ +From be6acfdfd0ddd5625d68bdeb1fb5962d710557be Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 17 Aug 2025 21:05:24 +0900 +Subject: [PATCH] cryptsetup: HAVE_CRYPT_SET_KEYRING_TO_LINK is always defined + +Follow-up for c5daf14c88ba44cefabe052de93a29d28b6b0175 (v256). + +(cherry picked from commit fb4aabf4432d523b97376099ce4353b5c268ae82) + +Resolves: RHEL-97175 +--- + src/cryptsetup/cryptsetup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 1f672f19f1..4dc315e810 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -493,7 +493,7 @@ static int parse_one_option(const char *option) { + log_warning_errno(r, "Failed to parse %s, ignoring: %m", option); + + } else if ((val = startswith(option, "link-volume-key="))) { +-#ifdef HAVE_CRYPT_SET_KEYRING_TO_LINK ++#if HAVE_CRYPT_SET_KEYRING_TO_LINK + const char *sep, *c; + _cleanup_free_ char *keyring = NULL, *key_type = NULL, *key_description = NULL; + diff --git a/1278-coredump-make-check-that-all-argv-meta-data-fields-a.patch b/1278-coredump-make-check-that-all-argv-meta-data-fields-a.patch new file mode 100644 index 0000000..ff50343 --- /dev/null +++ b/1278-coredump-make-check-that-all-argv-meta-data-fields-a.patch @@ -0,0 +1,34 @@ +From 9109aaae160fe7dcb9390829db619e4e8f90274f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 31 Oct 2024 17:02:59 +0100 +Subject: [PATCH] coredump: make check that all argv[] meta data fields are + passed strict + +Otherwise, if some field is not supplied we might end up parsing a NULL +string later. Let's catch that early. + +(cherry picked from commit 098c3975acb3df61eedfe471fca27c21f13cf04c) + +Related: RHEL-104138 +--- + src/coredump/coredump.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index dca78fa72c..b24f4c8cc3 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -1067,9 +1067,10 @@ static int save_context(Context *context, const struct iovec_wrapper *iovw) { + } + } + +- if (!context->meta[META_ARGV_PID]) +- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), +- "Failed to find the PID of crashing process"); ++ /* The basic fields from argv[] should always be there, refuse early if not */ ++ for (int i = 0; i < _META_ARGV_MAX; i++) ++ if (!context->meta[i]) ++ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "A required (%s) has not been sent, aborting.", meta_field_names[i]); + + r = parse_pid(context->meta[META_ARGV_PID], &context->pid); + if (r < 0) diff --git a/1279-coredump-restore-compatibility-with-older-patterns.patch b/1279-coredump-restore-compatibility-with-older-patterns.patch new file mode 100644 index 0000000..90cabb3 --- /dev/null +++ b/1279-coredump-restore-compatibility-with-older-patterns.patch @@ -0,0 +1,122 @@ +From 38d7a52bcdad1cef1dba218f86e3905c24d51d9a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 29 Apr 2025 14:47:59 +0200 +Subject: [PATCH] coredump: restore compatibility with older patterns + +This was broken in f45b8015513d38ee5f7cc361db9c5b88c9aae704. Unfortunately +the review does not talk about backward compatibility at all. There are +two places where it matters: +- During upgrades, the replacement of kernel.core_pattern is asynchronous. + For example, during rpm upgrades, it would be updated a post-transaction + file trigger. In other scenarios, the update might only happen after + reboot. We have a potentially long window where the old pattern is in + place. We need to capture coredumps during upgrades too. +- With --backtrace. The interface of --backtrace, in hindsight, is not + great. But there are users of --backtrace which were written to use + a specific set of arguments, and we can't just break compatiblity. + One example is systemd-coredump-python, but there are also reports of + users using --backtrace to generate coredump logs. + +Thus, we require the original set of args, and will use the additional args if +found. + +A test is added to verify that --backtrace works with and without the optional +args. + +(cherry picked from commit ded0aac389e647d35bce7ec4a48e718d77c0435b) + +Related: RHEL-104138 +--- + src/coredump/coredump.c | 23 +++++++++++++++-------- + test/units/testsuite-74.coredump.sh | 18 +++++++++++------- + 2 files changed, 26 insertions(+), 15 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index b24f4c8cc3..458857ffb2 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -94,8 +94,12 @@ enum { + META_ARGV_SIGNAL, /* %s: number of signal causing dump */ + META_ARGV_TIMESTAMP, /* %t: time of dump, expressed as seconds since the Epoch (we expand this to µs granularity) */ + META_ARGV_RLIMIT, /* %c: core file size soft resource limit */ +- META_ARGV_HOSTNAME, /* %h: hostname */ ++ _META_ARGV_REQUIRED, ++ /* The fields below were added to kernel/core_pattern at later points, so they might be missing. */ ++ META_ARGV_HOSTNAME = _META_ARGV_REQUIRED, /* %h: hostname */ + _META_ARGV_MAX, ++ /* If new fields are added, they should be added here, to maintain compatibility ++ * with callers which don't know about the new fields. */ + + /* The following indexes are cached for a couple of special fields we use (and + * thereby need to be retrieved quickly) for naming coredump files, and attaching +@@ -106,7 +110,7 @@ enum { + _META_MANDATORY_MAX, + + /* The rest are similar to the previous ones except that we won't fail if one of +- * them is missing. */ ++ * them is missing in a message sent over the socket. */ + + META_EXE = _META_MANDATORY_MAX, + META_UNIT, +@@ -1068,7 +1072,7 @@ static int save_context(Context *context, const struct iovec_wrapper *iovw) { + } + + /* The basic fields from argv[] should always be there, refuse early if not */ +- for (int i = 0; i < _META_ARGV_MAX; i++) ++ for (int i = 0; i < _META_ARGV_REQUIRED; i++) + if (!context->meta[i]) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "A required (%s) has not been sent, aborting.", meta_field_names[i]); + +@@ -1286,14 +1290,17 @@ static int gather_pid_metadata_from_argv( + char *t; + + /* We gather all metadata that were passed via argv[] into an array of iovecs that +- * we'll forward to the socket unit */ ++ * we'll forward to the socket unit. ++ * ++ * We require at least _META_ARGV_REQUIRED args, but will accept more. ++ * We know how to parse _META_ARGV_MAX args. The rest will be ignored. */ + +- if (argc < _META_ARGV_MAX) ++ if (argc < _META_ARGV_REQUIRED) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), +- "Not enough arguments passed by the kernel (%i, expected %i).", +- argc, _META_ARGV_MAX); ++ "Not enough arguments passed by the kernel (%i, expected between %i and %i).", ++ argc, _META_ARGV_REQUIRED, _META_ARGV_MAX); + +- for (int i = 0; i < _META_ARGV_MAX; i++) { ++ for (int i = 0; i < MIN(argc, _META_ARGV_MAX); i++) { + + t = argv[i]; + +diff --git a/test/units/testsuite-74.coredump.sh b/test/units/testsuite-74.coredump.sh +index 1093cad8a9..0163131096 100755 +--- a/test/units/testsuite-74.coredump.sh ++++ b/test/units/testsuite-74.coredump.sh +@@ -218,14 +218,18 @@ rm -f /tmp/core.{output,redirected} + (! "${UNPRIV_CMD[@]}" coredumpctl dump "$CORE_TEST_BIN" >/dev/null) + + # --backtrace mode +-# Pass one of the existing journal coredump records to systemd-coredump and +-# use our PID as the source to make matching the coredump later easier +-# systemd-coredump args: PID UID GID SIGNUM TIMESTAMP CORE_SOFT_RLIMIT HOSTNAME ++# Pass one of the existing journal coredump records to systemd-coredump. ++# Use our PID as the source to be able to create a PIDFD and to make matching easier. ++# systemd-coredump args: PID UID GID SIGNUM TIMESTAMP CORE_SOFT_RLIMIT [HOSTNAME] + journalctl -b -n 1 --output=export --output-fields=MESSAGE,COREDUMP COREDUMP_EXE="/usr/bin/test-dump" | +- /usr/lib/systemd/systemd-coredump --backtrace $$ 0 0 6 1679509994 12345 mymachine +-# Wait a bit for the coredump to get processed +-timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $$ | wc -l) -eq 0 ]]; do sleep 1; done" +-coredumpctl info "$$" ++ /usr/lib/systemd/systemd-coredump --backtrace $$ 0 0 6 1679509900 12345 ++journalctl -b -n 1 --output=export --output-fields=MESSAGE,COREDUMP COREDUMP_EXE="/usr/bin/test-dump" | ++ /usr/lib/systemd/systemd-coredump --backtrace $$ 0 0 6 1679509901 12345 mymachine ++# Wait a bit for the coredumps to get processed ++timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $$ | wc -l) -lt 2 ]]; do sleep 1; done" ++coredumpctl info $$ ++coredumpctl info COREDUMP_TIMESTAMP=1679509900000000 ++coredumpctl info COREDUMP_TIMESTAMP=1679509901000000 + coredumpctl info COREDUMP_HOSTNAME="mymachine" + + # This used to cause a stack overflow diff --git a/1280-coredump-use-d-in-kernel-core-pattern.patch b/1280-coredump-use-d-in-kernel-core-pattern.patch new file mode 100644 index 0000000..d6c53bf --- /dev/null +++ b/1280-coredump-use-d-in-kernel-core-pattern.patch @@ -0,0 +1,158 @@ +From fbc5015c95298c71c806b5e80207e52688aad69a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 29 Apr 2025 14:47:59 +0200 +Subject: [PATCH] coredump: use %d in kernel core pattern +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The kernel provides %d which is documented as +"dump mode—same as value returned by prctl(2) PR_GET_DUMPABLE". + +We already query /proc/pid/auxv for this information, but unfortunately this +check is subject to a race, because the crashed process may be replaced by an +attacker before we read this data, for example replacing a SUID process that +was killed by a signal with another process that is not SUID, tricking us into +making the coredump of the original process readable by the attacker. + +With this patch, we effectively add one more check to the list of conditions +that need be satisfied if we are to make the coredump accessible to the user. + +Reportedy-by: Qualys Security Advisory + +In principle, %d might return a value other than 0, 1, or 2 in the future. +Thus, we accept those, but emit a notice. + +(cherry picked from commit 0c49e0049b7665bb7769a13ef346fef92e1ad4d6) + +Related: RHEL-104138 +--- + man/systemd-coredump.xml | 10 ++++++++++ + src/coredump/coredump.c | 22 +++++++++++++++++++--- + sysctl.d/50-coredump.conf.in | 2 +- + test/units/testsuite-74.coredump.sh | 5 +++++ + 4 files changed, 35 insertions(+), 4 deletions(-) + +diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml +index cb9f47745b..6cfa04f466 100644 +--- a/man/systemd-coredump.xml ++++ b/man/systemd-coredump.xml +@@ -259,6 +259,16 @@ COREDUMP_FILENAME=/var/lib/systemd/coredump/core.Web….552351.….zst + + + ++ ++ COREDUMP_DUMPABLE= ++ ++ The PR_GET_DUMPABLE field as reported by the kernel, see ++ prctl2. ++ ++ ++ ++ + + COREDUMP_OPEN_FDS= + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 458857ffb2..cd10678c43 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -97,7 +97,9 @@ enum { + _META_ARGV_REQUIRED, + /* The fields below were added to kernel/core_pattern at later points, so they might be missing. */ + META_ARGV_HOSTNAME = _META_ARGV_REQUIRED, /* %h: hostname */ ++ META_ARGV_DUMPABLE, /* %d: as set by the kernel */ + _META_ARGV_MAX, ++ + /* If new fields are added, they should be added here, to maintain compatibility + * with callers which don't know about the new fields. */ + +@@ -126,6 +128,7 @@ static const char * const meta_field_names[_META_MAX] = { + [META_ARGV_TIMESTAMP] = "COREDUMP_TIMESTAMP=", + [META_ARGV_RLIMIT] = "COREDUMP_RLIMIT=", + [META_ARGV_HOSTNAME] = "COREDUMP_HOSTNAME=", ++ [META_ARGV_DUMPABLE] = "COREDUMP_DUMPABLE=", + [META_COMM] = "COREDUMP_COMM=", + [META_EXE] = "COREDUMP_EXE=", + [META_UNIT] = "COREDUMP_UNIT=", +@@ -138,6 +141,7 @@ typedef struct Context { + pid_t pid; + uid_t uid; + gid_t gid; ++ unsigned dumpable; + bool is_pid1; + bool is_journald; + } Context; +@@ -453,14 +457,16 @@ static int grant_user_access(int core_fd, const Context *context) { + 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. */ ++ /* We allow access if %d/dumpable on the command line was exactly 1, we got all the data, ++ * at_secure is not set, and the uid/gid match euid/egid. */ + bool ret = ++ context->dumpable == 1 && + 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)", ++ log_debug("Will %s access (dumpable=%u uid="UID_FMT " euid="UID_FMT " gid="GID_FMT " egid="GID_FMT " at_secure=%s)", + ret ? "permit" : "restrict", ++ context->dumpable, + uid, euid, gid, egid, yes_no(at_secure)); + return ret; + } +@@ -1089,6 +1095,16 @@ static int save_context(Context *context, const struct iovec_wrapper *iovw) { + return log_error_errno(r, "Failed to parse GID \"%s\": %m", context->meta[META_ARGV_GID]); + + ++ /* The value is set to contents of /proc/sys/fs/suid_dumpable, which we set to 2, ++ * if the process is marked as not dumpable, see PR_SET_DUMPABLE(2const). */ ++ if (context->meta[META_ARGV_DUMPABLE]) { ++ r = safe_atou(context->meta[META_ARGV_DUMPABLE], &context->dumpable); ++ if (r < 0) ++ return log_error_errno(r, "Failed to parse dumpable field \"%s\": %m", context->meta[META_ARGV_DUMPABLE]); ++ if (context->dumpable > 2) ++ log_notice("Got unexpected %%d/dumpable value %u.", context->dumpable); ++ } ++ + unit = context->meta[META_UNIT]; + context->is_pid1 = streq(context->meta[META_ARGV_PID], "1") || streq_ptr(unit, SPECIAL_INIT_SCOPE); + context->is_journald = streq_ptr(unit, SPECIAL_JOURNALD_SERVICE); +diff --git a/sysctl.d/50-coredump.conf.in b/sysctl.d/50-coredump.conf.in +index 5fb551a8cf..9c10a89828 100644 +--- a/sysctl.d/50-coredump.conf.in ++++ b/sysctl.d/50-coredump.conf.in +@@ -13,7 +13,7 @@ + # the core dump. + # + # See systemd-coredump(8) and core(5). +-kernel.core_pattern=|{{ROOTLIBEXECDIR}}/systemd-coredump %P %u %g %s %t %c %h ++kernel.core_pattern=|{{ROOTLIBEXECDIR}}/systemd-coredump %P %u %g %s %t %c %h %d + + # Allow 16 coredumps to be dispatched in parallel by the kernel. + # We collect metadata from /proc/%P/, and thus need to make sure the crashed +diff --git a/test/units/testsuite-74.coredump.sh b/test/units/testsuite-74.coredump.sh +index 0163131096..b72313672c 100755 +--- a/test/units/testsuite-74.coredump.sh ++++ b/test/units/testsuite-74.coredump.sh +@@ -225,12 +225,17 @@ journalctl -b -n 1 --output=export --output-fields=MESSAGE,COREDUMP COREDUMP_EXE + /usr/lib/systemd/systemd-coredump --backtrace $$ 0 0 6 1679509900 12345 + journalctl -b -n 1 --output=export --output-fields=MESSAGE,COREDUMP COREDUMP_EXE="/usr/bin/test-dump" | + /usr/lib/systemd/systemd-coredump --backtrace $$ 0 0 6 1679509901 12345 mymachine ++journalctl -b -n 1 --output=export --output-fields=MESSAGE,COREDUMP COREDUMP_EXE="/usr/bin/test-dump" | ++ /usr/lib/systemd/systemd-coredump --backtrace $$ 0 0 6 1679509902 12345 youmachine 1 + # Wait a bit for the coredumps to get processed + timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $$ | wc -l) -lt 2 ]]; do sleep 1; done" + coredumpctl info $$ + coredumpctl info COREDUMP_TIMESTAMP=1679509900000000 + coredumpctl info COREDUMP_TIMESTAMP=1679509901000000 + coredumpctl info COREDUMP_HOSTNAME="mymachine" ++coredumpctl info COREDUMP_TIMESTAMP=1679509902000000 ++coredumpctl info COREDUMP_HOSTNAME="youmachine" ++coredumpctl info COREDUMP_DUMPABLE="1" + + # This used to cause a stack overflow + systemd-run -t --property CoredumpFilter=all ls /tmp diff --git a/1281-pidref-add-structure-that-can-reference-a-pid-via-bo.patch b/1281-pidref-add-structure-that-can-reference-a-pid-via-bo.patch new file mode 100644 index 0000000..906c988 --- /dev/null +++ b/1281-pidref-add-structure-that-can-reference-a-pid-via-bo.patch @@ -0,0 +1,230 @@ +From e638eb667af0e8ac9d3d409edbbf51507a4eef0e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Sat, 9 Sep 2023 09:29:27 +0200 +Subject: [PATCH] pidref: add structure that can reference a pid via both pidfd + and pid_t + +Let's start with the conversion of PID 1 to pidfds. Let's add a simple +structure with just two fields that can be used to maintain a reference +to arbitrary processes via both pid_t and pidfd. + +This is an embeddable struct, to keep it in line with where we +previously used a pid_t directly to track a process. + +Of course, since this might contain an fd on systems where we have pidfd +this structure has a proper lifecycle. + +(Note that this is quite different from sd_event_add_child() event +source objects as that one is only for child processes and collects +process results, while this infra is much simpler and more generic and +can be used to reference any process, anywhere in the tree.) + +(cherry picked from commit 3bda3f17fa84557eeb28fa7c330cbd3a3f876d47) + +Related: RHEL-104138 +--- + src/basic/meson.build | 1 + + src/basic/pidref.c | 145 ++++++++++++++++++++++++++++++++++++++++++ + src/basic/pidref.h | 29 +++++++++ + 3 files changed, 175 insertions(+) + create mode 100644 src/basic/pidref.c + create mode 100644 src/basic/pidref.h + +diff --git a/src/basic/meson.build b/src/basic/meson.build +index 11053a5ecd..b8b4213c70 100644 +--- a/src/basic/meson.build ++++ b/src/basic/meson.build +@@ -182,6 +182,7 @@ basic_sources = files( + 'path-util.h', + 'percent-util.c', + 'percent-util.h', ++ 'pidref.c', + 'prioq.c', + 'prioq.h', + 'proc-cmdline.c', +diff --git a/src/basic/pidref.c b/src/basic/pidref.c +new file mode 100644 +index 0000000000..f41460938c +--- /dev/null ++++ b/src/basic/pidref.c +@@ -0,0 +1,145 @@ ++/* SPDX-License-Identifier: LGPL-2.1-or-later */ ++ ++#include "errno-util.h" ++#include "fd-util.h" ++#include "missing_syscall.h" ++#include "parse-util.h" ++#include "pidref.h" ++#include "process-util.h" ++ ++int pidref_set_pid(PidRef *pidref, pid_t pid) { ++ int fd; ++ ++ assert(pidref); ++ ++ if (pid < 0) ++ return -ESRCH; ++ if (pid == 0) ++ pid = getpid_cached(); ++ ++ fd = pidfd_open(pid, 0); ++ if (fd < 0) { ++ /* Graceful fallback in case the kernel doesn't support pidfds or is out of fds */ ++ if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno) && !ERRNO_IS_RESOURCE(errno)) ++ return -errno; ++ ++ fd = -EBADF; ++ } ++ ++ *pidref = (PidRef) { ++ .fd = fd, ++ .pid = pid, ++ }; ++ ++ return 0; ++} ++ ++int pidref_set_pidstr(PidRef *pidref, const char *pid) { ++ pid_t nr; ++ int r; ++ ++ assert(pidref); ++ ++ r = parse_pid(pid, &nr); ++ if (r < 0) ++ return r; ++ ++ return pidref_set_pid(pidref, nr); ++} ++ ++int pidref_set_pidfd(PidRef *pidref, int fd) { ++ int r; ++ ++ assert(pidref); ++ ++ if (fd < 0) ++ return -EBADF; ++ ++ int fd_copy = fcntl(fd, F_DUPFD_CLOEXEC, 3); ++ if (fd_copy < 0) { ++ pid_t pid; ++ ++ if (!ERRNO_IS_RESOURCE(errno)) ++ return -errno; ++ ++ /* Graceful fallback if we are out of fds */ ++ r = pidfd_get_pid(fd, &pid); ++ if (r < 0) ++ return r; ++ ++ *pidref = (PidRef) { ++ .fd = -EBADF, ++ .pid = pid, ++ }; ++ ++ return 0; ++ } ++ ++ return pidref_set_pidfd_consume(pidref, fd_copy); ++} ++ ++int pidref_set_pidfd_take(PidRef *pidref, int fd) { ++ pid_t pid; ++ int r; ++ ++ assert(pidref); ++ ++ if (fd < 0) ++ return -EBADF; ++ ++ r = pidfd_get_pid(fd, &pid); ++ if (r < 0) ++ return r; ++ ++ *pidref = (PidRef) { ++ .fd = fd, ++ .pid = pid, ++ }; ++ ++ return 0; ++} ++ ++int pidref_set_pidfd_consume(PidRef *pidref, int fd) { ++ int r; ++ ++ r = pidref_set_pidfd_take(pidref, fd); ++ if (r < 0) ++ safe_close(fd); ++ ++ return r; ++} ++ ++void pidref_done(PidRef *pidref) { ++ assert(pidref); ++ ++ *pidref = (PidRef) { ++ .fd = safe_close(pidref->fd), ++ }; ++} ++ ++int pidref_kill(PidRef *pidref, int sig) { ++ ++ if (!pidref) ++ return -ESRCH; ++ ++ if (pidref->fd >= 0) ++ return RET_NERRNO(pidfd_send_signal(pidref->fd, sig, NULL, 0)); ++ ++ if (pidref->pid > 0) ++ return RET_NERRNO(kill(pidref->pid, sig)); ++ ++ return -ESRCH; ++} ++ ++int pidref_kill_and_sigcont(PidRef *pidref, int sig) { ++ int r; ++ ++ r = pidref_kill(pidref, sig); ++ if (r < 0) ++ return r; ++ ++ if (!IN_SET(sig, SIGCONT, SIGKILL)) ++ (void) pidref_kill(pidref, SIGCONT); ++ ++ return 0; ++} +diff --git a/src/basic/pidref.h b/src/basic/pidref.h +new file mode 100644 +index 0000000000..2411e510f1 +--- /dev/null ++++ b/src/basic/pidref.h +@@ -0,0 +1,29 @@ ++/* SPDX-License-Identifier: LGPL-2.1-or-later */ ++#pragma once ++ ++#include "macro.h" ++ ++/* An embeddable structure carrying a reference to a process. Supposed to be used when tracking processes continously. */ ++typedef struct PidRef { ++ pid_t pid; /* always valid */ ++ int fd; /* only valid if pidfd are available in the kernel, and we manage to get an fd */ ++} PidRef; ++ ++#define PIDREF_NULL (PidRef) { .fd = -EBADF } ++ ++static inline bool pidref_is_set(const PidRef *pidref) { ++ return pidref && pidref->pid > 0; ++} ++ ++int pidref_set_pid(PidRef *pidref, pid_t pid); ++int pidref_set_pidstr(PidRef *pidref, const char *pid); ++int pidref_set_pidfd(PidRef *pidref, int fd); ++int pidref_set_pidfd_take(PidRef *pidref, int fd); /* takes ownership of the passed pidfd on success*/ ++int pidref_set_pidfd_consume(PidRef *pidref, int fd); /* takes ownership of the passed pidfd in both success and failure */ ++ ++void pidref_done(PidRef *pidref); ++ ++int pidref_kill(PidRef *pidref, int sig); ++int pidref_kill_and_sigcont(PidRef *pidref, int sig); ++ ++#define TAKE_PIDREF(p) TAKE_GENERIC((p), PidRef, PIDREF_NULL) diff --git a/1282-fd-util-introduce-parse_fd.patch b/1282-fd-util-introduce-parse_fd.patch new file mode 100644 index 0000000..0442124 --- /dev/null +++ b/1282-fd-util-introduce-parse_fd.patch @@ -0,0 +1,54 @@ +From 8219e46540ddf0d6a7d3f97481debf297723a58f Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 5 May 2023 08:09:14 +0200 +Subject: [PATCH] fd-util: introduce parse_fd() + +It's a simple wrapper for safe_atoi() that returns error if the parsed +fd is < 0 . + +(cherry picked from commit b8f83d7f0c35dca6ca3a23c42215d566e2815ca5) + +Related: RHEL-104138 +--- + src/basic/parse-util.c | 15 +++++++++++++++ + src/basic/parse-util.h | 1 + + 2 files changed, 16 insertions(+) + +diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c +index 3b3efb0ab8..4161211c49 100644 +--- a/src/basic/parse-util.c ++++ b/src/basic/parse-util.c +@@ -313,6 +313,21 @@ int parse_errno(const char *t) { + return e; + } + ++int parse_fd(const char *t) { ++ int r, fd; ++ ++ assert(t); ++ ++ r = safe_atoi(t, &fd); ++ if (r < 0) ++ return r; ++ ++ if (fd < 0) ++ return -ERANGE; ++ ++ return fd; ++} ++ + static const char *mangle_base(const char *s, unsigned *base) { + const char *k; + +diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h +index 8d8d52327b..5c012d702a 100644 +--- a/src/basic/parse-util.h ++++ b/src/basic/parse-util.h +@@ -20,6 +20,7 @@ int parse_mtu(int family, const char *s, uint32_t *ret); + int parse_size(const char *t, uint64_t base, uint64_t *size); + int parse_range(const char *t, unsigned *lower, unsigned *upper); + int parse_errno(const char *t); ++int parse_fd(const char *t); + + #define SAFE_ATO_REFUSE_PLUS_MINUS (1U << 30) + #define SAFE_ATO_REFUSE_LEADING_ZERO (1U << 29) diff --git a/1283-coredump-add-support-for-new-F-PIDFD-specifier.patch b/1283-coredump-add-support-for-new-F-PIDFD-specifier.patch new file mode 100644 index 0000000..ab2779e --- /dev/null +++ b/1283-coredump-add-support-for-new-F-PIDFD-specifier.patch @@ -0,0 +1,245 @@ +From 27faf1af778849841d7c3140bd3d92aceaea2ee3 Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Sun, 13 Apr 2025 22:10:36 +0100 +Subject: [PATCH] coredump: add support for new %F PIDFD specifier + +A new core_pattern specifier was added, %F, to provide a PIDFD +to the usermode helper process referring to the crashed process. +This removes all possible race conditions, ensuring only the +crashed process gets inspected by systemd-coredump. + +(cherry picked from commit 868d95577ec9f862580ad365726515459be582fc) + +Resolves: RHEL-104138 +--- + man/systemd-coredump.xml | 9 ++++ + src/coredump/coredump.c | 89 ++++++++++++++++++++++++++++++++---- + sysctl.d/50-coredump.conf.in | 2 +- + 3 files changed, 89 insertions(+), 11 deletions(-) + +diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml +index 6cfa04f466..b3d81d838a 100644 +--- a/man/systemd-coredump.xml ++++ b/man/systemd-coredump.xml +@@ -186,6 +186,15 @@ COREDUMP_FILENAME=/var/lib/systemd/coredump/core.Web….552351.….zst + + + ++ ++ COREDUMP_BY_PIDFD= ++ If the crashed process was analyzed using a PIDFD provided by the kernel (requires ++ kernel v6.16) then this field will be present and set to 1. If this field is ++ not set, then the crashed process was analyzed via a PID, which is known to be subject to race ++ conditions. ++ ++ ++ + + COREDUMP_TIMESTAMP= + The time of the crash as reported by the kernel (in µs since the epoch). +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index cd10678c43..e0aac3c8d0 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -39,6 +39,7 @@ + #include "mkdir-label.h" + #include "namespace-util.h" + #include "parse-util.h" ++#include "pidref.h" + #include "process-util.h" + #include "signal-util.h" + #include "socket-util.h" +@@ -98,8 +99,8 @@ enum { + /* The fields below were added to kernel/core_pattern at later points, so they might be missing. */ + META_ARGV_HOSTNAME = _META_ARGV_REQUIRED, /* %h: hostname */ + META_ARGV_DUMPABLE, /* %d: as set by the kernel */ ++ META_ARGV_PIDFD, /* %F: pidfd of the process, since v6.16 */ + _META_ARGV_MAX, +- + /* If new fields are added, they should be added here, to maintain compatibility + * with callers which don't know about the new fields. */ + +@@ -129,6 +130,7 @@ static const char * const meta_field_names[_META_MAX] = { + [META_ARGV_RLIMIT] = "COREDUMP_RLIMIT=", + [META_ARGV_HOSTNAME] = "COREDUMP_HOSTNAME=", + [META_ARGV_DUMPABLE] = "COREDUMP_DUMPABLE=", ++ [META_ARGV_PIDFD] = "COREDUMP_BY_PIDFD=", + [META_COMM] = "COREDUMP_COMM=", + [META_EXE] = "COREDUMP_EXE=", + [META_UNIT] = "COREDUMP_UNIT=", +@@ -136,6 +138,7 @@ static const char * const meta_field_names[_META_MAX] = { + }; + + typedef struct Context { ++ PidRef pidref; + const char *meta[_META_MAX]; + size_t meta_size[_META_MAX]; + pid_t pid; +@@ -146,6 +149,14 @@ typedef struct Context { + bool is_journald; + } Context; + ++#define CONTEXT_NULL \ ++ (Context) { \ ++ .pidref = PIDREF_NULL, \ ++ .uid = UID_INVALID, \ ++ .gid = GID_INVALID, \ ++ } ++ ++ + typedef enum CoredumpStorage { + COREDUMP_STORAGE_NONE, + COREDUMP_STORAGE_EXTERNAL, +@@ -171,6 +182,12 @@ static uint64_t arg_journal_size_max = JOURNAL_SIZE_MAX; + static uint64_t arg_keep_free = UINT64_MAX; + static uint64_t arg_max_use = UINT64_MAX; + ++static void context_done(Context *c) { ++ assert(c); ++ ++ pidref_done(&c->pidref); ++} ++ + static int parse_config(void) { + static const ConfigTableItem items[] = { + { "Coredump", "Storage", config_parse_coredump_storage, 0, &arg_storage }, +@@ -1114,7 +1131,7 @@ static int save_context(Context *context, const struct iovec_wrapper *iovw) { + + static int process_socket(int fd) { + _cleanup_close_ int input_fd = -EBADF, mntns_fd = -EBADF; +- Context context = {}; ++ _cleanup_(context_done) Context context = CONTEXT_NULL; + struct iovec_wrapper iovw = {}; + struct iovec iovec; + int iterations = 0, r; +@@ -1215,7 +1232,7 @@ static int process_socket(int fd) { + goto finish; + + /* Make sure we received at least all fields we need. */ +- for (int i = 0; i < _META_MANDATORY_MAX; i++) ++ for (int i = 0; i < _META_ARGV_REQUIRED; i++) + if (!context.meta[i]) { + r = log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "A mandatory argument (%i) has not been sent, aborting.", +@@ -1301,9 +1318,9 @@ static int gather_pid_metadata_from_argv( + Context *context, + int argc, char **argv) { + ++ _cleanup_(pidref_done) PidRef local_pidref = PIDREF_NULL; + _cleanup_free_ char *free_timestamp = NULL; +- int r, signo; +- char *t; ++ int r, signo, kernel_fd = -EBADF; + + /* We gather all metadata that were passed via argv[] into an array of iovecs that + * we'll forward to the socket unit. +@@ -1317,8 +1334,7 @@ static int gather_pid_metadata_from_argv( + argc, _META_ARGV_REQUIRED, _META_ARGV_MAX); + + for (int i = 0; i < MIN(argc, _META_ARGV_MAX); i++) { +- +- t = argv[i]; ++ const char *t = argv[i]; + + switch (i) { + +@@ -1343,6 +1359,47 @@ static int gather_pid_metadata_from_argv( + break; + } + ++ if (i == META_ARGV_PID) { ++ /* Store this so that we can check whether the core will be forwarded to a container ++ * even when the kernel doesn't provide a pidfd. Can be dropped once baseline is ++ * >= v6.16. */ ++ r = pidref_set_pidstr(&local_pidref, t); ++ if (r < 0) ++ return log_error_errno(r, "Failed to initialize pidref from pid %s: %m", t); ++ } ++ ++ if (i == META_ARGV_PIDFD) { ++ /* If the current kernel doesn't support the %F specifier (which resolves to a ++ * pidfd), but we included it in the core_pattern expression, we'll receive an empty ++ * string here. Deal with that gracefully. */ ++ if (isempty(t)) ++ continue; ++ ++ assert(!pidref_is_set(&context->pidref)); ++ assert(kernel_fd < 0); ++ ++ kernel_fd = parse_fd(t); ++ if (kernel_fd < 0) ++ return log_error_errno(kernel_fd, "Failed to parse pidfd \"%s\": %m", t); ++ ++ r = pidref_set_pidfd(&context->pidref, kernel_fd); ++ if (r < 0) ++ return log_error_errno(r, "Failed to initialize pidref from pidfd %d: %m", kernel_fd); ++ ++ /* If there are containers involved with different versions of the code they might ++ * not be using pidfds, so it would be wrong to set the metadata, skip it. */ ++ r = in_same_namespace(getpid_cached(), context->pidref.pid, NAMESPACE_PID); ++ if (r < 0) ++ log_debug_errno(r, "Failed to check pidns of crashing process, ignoring: %m"); ++ if (r <= 0) ++ continue; ++ ++ /* We don't print the fd number in the journal as it's meaningless, but we still ++ * record that the parsing was done with a kernel-provided fd as it means it's safe ++ * from races, which is valuable information to provide in the journal record. */ ++ t = "1"; ++ } ++ + r = iovw_put_string_field(iovw, meta_field_names[i], t); + if (r < 0) + return r; +@@ -1350,7 +1407,19 @@ static int gather_pid_metadata_from_argv( + + /* Cache some of the process metadata we collected so far and that we'll need to + * access soon */ +- return save_context(context, iovw); ++ r = save_context(context, iovw); ++ if (r < 0) ++ return r; ++ ++ /* If the kernel didn't give us a PIDFD, then use the one derived from the ++ * PID immediately, given we have it. */ ++ if (!pidref_is_set(&context->pidref)) ++ context->pidref = TAKE_PIDREF(local_pidref); ++ ++ /* Close the kernel-provided FD as the last thing after everything else succeeded. */ ++ kernel_fd = safe_close(kernel_fd); ++ ++ return 0; + } + + static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) { +@@ -1466,7 +1535,7 @@ static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) { + } + + static int process_kernel(int argc, char* argv[]) { +- Context context = {}; ++ _cleanup_(context_done) Context context = CONTEXT_NULL; + struct iovec_wrapper *iovw; + int r, mntns_fd = -EBADF; + +@@ -1543,7 +1612,7 @@ static int process_kernel(int argc, char* argv[]) { + } + + static int process_backtrace(int argc, char *argv[]) { +- Context context = {}; ++ _cleanup_(context_done) Context context = CONTEXT_NULL; + struct iovec_wrapper *iovw; + char *message; + int r; +diff --git a/sysctl.d/50-coredump.conf.in b/sysctl.d/50-coredump.conf.in +index 9c10a89828..1c6230ad93 100644 +--- a/sysctl.d/50-coredump.conf.in ++++ b/sysctl.d/50-coredump.conf.in +@@ -13,7 +13,7 @@ + # the core dump. + # + # See systemd-coredump(8) and core(5). +-kernel.core_pattern=|{{ROOTLIBEXECDIR}}/systemd-coredump %P %u %g %s %t %c %h %d ++kernel.core_pattern=|{{ROOTLIBEXECDIR}}/systemd-coredump %P %u %g %s %t %c %h %d %F + + # Allow 16 coredumps to be dispatched in parallel by the kernel. + # We collect metadata from /proc/%P/, and thus need to make sure the crashed diff --git a/systemd.spec b/systemd.spec index f9feb0a..50e4e9a 100644 --- a/systemd.spec +++ b/systemd.spec @@ -21,7 +21,7 @@ Name: systemd Url: https://systemd.io Version: 252 -Release: 59%{?dist} +Release: 60%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -1356,6 +1356,16 @@ Patch1270: 1270-timer-don-t-run-service-immediately-after-restart-of.patch Patch1271: 1271-test-store-and-compare-just-the-property-value.patch Patch1272: 1272-test-make-test-fd-util-more-lenient-when-using-fd_mo.patch Patch1273: 1273-basic-add-PIDFS-magic-31709.patch +Patch1274: 1274-man-fix-a-missing-word.patch +Patch1275: 1275-cryptsetup-Add-optional-support-for-linking-volume-k.patch +Patch1276: 1276-cryptsetup-fix-typo.patch +Patch1277: 1277-cryptsetup-HAVE_CRYPT_SET_KEYRING_TO_LINK-is-always-.patch +Patch1278: 1278-coredump-make-check-that-all-argv-meta-data-fields-a.patch +Patch1279: 1279-coredump-restore-compatibility-with-older-patterns.patch +Patch1280: 1280-coredump-use-d-in-kernel-core-pattern.patch +Patch1281: 1281-pidref-add-structure-that-can-reference-a-pid-via-bo.patch +Patch1282: 1282-fd-util-introduce-parse_fd.patch +Patch1283: 1283-coredump-add-support-for-new-F-PIDFD-specifier.patch # Downstream-only patches (9000–9999) @@ -2233,6 +2243,18 @@ systemd-hwdb update &>/dev/null || : %{_prefix}/lib/dracut/modules.d/70rhel-net-naming-sysattrs/* %changelog +* Wed Nov 05 2025 systemd maintenance team - 252-60 +- man: fix a missing word (RHEL-115182) +- cryptsetup: Add optional support for linking volume key in keyring. (RHEL-97175) +- cryptsetup: fix typo (RHEL-97175) +- cryptsetup: HAVE_CRYPT_SET_KEYRING_TO_LINK is always defined (RHEL-97175) +- coredump: make check that all argv[] meta data fields are passed strict (RHEL-104138) +- coredump: restore compatibility with older patterns (RHEL-104138) +- coredump: use %d in kernel core pattern (RHEL-104138) +- pidref: add structure that can reference a pid via both pidfd and pid_t (RHEL-104138) +- fd-util: introduce parse_fd() (RHEL-104138) +- coredump: add support for new %F PIDFD specifier (RHEL-104138) + * Thu Oct 02 2025 systemd maintenance team - 252-59 - test: rename TEST-53-ISSUE-16347 to TEST-53-TIMER (RHEL-118215) - test: restarting elapsed timer shouldn't trigger the corresponding service (RHEL-118215)