From 965552652cb48ccf79d3de26b83d33f540230b0d Mon Sep 17 00:00:00 2001 From: AlmaLinux RelEng Bot Date: Tue, 5 May 2026 06:25:07 -0400 Subject: [PATCH] import UBI systemd-257-13.el10_1.3 --- .abignore | 3 + ...pidfd-after-parsing-data-in-usermode.patch | 32 ++++ ...re-compatibility-with-older-patterns.patch | 122 +++++++++++++ ...p-long-lines-fix-grammar-in-comments.patch | 123 +++++++++++++ ...edump-get-rid-of-_META_MANDATORY_MAX.patch | 94 ++++++++++ ...oredump-use-d-in-kernel-core-pattern.patch | 155 +++++++++++++++++ ...op-forwarding-non-dumpable-processes.patch | 52 ++++++ ...oredump-get-rid-of-a-bogus-assertion.patch | 42 +++++ ...dd-support-for-new-F-PIDFD-specifier.patch | 153 +++++++++++++++++ ...pidfd-is-used-again-allow-forwarding.patch | 53 ++++++ ...ce-an-enum-to-wrap-dumpable-constant.patch | 82 +++++++++ ...efine-helper-to-call-PR_SET_DUMPABLE.patch | 115 +++++++++++++ ...dump-fix-0-passed-as-pointer-warning.patch | 25 +++ ...dump-fix-0-passed-as-pointer-warning.patch | 25 +++ ...efine-helper-to-call-PR_SET_DUMPABLE.patch | 115 +++++++++++++ ...introduce-an-enum-to-wrap-dumpable-c.patch | 79 +++++++++ ...when-F-pidfd-is-used-again-allow-for.patch | 53 ++++++ ...add-support-for-new-F-PIDFD-specifie.patch | 148 ++++++++++++++++ ...oredump-get-rid-of-a-bogus-assertion.patch | 24 +++ ...also-stop-forwarding-non-dumpable-pr.patch | 49 ++++++ ...oredump-use-d-in-kernel-core-pattern.patch | 138 +++++++++++++++ ...edump-get-rid-of-_META_MANDATORY_MAX.patch | 83 +++++++++ ...wrap-long-lines-fix-grammar-in-comme.patch | 123 +++++++++++++ ...restore-compatibility-with-older-pat.patch | 102 +++++++++++ ...verify-pidfd-after-parsing-data-in-u.patch | 29 ++++ ...-framework-option-for-build-and-unit.patch | 89 ++++++++++ ...bpftool-workaround-to-codeql-job-too.patch | 32 ++++ ...-workaround-about-bpftool-for-codeql.patch | 27 +++ ...d-bpftool-workaround-to-coverity-too.patch | 31 ++++ ...mkosi-to-the-latest-RHEL-10.1-commit.patch | 40 +++++ ...-apt-get-update-before-running-mkosi.patch | 50 ++++++ ...avour-of-path_startswith-that-leaves.patch | 162 ++++++++++++++++++ ...me-code-over-to-path_startswith_full.patch | 45 +++++ ...-PATH_STARTSWITH_ACCEPT_DOT_DOT-flag.patch | 95 ++++++++++ ...by-one-issue-when-updating-parent-fo.patch | 28 +++ ...group-avoid-one-unnecessary-strjoina.patch | 96 +++++++++++ ...ate-input-cgroup-path-more-prudently.patch | 29 ++++ systemd.spec | 80 ++++++++- 38 files changed, 2822 insertions(+), 1 deletion(-) create mode 100644 .abignore create mode 100644 0439-coredump-verify-pidfd-after-parsing-data-in-usermode.patch create mode 100644 0440-coredump-restore-compatibility-with-older-patterns.patch create mode 100644 0441-coredump-wrap-long-lines-fix-grammar-in-comments.patch create mode 100644 0442-coredump-get-rid-of-_META_MANDATORY_MAX.patch create mode 100644 0443-coredump-use-d-in-kernel-core-pattern.patch create mode 100644 0444-coredump-also-stop-forwarding-non-dumpable-processes.patch create mode 100644 0445-coredump-get-rid-of-a-bogus-assertion.patch create mode 100644 0446-coredump-add-support-for-new-F-PIDFD-specifier.patch create mode 100644 0447-coredump-when-F-pidfd-is-used-again-allow-forwarding.patch create mode 100644 0448-coredump-introduce-an-enum-to-wrap-dumpable-constant.patch create mode 100644 0449-Define-helper-to-call-PR_SET_DUMPABLE.patch create mode 100644 0450-coredump-fix-0-passed-as-pointer-warning.patch create mode 100644 0451-Revert-coredump-fix-0-passed-as-pointer-warning.patch create mode 100644 0452-Revert-Define-helper-to-call-PR_SET_DUMPABLE.patch create mode 100644 0453-Revert-coredump-introduce-an-enum-to-wrap-dumpable-c.patch create mode 100644 0454-Revert-coredump-when-F-pidfd-is-used-again-allow-for.patch create mode 100644 0455-Revert-coredump-add-support-for-new-F-PIDFD-specifie.patch create mode 100644 0456-Revert-coredump-get-rid-of-a-bogus-assertion.patch create mode 100644 0457-Revert-coredump-also-stop-forwarding-non-dumpable-pr.patch create mode 100644 0458-Revert-coredump-use-d-in-kernel-core-pattern.patch create mode 100644 0459-Revert-coredump-get-rid-of-_META_MANDATORY_MAX.patch create mode 100644 0460-Revert-coredump-wrap-long-lines-fix-grammar-in-comme.patch create mode 100644 0461-Revert-coredump-restore-compatibility-with-older-pat.patch create mode 100644 0462-Revert-coredump-verify-pidfd-after-parsing-data-in-u.patch create mode 100644 0463-ci-re-enable-bpf-framework-option-for-build-and-unit.patch create mode 100644 0464-ci-add-bpftool-workaround-to-codeql-job-too.patch create mode 100644 0465-ci-fix-workaround-about-bpftool-for-codeql.patch create mode 100644 0466-ci-add-bpftool-workaround-to-coverity-too.patch create mode 100644 0467-ci-pin-Packit-mkosi-to-the-latest-RHEL-10.1-commit.patch create mode 100644 0468-ci-run-apt-get-update-before-running-mkosi.patch create mode 100644 0469-path-util-add-flavour-of-path_startswith-that-leaves.patch create mode 100644 0470-cgroup-port-some-code-over-to-path_startswith_full.patch create mode 100644 0471-path-util-invert-PATH_STARTSWITH_ACCEPT_DOT_DOT-flag.patch create mode 100644 0472-sd-json-fix-off-by-one-issue-when-updating-parent-fo.patch create mode 100644 0473-core-cgroup-avoid-one-unnecessary-strjoina.patch create mode 100644 0474-core-validate-input-cgroup-path-more-prudently.patch diff --git a/.abignore b/.abignore new file mode 100644 index 0000000..6a33b88 --- /dev/null +++ b/.abignore @@ -0,0 +1,3 @@ +[suppress_file] +# Those shared objects are private to systemd +file_name_regexp=libsystemd-(shared|core)-.*.so diff --git a/0439-coredump-verify-pidfd-after-parsing-data-in-usermode.patch b/0439-coredump-verify-pidfd-after-parsing-data-in-usermode.patch new file mode 100644 index 0000000..c95a481 --- /dev/null +++ b/0439-coredump-verify-pidfd-after-parsing-data-in-usermode.patch @@ -0,0 +1,32 @@ +From ae1394abcded51ed5e443d1124059b2e31748baa Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Fri, 11 Apr 2025 14:44:30 +0100 +Subject: [PATCH] coredump: verify pidfd after parsing data in usermode helper + +Ensure the pidfd is still valid before continuing + +Follow-up for 313537da6ffdea4049873571202679734d49f0a1 + +(cherry picked from commit ba6c955f21ac3f46a6914c3607b910e371a25dee) + +Related: RHEL-104135 +--- + src/coredump/coredump.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index d3a1f7c09d..db7f76f6c4 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -1458,6 +1458,11 @@ static int gather_pid_metadata_from_procfs(struct iovec_wrapper *iovw, Context * + if (get_process_environ(pid, &t) >= 0) + (void) iovw_put_string_field_free(iovw, "COREDUMP_ENVIRON=", t); + ++ /* Now that we have parsed info from /proc/ ensure the pidfd is still valid before continuing */ ++ r = pidref_verify(&context->pidref); ++ if (r < 0) ++ return log_error_errno(r, "PIDFD validation failed: %m"); ++ + /* we successfully acquired all metadata */ + return context_parse_iovw(context, iovw); + } diff --git a/0440-coredump-restore-compatibility-with-older-patterns.patch b/0440-coredump-restore-compatibility-with-older-patterns.patch new file mode 100644 index 0000000..a3a29a0 --- /dev/null +++ b/0440-coredump-restore-compatibility-with-older-patterns.patch @@ -0,0 +1,122 @@ +From 942d050f98cc0b6c89dbe30157163a8610cf7f78 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-104135 +--- + src/coredump/coredump.c | 23 +++++++++++++++-------- + test/units/TEST-74-AUX-UTILS.coredump.sh | 18 +++++++++++------- + 2 files changed, 26 insertions(+), 15 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index db7f76f6c4..58bcd4910f 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -105,8 +105,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 +@@ -117,7 +121,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, +@@ -1046,7 +1050,7 @@ static int context_parse_iovw(Context *context, 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]); + +@@ -1314,14 +1318,17 @@ static int gather_pid_metadata_from_argv( + assert(context); + + /* 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++) { + _cleanup_free_ char *buf = NULL; + const char *t = argv[i]; + +diff --git a/test/units/TEST-74-AUX-UTILS.coredump.sh b/test/units/TEST-74-AUX-UTILS.coredump.sh +index 2c084f54d2..8173a23162 100755 +--- a/test/units/TEST-74-AUX-UTILS.coredump.sh ++++ b/test/units/TEST-74-AUX-UTILS.coredump.sh +@@ -194,14 +194,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/0441-coredump-wrap-long-lines-fix-grammar-in-comments.patch b/0441-coredump-wrap-long-lines-fix-grammar-in-comments.patch new file mode 100644 index 0000000..100486a --- /dev/null +++ b/0441-coredump-wrap-long-lines-fix-grammar-in-comments.patch @@ -0,0 +1,123 @@ +From ad1453257d69a74bf8e47493394c601d733774de Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 21 May 2025 22:33:50 +0200 +Subject: [PATCH] coredump: wrap long lines, fix grammar in comments + +(cherry picked from commit c673f1f67aa44f99be5fdcb0dc22d7599776e5ed) + +Related: RHEL-104135 +--- + src/coredump/coredump.c | 34 ++++++++++++++++++---------------- + 1 file changed, 18 insertions(+), 16 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 58bcd4910f..c96b59b2f5 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -95,9 +95,9 @@ assert_cc(JOURNAL_SIZE_MAX <= DATA_SIZE_MAX); + enum { + /* We use these as array indexes for our process metadata cache. + * +- * The first indices of the cache stores the same metadata as the ones passed by +- * the kernel via argv[], ie the strings array passed by the kernel according to +- * our pattern defined in /proc/sys/kernel/core_pattern (see man:core(5)). */ ++ * The first indices of the cache stores the same metadata as the ones passed by the kernel via ++ * argv[], i.e. the strings specified in our pattern defined in /proc/sys/kernel/core_pattern, ++ * see core(5). */ + + META_ARGV_PID, /* %P: as seen in the initial pid namespace */ + META_ARGV_UID, /* %u: as seen in the initial user namespace */ +@@ -274,7 +274,6 @@ static int fix_acl(int fd, uid_t uid, bool allow_user) { + } + + 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", +@@ -1032,9 +1031,9 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + bool have_signal_name = false; + FOREACH_ARRAY(iovec, iovw->iovec, iovw->count) { + for (size_t i = 0; i < ELEMENTSOF(meta_field_names); i++) { +- /* Note that these strings are NUL terminated, because we made sure that a ++ /* 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_*()) */ ++ * count (see process_socket() and gather_pid_metadata_*()). */ + assert(((char*) iovec->iov_base)[iovec->iov_len] == 0); + + const char *p = memory_startswith(iovec->iov_base, iovec->iov_len, meta_field_names[i]); +@@ -1049,10 +1048,11 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + memory_startswith(iovec->iov_base, iovec->iov_len, "COREDUMP_SIGNAL_NAME="); + } + +- /* The basic fields from argv[] should always be there, refuse early if not */ ++ /* The basic fields from argv[] should always be there, refuse early if not. */ + 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]); ++ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), ++ "A required (%s) has not been sent, aborting.", meta_field_names[i]); + + pid_t parsed_pid; + r = parse_pid(context->meta[META_ARGV_PID], &parsed_pid); +@@ -1060,7 +1060,8 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + return log_error_errno(r, "Failed to parse PID \"%s\": %m", context->meta[META_ARGV_PID]); + if (pidref_is_set(&context->pidref)) { + if (context->pidref.pid != parsed_pid) +- return log_error_errno(r, "Passed PID " PID_FMT " does not match passed " PID_FMT ": %m", parsed_pid, context->pidref.pid); ++ return log_error_errno(r, "Passed PID " PID_FMT " does not match passed " PID_FMT ": %m", ++ parsed_pid, context->pidref.pid); + } else { + r = pidref_set_pid(&context->pidref, parsed_pid); + if (r < 0) +@@ -1158,7 +1159,8 @@ static int process_socket(int fd) { + * that's permissible for the final two fds. Hence let's be strict on the + * first fd, but lenient on the other two. */ + +- if (!cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, (socklen_t) -1) && state != STATE_PAYLOAD) /* no fds, and already got the first fd → we are done */ ++ if (!cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, (socklen_t) -1) && state != STATE_PAYLOAD) ++ /* No fds, and already got the first fd → we are done. */ + break; + + cmsg_close_all(&mh); +@@ -1350,7 +1352,7 @@ 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 */ ++ * access soon. */ + return context_parse_iovw(context, iovw); + } + +@@ -1465,12 +1467,12 @@ static int gather_pid_metadata_from_procfs(struct iovec_wrapper *iovw, Context * + if (get_process_environ(pid, &t) >= 0) + (void) iovw_put_string_field_free(iovw, "COREDUMP_ENVIRON=", t); + +- /* Now that we have parsed info from /proc/ ensure the pidfd is still valid before continuing */ ++ /* Now that we have parsed info from /proc/ ensure the pidfd is still valid before continuing. */ + r = pidref_verify(&context->pidref); + if (r < 0) + return log_error_errno(r, "PIDFD validation failed: %m"); + +- /* we successfully acquired all metadata */ ++ /* We successfully acquired all metadata. */ + return context_parse_iovw(context, iovw); + } + +@@ -1826,12 +1828,12 @@ static int process_kernel(int argc, char* argv[]) { + log_warning_errno(r, "Failed to access the mount tree of a container, ignoring: %m"); + } + +- /* If this is PID 1 disable coredump collection, we'll unlikely be able to process ++ /* If this is PID 1, disable coredump collection, we'll unlikely be able to process + * it later on. + * + * FIXME: maybe we should disable coredumps generation from the beginning and +- * re-enable it only when we know it's either safe (ie we're not running OOM) or +- * it's not pid1 ? */ ++ * re-enable it only when we know it's either safe (i.e. we're not running OOM) or ++ * it's not PID 1 ? */ + if (context.is_pid1) { + log_notice("Due to PID 1 having crashed coredump collection will now be turned off."); + disable_coredumps(); diff --git a/0442-coredump-get-rid-of-_META_MANDATORY_MAX.patch b/0442-coredump-get-rid-of-_META_MANDATORY_MAX.patch new file mode 100644 index 0000000..6c8f64d --- /dev/null +++ b/0442-coredump-get-rid-of-_META_MANDATORY_MAX.patch @@ -0,0 +1,94 @@ +From 6f678c43638caa6b0b349e56f0ded6d9c781a345 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 26 May 2025 12:04:44 +0200 +Subject: [PATCH] coredump: get rid of _META_MANDATORY_MAX + +No functional change. This change is done in preparation for future changes. +Currently, the list of fields which are received on the command line is a +strict subset of the fields which are always expected to be received on a +socket. But when we add new kernel args in the future, we'll have two +non-overlapping sets and this approach will not work. Get rid of the variable +and enumerate the required fields. This set will never change, so this is +actually more maintainable. + +The message with the hint where to add new fields is switched with +_META_ARGV_MAX. The new order is more correct. + +(cherry picked from commit 49f1f2d4a7612bbed5211a73d11d6a94fbe3bb69) + +Related: RHEL-104135 +--- + src/coredump/coredump.c | 29 +++++++++++++++++++++-------- + 1 file changed, 21 insertions(+), 8 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index c96b59b2f5..ac1e1cb9d3 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -92,7 +92,7 @@ assert_cc(JOURNAL_SIZE_MAX <= DATA_SIZE_MAX); + + #define MOUNT_TREE_ROOT "/run/systemd/mount-rootfs" + +-enum { ++typedef enum { + /* We use these as array indexes for our process metadata cache. + * + * The first indices of the cache stores the same metadata as the ones passed by the kernel via +@@ -108,9 +108,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_MAX, + /* If new fields are added, they should be added here, to maintain compatibility + * with callers which don't know about the new fields. */ ++ _META_ARGV_MAX, + + /* 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 +@@ -118,16 +118,15 @@ enum { + * environment. */ + + META_COMM = _META_ARGV_MAX, +- _META_MANDATORY_MAX, + + /* The rest are similar to the previous ones except that we won't fail if one of + * them is missing in a message sent over the socket. */ + +- META_EXE = _META_MANDATORY_MAX, ++ META_EXE, + META_UNIT, + META_PROC_AUXV, + _META_MAX +-}; ++} meta_argv_t; + + static const char * const meta_field_names[_META_MAX] = { + [META_ARGV_PID] = "COREDUMP_PID=", +@@ -1224,10 +1223,24 @@ static int process_socket(int fd) { + if (r < 0) + return r; + +- /* Make sure we received at least all fields we need. */ +- for (int i = 0; i < _META_MANDATORY_MAX; i++) ++ /* Make sure we received all the expected fields. We support being called by an *older* ++ * systemd-coredump from the outside, so we require only the basic set of fields that ++ * was being sent when the support for sending to containers over a socket was added ++ * in a108c43e36d3ceb6e34efe37c014fc2cda856000. */ ++ meta_argv_t i; ++ FOREACH_ARGUMENT(i, ++ META_ARGV_PID, ++ META_ARGV_UID, ++ META_ARGV_GID, ++ META_ARGV_SIGNAL, ++ META_ARGV_TIMESTAMP, ++ META_ARGV_RLIMIT, ++ META_ARGV_HOSTNAME, ++ META_COMM) + if (!context.meta[i]) +- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "A mandatory argument (%i) has not been sent, aborting.", i); ++ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), ++ "Mandatory argument %s not received on socket, aborting.", ++ meta_field_names[i]); + + return submit_coredump(&context, &iovw, input_fd); + } diff --git a/0443-coredump-use-d-in-kernel-core-pattern.patch b/0443-coredump-use-d-in-kernel-core-pattern.patch new file mode 100644 index 0000000..d193641 --- /dev/null +++ b/0443-coredump-use-d-in-kernel-core-pattern.patch @@ -0,0 +1,155 @@ +From 0ade63d15214fa8e184cc87522bfac9533be441b 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 + +(cherry picked from commit 0c49e0049b7665bb7769a13ef346fef92e1ad4d6) + +Related: RHEL-104135 +--- + man/systemd-coredump.xml | 12 ++++++++++++ + src/coredump/coredump.c | 21 ++++++++++++++++++--- + sysctl.d/50-coredump.conf.in | 2 +- + test/units/TEST-74-AUX-UTILS.coredump.sh | 5 +++++ + 4 files changed, 36 insertions(+), 4 deletions(-) + +diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml +index 737b80de9a..0f5ccf12f9 100644 +--- a/man/systemd-coredump.xml ++++ b/man/systemd-coredump.xml +@@ -292,6 +292,18 @@ 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 ac1e1cb9d3..19d4d02437 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -108,6 +108,7 @@ typedef 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 */ + /* If new fields are added, they should be added here, to maintain compatibility + * with callers which don't know about the new fields. */ + _META_ARGV_MAX, +@@ -136,6 +137,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=", +@@ -146,6 +148,7 @@ typedef struct Context { + PidRef pidref; + uid_t uid; + gid_t gid; ++ unsigned dumpable; + int signo; + uint64_t rlimit; + bool is_pid1; +@@ -433,14 +436,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 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; + } +@@ -1083,6 +1088,16 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + if (r < 0) + log_warning_errno(r, "Failed to parse resource limit \"%s\", ignoring: %m", context->meta[META_ARGV_RLIMIT]); + ++ /* 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 90c080bdfe..a550c87258 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=|{{LIBEXECDIR}}/systemd-coredump %P %u %g %s %t %c %h ++kernel.core_pattern=|{{LIBEXECDIR}}/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/TEST-74-AUX-UTILS.coredump.sh b/test/units/TEST-74-AUX-UTILS.coredump.sh +index 8173a23162..f157f97443 100755 +--- a/test/units/TEST-74-AUX-UTILS.coredump.sh ++++ b/test/units/TEST-74-AUX-UTILS.coredump.sh +@@ -201,12 +201,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/0444-coredump-also-stop-forwarding-non-dumpable-processes.patch b/0444-coredump-also-stop-forwarding-non-dumpable-processes.patch new file mode 100644 index 0000000..202f37a --- /dev/null +++ b/0444-coredump-also-stop-forwarding-non-dumpable-processes.patch @@ -0,0 +1,52 @@ +From 69d7d75a872d319b5fda048044238a735dce3834 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 5 May 2025 15:48:40 +0200 +Subject: [PATCH] coredump: also stop forwarding non-dumpable processes + +See the comment in the patch for details. + +Suggested-by: Qualys Security Advisory + +(cherry picked from commit 8fc7b2a211eb13ef1a94250b28e1c79cab8bdcb9) + +Related: RHEL-104135 +--- + src/coredump/coredump.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 19d4d02437..048eb53546 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -1560,10 +1560,21 @@ static int receive_ucred(int transport_fd, struct ucred *ret_ucred) { + return 0; + } + +-static int can_forward_coredump(pid_t pid) { ++static int can_forward_coredump(Context *context, pid_t pid) { + _cleanup_free_ char *cgroup = NULL, *path = NULL, *unit = NULL; + int r; + ++ assert(context); ++ ++ /* We don't use %F/pidfd to pin down the crashed process yet. We need to avoid a situation where the ++ * attacker crashes a SUID process or a root daemon and quickly replaces it with a namespaced process ++ * and we forward the initial part of the coredump to the attacker, inside the namespace. ++ * ++ * TODO: relax this check when %F is implemented and used. ++ */ ++ if (context->dumpable != 1) ++ return false; ++ + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup); + if (r < 0) + return r; +@@ -1607,7 +1618,7 @@ static int forward_coredump_to_container(Context *context) { + if (r < 0) + return log_debug_errno(r, "Failed to get namespace leader: %m"); + +- r = can_forward_coredump(leader_pid); ++ r = can_forward_coredump(context, leader_pid); + if (r < 0) + return log_debug_errno(r, "Failed to check if coredump can be forwarded: %m"); + if (r == 0) diff --git a/0445-coredump-get-rid-of-a-bogus-assertion.patch b/0445-coredump-get-rid-of-a-bogus-assertion.patch new file mode 100644 index 0000000..8c02eef --- /dev/null +++ b/0445-coredump-get-rid-of-a-bogus-assertion.patch @@ -0,0 +1,42 @@ +From cee91ba610d7ae7b80d32e487c79ea10c8fb98bc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 26 May 2025 15:24:04 +0200 +Subject: [PATCH] coredump: get rid of a bogus assertion + +The check looks plausible, but when I started checking whether it needs +to be lowered for the recent changes, I realized that it doesn't make +much sense. + +context_parse_iovw() is called from a few places, e.g.: +- process_socket(), where the other side controls the contents of the + message. We already do other checks on the correctness of the message + and this assert is not needed. +- gather_pid_metadata_from_argv(), which is called after + inserting MESSAGE_ID= and PRIORITY= into the array, so there is no + direct relation between _META_ARGV_MAX and the number of args in the + iovw. +- gather_pid_metadata_from_procfs(), where we insert a bazillion fields, + but without any relation to _META_ARGV_MAX. + +Since we already separately check if the required stuff was set, drop this +misleading check. + +(cherry picked from commit 13902e025321242b1d95c6d8b4e482b37f58cdef) + +Related: RHEL-104135 +--- + src/coredump/coredump.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 048eb53546..88cd1c394d 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -1027,7 +1027,6 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + + assert(context); + assert(iovw); +- assert(iovw->count >= _META_ARGV_MAX); + + /* Converts the data in the iovec array iovw into separate fields. Fills in context->meta[] (for + * which no memory is allocated, it just contains direct pointers into the iovec array memory). */ diff --git a/0446-coredump-add-support-for-new-F-PIDFD-specifier.patch b/0446-coredump-add-support-for-new-F-PIDFD-specifier.patch new file mode 100644 index 0000000..89eeace --- /dev/null +++ b/0446-coredump-add-support-for-new-F-PIDFD-specifier.patch @@ -0,0 +1,153 @@ +From 46e24959ecb9390f61403925bb1569c57ca375df 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) + +Related: RHEL-104135 +--- + man/systemd-coredump.xml | 11 +++++++ + src/coredump/coredump.c | 60 ++++++++++++++++++++++++++++++++++-- + sysctl.d/50-coredump.conf.in | 2 +- + 3 files changed, 70 insertions(+), 3 deletions(-) + +diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml +index 0f5ccf12f9..185497125c 100644 +--- a/man/systemd-coredump.xml ++++ b/man/systemd-coredump.xml +@@ -192,6 +192,17 @@ 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 88cd1c394d..940eb44528 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -109,6 +109,7 @@ typedef 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 */ + /* If new fields are added, they should be added here, to maintain compatibility + * with callers which don't know about the new fields. */ + _META_ARGV_MAX, +@@ -138,6 +139,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=", +@@ -1341,7 +1343,8 @@ static int gather_pid_metadata_from_argv( + Context *context, + int argc, char **argv) { + +- int r; ++ _cleanup_(pidref_done) PidRef local_pidref = PIDREF_NULL; ++ int r, kernel_fd = -EBADF; + + assert(iovw); + assert(context); +@@ -1373,6 +1376,47 @@ static int gather_pid_metadata_from_argv( + t = buf; + } + ++ 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(/* pid1 = */ 0, 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; +@@ -1380,7 +1424,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 context_parse_iovw(context, iovw); ++ r = context_parse_iovw(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_from_procfs(struct iovec_wrapper *iovw, Context *context) { +diff --git a/sysctl.d/50-coredump.conf.in b/sysctl.d/50-coredump.conf.in +index a550c87258..fe8f7670b0 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=|{{LIBEXECDIR}}/systemd-coredump %P %u %g %s %t %c %h %d ++kernel.core_pattern=|{{LIBEXECDIR}}/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/0447-coredump-when-F-pidfd-is-used-again-allow-forwarding.patch b/0447-coredump-when-F-pidfd-is-used-again-allow-forwarding.patch new file mode 100644 index 0000000..fe3e0ea --- /dev/null +++ b/0447-coredump-when-F-pidfd-is-used-again-allow-forwarding.patch @@ -0,0 +1,53 @@ +From 1a01ba0f895a8781908cfebfa1d74f326f6faacb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 27 May 2025 10:44:32 +0200 +Subject: [PATCH] coredump: when %F/pidfd is used, again allow forwarding to + containers + +(cherry picked from commit e6a8687b939ab21854f12f59a3cce703e32768cf) + +Related: RHEL-104135 +--- + src/coredump/coredump.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 940eb44528..67abc20ec5 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -155,6 +155,7 @@ typedef struct Context { + uint64_t rlimit; + bool is_pid1; + bool is_journald; ++ bool got_pidfd; + int mount_tree_fd; + + /* These point into external memory, are not owned by this object */ +@@ -1403,6 +1404,8 @@ static int gather_pid_metadata_from_argv( + if (r < 0) + return log_error_errno(r, "Failed to initialize pidref from pidfd %d: %m", kernel_fd); + ++ context->got_pidfd = 1; ++ + /* 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(/* pid1 = */ 0, context->pidref.pid, NAMESPACE_PID); +@@ -1621,13 +1624,11 @@ static int can_forward_coredump(Context *context, pid_t pid) { + + assert(context); + +- /* We don't use %F/pidfd to pin down the crashed process yet. We need to avoid a situation where the +- * attacker crashes a SUID process or a root daemon and quickly replaces it with a namespaced process +- * and we forward the initial part of the coredump to the attacker, inside the namespace. +- * +- * TODO: relax this check when %F is implemented and used. +- */ +- if (context->dumpable != 1) ++ /* We need to avoid a situation where the attacker crashes a SUID process or a root daemon and ++ * quickly replaces it with a namespaced process and we forward the coredump to the attacker, into ++ * the namespace. With %F/pidfd we can reliably check the namespace of the original process, hence we ++ * can allow forwarding. */ ++ if (!context->got_pidfd && context->dumpable != 1) + return false; + + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup); diff --git a/0448-coredump-introduce-an-enum-to-wrap-dumpable-constant.patch b/0448-coredump-introduce-an-enum-to-wrap-dumpable-constant.patch new file mode 100644 index 0000000..2bba4a2 --- /dev/null +++ b/0448-coredump-introduce-an-enum-to-wrap-dumpable-constant.patch @@ -0,0 +1,82 @@ +From 20b0f1e07885ffc887ac27f9dad164271b07581c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 27 May 2025 20:32:30 +0200 +Subject: [PATCH] coredump: introduce an enum to wrap dumpable constants + +Two constants are described in the man page, but are not defined by a header. +The third constant is described in the kernel docs. Use explicit values to +show that those are values are defined externally. + +(cherry picked from commit 76e0ab49c47965877c19772a2b3bf55f6417ca39) + +Related: RHEL-104135 +--- + src/coredump/coredump.c | 10 +++++----- + src/shared/coredump-util.h | 7 +++++++ + 2 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 67abc20ec5..7bde2f5196 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -442,7 +442,7 @@ static int grant_user_access(int core_fd, const Context *context) { + /* We allow access if 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 && ++ context->dumpable == SUID_DUMP_USER && + at_secure == 0 && + uid != UID_INVALID && euid != UID_INVALID && uid == euid && + gid != GID_INVALID && egid != GID_INVALID && gid == egid; +@@ -1090,13 +1090,13 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + if (r < 0) + log_warning_errno(r, "Failed to parse resource limit \"%s\", ignoring: %m", context->meta[META_ARGV_RLIMIT]); + +- /* The value is set to contents of /proc/sys/fs/suid_dumpable, which we set to 2, ++ /* The value is set to contents of /proc/sys/fs/suid_dumpable, which we set to SUID_DUMP_SAFE (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) ++ if (context->dumpable > SUID_DUMP_SAFE) + log_notice("Got unexpected %%d/dumpable value %u.", context->dumpable); + } + +@@ -1628,7 +1628,7 @@ static int can_forward_coredump(Context *context, pid_t pid) { + * quickly replaces it with a namespaced process and we forward the coredump to the attacker, into + * the namespace. With %F/pidfd we can reliably check the namespace of the original process, hence we + * can allow forwarding. */ +- if (!context->got_pidfd && context->dumpable != 1) ++ if (!context->got_pidfd && context->dumpable != SUID_DUMP_USER) + return false; + + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup); +@@ -2016,7 +2016,7 @@ static int run(int argc, char *argv[]) { + log_set_target_and_open(LOG_TARGET_KMSG); + + /* Make sure we never enter a loop */ +- (void) prctl(PR_SET_DUMPABLE, 0); ++ (void) prctl(PR_SET_DUMPABLE, SUID_DUMP_DISABLE); + + /* Ignore all parse errors */ + (void) parse_config(); +diff --git a/src/shared/coredump-util.h b/src/shared/coredump-util.h +index 4f54bb94c0..73c74c98c7 100644 +--- a/src/shared/coredump-util.h ++++ b/src/shared/coredump-util.h +@@ -25,6 +25,13 @@ typedef enum CoredumpFilter { + /* The kernel doesn't like UINT64_MAX and returns ERANGE, use UINT32_MAX to support future new flags */ + #define COREDUMP_FILTER_MASK_ALL UINT32_MAX + ++typedef enum SuidDumpMode { ++ SUID_DUMP_DISABLE = 0, /* PR_SET_DUMPABLE(2const) */ ++ SUID_DUMP_USER = 1, /* PR_SET_DUMPABLE(2const) */ ++ SUID_DUMP_SAFE = 2, /* https://www.kernel.org/doc/html/latest/admin-guide/sysctl/fs.html#suid-dumpable */ ++ _SUID_DUMP_MODE_MAX, ++} SuidDumpMode; ++ + const char* coredump_filter_to_string(CoredumpFilter i) _const_; + CoredumpFilter coredump_filter_from_string(const char *s) _pure_; + int coredump_filter_mask_from_string(const char *s, uint64_t *ret); diff --git a/0449-Define-helper-to-call-PR_SET_DUMPABLE.patch b/0449-Define-helper-to-call-PR_SET_DUMPABLE.patch new file mode 100644 index 0000000..1834dbc --- /dev/null +++ b/0449-Define-helper-to-call-PR_SET_DUMPABLE.patch @@ -0,0 +1,115 @@ +From 2271674c5776fa8308ad8d425e64246910366d2f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 28 May 2025 18:31:13 +0200 +Subject: [PATCH] Define helper to call PR_SET_DUMPABLE + +(cherry picked from commit 9ce8e3e449def92c75ada41b7d10c5bc3946be77) + +Related: RHEL-104135 +--- + src/coredump/coredump.c | 3 +-- + src/shared/coredump-util.c | 7 +++++++ + src/shared/coredump-util.h | 2 ++ + src/shared/elf-util.c | 4 ++-- + src/shared/tests.c | 1 + + 5 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 7bde2f5196..caec4bb76c 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -3,7 +3,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -2016,7 +2015,7 @@ static int run(int argc, char *argv[]) { + log_set_target_and_open(LOG_TARGET_KMSG); + + /* Make sure we never enter a loop */ +- (void) prctl(PR_SET_DUMPABLE, SUID_DUMP_DISABLE); ++ (void) set_dumpable(SUID_DUMP_DISABLE); + + /* Ignore all parse errors */ + (void) parse_config(); +diff --git a/src/shared/coredump-util.c b/src/shared/coredump-util.c +index 805503f366..0050e133c4 100644 +--- a/src/shared/coredump-util.c ++++ b/src/shared/coredump-util.c +@@ -1,14 +1,21 @@ + /* SPDX-License-Identifier: LGPL-2.1-or-later */ + + #include ++#include + + #include "coredump-util.h" ++#include "errno-util.h" + #include "extract-word.h" + #include "fileio.h" + #include "string-table.h" + #include "unaligned.h" + #include "virt.h" + ++int set_dumpable(SuidDumpMode mode) { ++ /* Cast mode explicitly to long, because prctl wants longs but is varargs. */ ++ return RET_NERRNO(prctl(PR_SET_DUMPABLE, (long) mode)); ++} ++ + static const char *const coredump_filter_table[_COREDUMP_FILTER_MAX] = { + [COREDUMP_FILTER_PRIVATE_ANONYMOUS] = "private-anonymous", + [COREDUMP_FILTER_SHARED_ANONYMOUS] = "shared-anonymous", +diff --git a/src/shared/coredump-util.h b/src/shared/coredump-util.h +index 73c74c98c7..b18cb33c84 100644 +--- a/src/shared/coredump-util.h ++++ b/src/shared/coredump-util.h +@@ -32,6 +32,8 @@ typedef enum SuidDumpMode { + _SUID_DUMP_MODE_MAX, + } SuidDumpMode; + ++int set_dumpable(SuidDumpMode mode); ++ + const char* coredump_filter_to_string(CoredumpFilter i) _const_; + CoredumpFilter coredump_filter_from_string(const char *s) _pure_; + int coredump_filter_mask_from_string(const char *s, uint64_t *ret); +diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c +index a3ff1fd3fb..ff8818de27 100644 +--- a/src/shared/elf-util.c ++++ b/src/shared/elf-util.c +@@ -6,12 +6,12 @@ + #include + #include + #include +-#include + #include + #include + #include + + #include "alloc-util.h" ++#include "coredump-util.h" + #include "dlfcn-util.h" + #include "elf-util.h" + #include "errno-util.h" +@@ -825,7 +825,7 @@ int parse_elf_object(int fd, const char *executable, const char *root, bool fork + if (r == 0) { + /* We want to avoid loops, given this can be called from systemd-coredump */ + if (fork_disable_dump) { +- r = RET_NERRNO(prctl(PR_SET_DUMPABLE, 0)); ++ r = set_dumpable(SUID_DUMP_DISABLE); + if (r < 0) + report_errno_and_exit(error_pipe[1], r); + } +diff --git a/src/shared/tests.c b/src/shared/tests.c +index 50b30ca17d..88031e90d9 100644 +--- a/src/shared/tests.c ++++ b/src/shared/tests.c +@@ -16,6 +16,7 @@ + #include "bus-wait-for-jobs.h" + #include "cgroup-setup.h" + #include "cgroup-util.h" ++#include "coredump-util.h" + #include "env-file.h" + #include "env-util.h" + #include "fd-util.h" diff --git a/0450-coredump-fix-0-passed-as-pointer-warning.patch b/0450-coredump-fix-0-passed-as-pointer-warning.patch new file mode 100644 index 0000000..0e0081f --- /dev/null +++ b/0450-coredump-fix-0-passed-as-pointer-warning.patch @@ -0,0 +1,25 @@ +From 35d4cb60dcfbb65359708a98c3474a8b3827f4a0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 6 Jun 2025 17:03:46 +0200 +Subject: [PATCH] coredump: fix 0-passed-as-pointer warning + +(cherry picked from commit 8ec2e177b01339ee940efd323361971acf027cc9) + +Related: RHEL-104135 +--- + src/coredump/coredump.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index caec4bb76c..412411bff7 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -217,7 +217,7 @@ static int parse_config(void) { + #if HAVE_DWFL_SET_SYSROOT + { "Coredump", "EnterNamespace", config_parse_bool, 0, &arg_enter_namespace }, + #else +- { "Coredump", "EnterNamespace", config_parse_warn_compat, DISABLED_CONFIGURATION, 0 }, ++ { "Coredump", "EnterNamespace", config_parse_warn_compat, DISABLED_CONFIGURATION, NULL }, + #endif + {} + }; diff --git a/0451-Revert-coredump-fix-0-passed-as-pointer-warning.patch b/0451-Revert-coredump-fix-0-passed-as-pointer-warning.patch new file mode 100644 index 0000000..1a18363 --- /dev/null +++ b/0451-Revert-coredump-fix-0-passed-as-pointer-warning.patch @@ -0,0 +1,25 @@ +From 40d1437d8aab83c50018decac472608b91f53e49 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 17:45:45 +0100 +Subject: [PATCH] Revert "coredump: fix 0-passed-as-pointer warning" + +This reverts commit 35d4cb60dcfbb65359708a98c3474a8b3827f4a0. + +Reverts: RHEL-104135 +--- + src/coredump/coredump.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 412411bff7..caec4bb76c 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -217,7 +217,7 @@ static int parse_config(void) { + #if HAVE_DWFL_SET_SYSROOT + { "Coredump", "EnterNamespace", config_parse_bool, 0, &arg_enter_namespace }, + #else +- { "Coredump", "EnterNamespace", config_parse_warn_compat, DISABLED_CONFIGURATION, NULL }, ++ { "Coredump", "EnterNamespace", config_parse_warn_compat, DISABLED_CONFIGURATION, 0 }, + #endif + {} + }; diff --git a/0452-Revert-Define-helper-to-call-PR_SET_DUMPABLE.patch b/0452-Revert-Define-helper-to-call-PR_SET_DUMPABLE.patch new file mode 100644 index 0000000..12888bc --- /dev/null +++ b/0452-Revert-Define-helper-to-call-PR_SET_DUMPABLE.patch @@ -0,0 +1,115 @@ +From e6fad9f1bcdf98fe8636b1f41da55afd75a0832d Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 17:45:45 +0100 +Subject: [PATCH] Revert "Define helper to call PR_SET_DUMPABLE" + +This reverts commit 2271674c5776fa8308ad8d425e64246910366d2f. + +Reverts: RHEL-104135 +--- + src/coredump/coredump.c | 3 ++- + src/shared/coredump-util.c | 7 ------- + src/shared/coredump-util.h | 2 -- + src/shared/elf-util.c | 4 ++-- + src/shared/tests.c | 1 - + 5 files changed, 4 insertions(+), 13 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index caec4bb76c..7bde2f5196 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2015,7 +2016,7 @@ static int run(int argc, char *argv[]) { + log_set_target_and_open(LOG_TARGET_KMSG); + + /* Make sure we never enter a loop */ +- (void) set_dumpable(SUID_DUMP_DISABLE); ++ (void) prctl(PR_SET_DUMPABLE, SUID_DUMP_DISABLE); + + /* Ignore all parse errors */ + (void) parse_config(); +diff --git a/src/shared/coredump-util.c b/src/shared/coredump-util.c +index 0050e133c4..805503f366 100644 +--- a/src/shared/coredump-util.c ++++ b/src/shared/coredump-util.c +@@ -1,21 +1,14 @@ + /* SPDX-License-Identifier: LGPL-2.1-or-later */ + + #include +-#include + + #include "coredump-util.h" +-#include "errno-util.h" + #include "extract-word.h" + #include "fileio.h" + #include "string-table.h" + #include "unaligned.h" + #include "virt.h" + +-int set_dumpable(SuidDumpMode mode) { +- /* Cast mode explicitly to long, because prctl wants longs but is varargs. */ +- return RET_NERRNO(prctl(PR_SET_DUMPABLE, (long) mode)); +-} +- + static const char *const coredump_filter_table[_COREDUMP_FILTER_MAX] = { + [COREDUMP_FILTER_PRIVATE_ANONYMOUS] = "private-anonymous", + [COREDUMP_FILTER_SHARED_ANONYMOUS] = "shared-anonymous", +diff --git a/src/shared/coredump-util.h b/src/shared/coredump-util.h +index b18cb33c84..73c74c98c7 100644 +--- a/src/shared/coredump-util.h ++++ b/src/shared/coredump-util.h +@@ -32,8 +32,6 @@ typedef enum SuidDumpMode { + _SUID_DUMP_MODE_MAX, + } SuidDumpMode; + +-int set_dumpable(SuidDumpMode mode); +- + const char* coredump_filter_to_string(CoredumpFilter i) _const_; + CoredumpFilter coredump_filter_from_string(const char *s) _pure_; + int coredump_filter_mask_from_string(const char *s, uint64_t *ret); +diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c +index ff8818de27..a3ff1fd3fb 100644 +--- a/src/shared/elf-util.c ++++ b/src/shared/elf-util.c +@@ -6,12 +6,12 @@ + #include + #include + #include ++#include + #include + #include + #include + + #include "alloc-util.h" +-#include "coredump-util.h" + #include "dlfcn-util.h" + #include "elf-util.h" + #include "errno-util.h" +@@ -825,7 +825,7 @@ int parse_elf_object(int fd, const char *executable, const char *root, bool fork + if (r == 0) { + /* We want to avoid loops, given this can be called from systemd-coredump */ + if (fork_disable_dump) { +- r = set_dumpable(SUID_DUMP_DISABLE); ++ r = RET_NERRNO(prctl(PR_SET_DUMPABLE, 0)); + if (r < 0) + report_errno_and_exit(error_pipe[1], r); + } +diff --git a/src/shared/tests.c b/src/shared/tests.c +index 88031e90d9..50b30ca17d 100644 +--- a/src/shared/tests.c ++++ b/src/shared/tests.c +@@ -16,7 +16,6 @@ + #include "bus-wait-for-jobs.h" + #include "cgroup-setup.h" + #include "cgroup-util.h" +-#include "coredump-util.h" + #include "env-file.h" + #include "env-util.h" + #include "fd-util.h" diff --git a/0453-Revert-coredump-introduce-an-enum-to-wrap-dumpable-c.patch b/0453-Revert-coredump-introduce-an-enum-to-wrap-dumpable-c.patch new file mode 100644 index 0000000..68333d0 --- /dev/null +++ b/0453-Revert-coredump-introduce-an-enum-to-wrap-dumpable-c.patch @@ -0,0 +1,79 @@ +From b00298da67577bd432df17ab640ab36b37e03d74 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 17:45:45 +0100 +Subject: [PATCH] Revert "coredump: introduce an enum to wrap dumpable + constants" + +This reverts commit 20b0f1e07885ffc887ac27f9dad164271b07581c. + +Reverts: RHEL-104135 +--- + src/coredump/coredump.c | 10 +++++----- + src/shared/coredump-util.h | 7 ------- + 2 files changed, 5 insertions(+), 12 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 7bde2f5196..67abc20ec5 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -442,7 +442,7 @@ static int grant_user_access(int core_fd, const Context *context) { + /* We allow access if 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 == SUID_DUMP_USER && ++ context->dumpable == 1 && + at_secure == 0 && + uid != UID_INVALID && euid != UID_INVALID && uid == euid && + gid != GID_INVALID && egid != GID_INVALID && gid == egid; +@@ -1090,13 +1090,13 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + if (r < 0) + log_warning_errno(r, "Failed to parse resource limit \"%s\", ignoring: %m", context->meta[META_ARGV_RLIMIT]); + +- /* The value is set to contents of /proc/sys/fs/suid_dumpable, which we set to SUID_DUMP_SAFE (2), ++ /* 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 > SUID_DUMP_SAFE) ++ if (context->dumpable > 2) + log_notice("Got unexpected %%d/dumpable value %u.", context->dumpable); + } + +@@ -1628,7 +1628,7 @@ static int can_forward_coredump(Context *context, pid_t pid) { + * quickly replaces it with a namespaced process and we forward the coredump to the attacker, into + * the namespace. With %F/pidfd we can reliably check the namespace of the original process, hence we + * can allow forwarding. */ +- if (!context->got_pidfd && context->dumpable != SUID_DUMP_USER) ++ if (!context->got_pidfd && context->dumpable != 1) + return false; + + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup); +@@ -2016,7 +2016,7 @@ static int run(int argc, char *argv[]) { + log_set_target_and_open(LOG_TARGET_KMSG); + + /* Make sure we never enter a loop */ +- (void) prctl(PR_SET_DUMPABLE, SUID_DUMP_DISABLE); ++ (void) prctl(PR_SET_DUMPABLE, 0); + + /* Ignore all parse errors */ + (void) parse_config(); +diff --git a/src/shared/coredump-util.h b/src/shared/coredump-util.h +index 73c74c98c7..4f54bb94c0 100644 +--- a/src/shared/coredump-util.h ++++ b/src/shared/coredump-util.h +@@ -25,13 +25,6 @@ typedef enum CoredumpFilter { + /* The kernel doesn't like UINT64_MAX and returns ERANGE, use UINT32_MAX to support future new flags */ + #define COREDUMP_FILTER_MASK_ALL UINT32_MAX + +-typedef enum SuidDumpMode { +- SUID_DUMP_DISABLE = 0, /* PR_SET_DUMPABLE(2const) */ +- SUID_DUMP_USER = 1, /* PR_SET_DUMPABLE(2const) */ +- SUID_DUMP_SAFE = 2, /* https://www.kernel.org/doc/html/latest/admin-guide/sysctl/fs.html#suid-dumpable */ +- _SUID_DUMP_MODE_MAX, +-} SuidDumpMode; +- + const char* coredump_filter_to_string(CoredumpFilter i) _const_; + CoredumpFilter coredump_filter_from_string(const char *s) _pure_; + int coredump_filter_mask_from_string(const char *s, uint64_t *ret); diff --git a/0454-Revert-coredump-when-F-pidfd-is-used-again-allow-for.patch b/0454-Revert-coredump-when-F-pidfd-is-used-again-allow-for.patch new file mode 100644 index 0000000..e6ee1df --- /dev/null +++ b/0454-Revert-coredump-when-F-pidfd-is-used-again-allow-for.patch @@ -0,0 +1,53 @@ +From dd0b6f16a367e8b1e5fb97233fb1c2099d0c4629 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 17:45:45 +0100 +Subject: [PATCH] Revert "coredump: when %F/pidfd is used, again allow + forwarding to containers" + +This reverts commit 1a01ba0f895a8781908cfebfa1d74f326f6faacb. + +Reverts: RHEL-104135 +--- + src/coredump/coredump.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 67abc20ec5..940eb44528 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -155,7 +155,6 @@ typedef struct Context { + uint64_t rlimit; + bool is_pid1; + bool is_journald; +- bool got_pidfd; + int mount_tree_fd; + + /* These point into external memory, are not owned by this object */ +@@ -1404,8 +1403,6 @@ static int gather_pid_metadata_from_argv( + if (r < 0) + return log_error_errno(r, "Failed to initialize pidref from pidfd %d: %m", kernel_fd); + +- context->got_pidfd = 1; +- + /* 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(/* pid1 = */ 0, context->pidref.pid, NAMESPACE_PID); +@@ -1624,11 +1621,13 @@ static int can_forward_coredump(Context *context, pid_t pid) { + + assert(context); + +- /* We need to avoid a situation where the attacker crashes a SUID process or a root daemon and +- * quickly replaces it with a namespaced process and we forward the coredump to the attacker, into +- * the namespace. With %F/pidfd we can reliably check the namespace of the original process, hence we +- * can allow forwarding. */ +- if (!context->got_pidfd && context->dumpable != 1) ++ /* We don't use %F/pidfd to pin down the crashed process yet. We need to avoid a situation where the ++ * attacker crashes a SUID process or a root daemon and quickly replaces it with a namespaced process ++ * and we forward the initial part of the coredump to the attacker, inside the namespace. ++ * ++ * TODO: relax this check when %F is implemented and used. ++ */ ++ if (context->dumpable != 1) + return false; + + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup); diff --git a/0455-Revert-coredump-add-support-for-new-F-PIDFD-specifie.patch b/0455-Revert-coredump-add-support-for-new-F-PIDFD-specifie.patch new file mode 100644 index 0000000..9e936ec --- /dev/null +++ b/0455-Revert-coredump-add-support-for-new-F-PIDFD-specifie.patch @@ -0,0 +1,148 @@ +From 8655b93872dc5d5468042164e71c117813a680e8 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 17:45:45 +0100 +Subject: [PATCH] Revert "coredump: add support for new %F PIDFD specifier" + +This reverts commit 46e24959ecb9390f61403925bb1569c57ca375df. + +Reverts: RHEL-104135 +--- + man/systemd-coredump.xml | 11 ------- + src/coredump/coredump.c | 60 ++---------------------------------- + sysctl.d/50-coredump.conf.in | 2 +- + 3 files changed, 3 insertions(+), 70 deletions(-) + +diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml +index 185497125c..0f5ccf12f9 100644 +--- a/man/systemd-coredump.xml ++++ b/man/systemd-coredump.xml +@@ -192,17 +192,6 @@ 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 940eb44528..88cd1c394d 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -109,7 +109,6 @@ typedef 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 */ + /* If new fields are added, they should be added here, to maintain compatibility + * with callers which don't know about the new fields. */ + _META_ARGV_MAX, +@@ -139,7 +138,6 @@ 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=", +@@ -1343,8 +1341,7 @@ static int gather_pid_metadata_from_argv( + Context *context, + int argc, char **argv) { + +- _cleanup_(pidref_done) PidRef local_pidref = PIDREF_NULL; +- int r, kernel_fd = -EBADF; ++ int r; + + assert(iovw); + assert(context); +@@ -1376,47 +1373,6 @@ static int gather_pid_metadata_from_argv( + t = buf; + } + +- 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(/* pid1 = */ 0, 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; +@@ -1424,19 +1380,7 @@ 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. */ +- r = context_parse_iovw(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; ++ return context_parse_iovw(context, iovw); + } + + static int gather_pid_metadata_from_procfs(struct iovec_wrapper *iovw, Context *context) { +diff --git a/sysctl.d/50-coredump.conf.in b/sysctl.d/50-coredump.conf.in +index fe8f7670b0..a550c87258 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=|{{LIBEXECDIR}}/systemd-coredump %P %u %g %s %t %c %h %d %F ++kernel.core_pattern=|{{LIBEXECDIR}}/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/0456-Revert-coredump-get-rid-of-a-bogus-assertion.patch b/0456-Revert-coredump-get-rid-of-a-bogus-assertion.patch new file mode 100644 index 0000000..3e891d7 --- /dev/null +++ b/0456-Revert-coredump-get-rid-of-a-bogus-assertion.patch @@ -0,0 +1,24 @@ +From 41f7b831986b1eda992ea40081ec9d7fe6157e41 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 17:45:45 +0100 +Subject: [PATCH] Revert "coredump: get rid of a bogus assertion" + +This reverts commit cee91ba610d7ae7b80d32e487c79ea10c8fb98bc. + +Reverts: RHEL-104135 +--- + src/coredump/coredump.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 88cd1c394d..048eb53546 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -1027,6 +1027,7 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + + assert(context); + assert(iovw); ++ assert(iovw->count >= _META_ARGV_MAX); + + /* Converts the data in the iovec array iovw into separate fields. Fills in context->meta[] (for + * which no memory is allocated, it just contains direct pointers into the iovec array memory). */ diff --git a/0457-Revert-coredump-also-stop-forwarding-non-dumpable-pr.patch b/0457-Revert-coredump-also-stop-forwarding-non-dumpable-pr.patch new file mode 100644 index 0000000..5458889 --- /dev/null +++ b/0457-Revert-coredump-also-stop-forwarding-non-dumpable-pr.patch @@ -0,0 +1,49 @@ +From 5281235691ff5b64702d9cfb3f704fd069c6169d Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 17:45:45 +0100 +Subject: [PATCH] Revert "coredump: also stop forwarding non-dumpable + processes" + +This reverts commit 69d7d75a872d319b5fda048044238a735dce3834. + +Reverts: RHEL-104135 +--- + src/coredump/coredump.c | 15 ++------------- + 1 file changed, 2 insertions(+), 13 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 048eb53546..19d4d02437 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -1560,21 +1560,10 @@ static int receive_ucred(int transport_fd, struct ucred *ret_ucred) { + return 0; + } + +-static int can_forward_coredump(Context *context, pid_t pid) { ++static int can_forward_coredump(pid_t pid) { + _cleanup_free_ char *cgroup = NULL, *path = NULL, *unit = NULL; + int r; + +- assert(context); +- +- /* We don't use %F/pidfd to pin down the crashed process yet. We need to avoid a situation where the +- * attacker crashes a SUID process or a root daemon and quickly replaces it with a namespaced process +- * and we forward the initial part of the coredump to the attacker, inside the namespace. +- * +- * TODO: relax this check when %F is implemented and used. +- */ +- if (context->dumpable != 1) +- return false; +- + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup); + if (r < 0) + return r; +@@ -1618,7 +1607,7 @@ static int forward_coredump_to_container(Context *context) { + if (r < 0) + return log_debug_errno(r, "Failed to get namespace leader: %m"); + +- r = can_forward_coredump(context, leader_pid); ++ r = can_forward_coredump(leader_pid); + if (r < 0) + return log_debug_errno(r, "Failed to check if coredump can be forwarded: %m"); + if (r == 0) diff --git a/0458-Revert-coredump-use-d-in-kernel-core-pattern.patch b/0458-Revert-coredump-use-d-in-kernel-core-pattern.patch new file mode 100644 index 0000000..d53a43d --- /dev/null +++ b/0458-Revert-coredump-use-d-in-kernel-core-pattern.patch @@ -0,0 +1,138 @@ +From cfb8f2d6b759ae93827908afccc18b2b8c3ccc4b Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 17:45:45 +0100 +Subject: [PATCH] Revert "coredump: use %d in kernel core pattern" + +This reverts commit 0ade63d15214fa8e184cc87522bfac9533be441b. + +Reverts: RHEL-104135 +--- + man/systemd-coredump.xml | 12 ------------ + src/coredump/coredump.c | 21 +++------------------ + sysctl.d/50-coredump.conf.in | 2 +- + test/units/TEST-74-AUX-UTILS.coredump.sh | 5 ----- + 4 files changed, 4 insertions(+), 36 deletions(-) + +diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml +index 0f5ccf12f9..737b80de9a 100644 +--- a/man/systemd-coredump.xml ++++ b/man/systemd-coredump.xml +@@ -292,18 +292,6 @@ 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 19d4d02437..ac1e1cb9d3 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -108,7 +108,6 @@ typedef 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 */ + /* If new fields are added, they should be added here, to maintain compatibility + * with callers which don't know about the new fields. */ + _META_ARGV_MAX, +@@ -137,7 +136,6 @@ 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=", +@@ -148,7 +146,6 @@ typedef struct Context { + PidRef pidref; + uid_t uid; + gid_t gid; +- unsigned dumpable; + int signo; + uint64_t rlimit; + bool is_pid1; +@@ -436,16 +433,14 @@ static int grant_user_access(int core_fd, const Context *context) { + if (r < 0) + return r; + +- /* We allow access if 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. */ ++ /* We allow access if we got all the data and at_secure is not set and ++ * the uid/gid matches 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 (dumpable=%u uid="UID_FMT " euid="UID_FMT " gid="GID_FMT " egid="GID_FMT " at_secure=%s)", ++ log_debug("Will %s access (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; + } +@@ -1088,16 +1083,6 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + if (r < 0) + log_warning_errno(r, "Failed to parse resource limit \"%s\", ignoring: %m", context->meta[META_ARGV_RLIMIT]); + +- /* 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 a550c87258..90c080bdfe 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=|{{LIBEXECDIR}}/systemd-coredump %P %u %g %s %t %c %h %d ++kernel.core_pattern=|{{LIBEXECDIR}}/systemd-coredump %P %u %g %s %t %c %h + + # 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/TEST-74-AUX-UTILS.coredump.sh b/test/units/TEST-74-AUX-UTILS.coredump.sh +index f157f97443..8173a23162 100755 +--- a/test/units/TEST-74-AUX-UTILS.coredump.sh ++++ b/test/units/TEST-74-AUX-UTILS.coredump.sh +@@ -201,17 +201,12 @@ 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/0459-Revert-coredump-get-rid-of-_META_MANDATORY_MAX.patch b/0459-Revert-coredump-get-rid-of-_META_MANDATORY_MAX.patch new file mode 100644 index 0000000..76d0214 --- /dev/null +++ b/0459-Revert-coredump-get-rid-of-_META_MANDATORY_MAX.patch @@ -0,0 +1,83 @@ +From 52ec2f34b8313eab2dd6a0eeadec2720d43fa3f1 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 17:45:45 +0100 +Subject: [PATCH] Revert "coredump: get rid of _META_MANDATORY_MAX" + +This reverts commit 6f678c43638caa6b0b349e56f0ded6d9c781a345. + +Reverts: RHEL-104135 +--- + src/coredump/coredump.c | 29 ++++++++--------------------- + 1 file changed, 8 insertions(+), 21 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index ac1e1cb9d3..c96b59b2f5 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -92,7 +92,7 @@ assert_cc(JOURNAL_SIZE_MAX <= DATA_SIZE_MAX); + + #define MOUNT_TREE_ROOT "/run/systemd/mount-rootfs" + +-typedef enum { ++enum { + /* We use these as array indexes for our process metadata cache. + * + * The first indices of the cache stores the same metadata as the ones passed by the kernel via +@@ -108,9 +108,9 @@ typedef 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_MAX, + /* If new fields are added, they should be added here, to maintain compatibility + * with callers which don't know about the new fields. */ +- _META_ARGV_MAX, + + /* 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 +@@ -118,15 +118,16 @@ typedef enum { + * environment. */ + + META_COMM = _META_ARGV_MAX, ++ _META_MANDATORY_MAX, + + /* The rest are similar to the previous ones except that we won't fail if one of + * them is missing in a message sent over the socket. */ + +- META_EXE, ++ META_EXE = _META_MANDATORY_MAX, + META_UNIT, + META_PROC_AUXV, + _META_MAX +-} meta_argv_t; ++}; + + static const char * const meta_field_names[_META_MAX] = { + [META_ARGV_PID] = "COREDUMP_PID=", +@@ -1223,24 +1224,10 @@ static int process_socket(int fd) { + if (r < 0) + return r; + +- /* Make sure we received all the expected fields. We support being called by an *older* +- * systemd-coredump from the outside, so we require only the basic set of fields that +- * was being sent when the support for sending to containers over a socket was added +- * in a108c43e36d3ceb6e34efe37c014fc2cda856000. */ +- meta_argv_t i; +- FOREACH_ARGUMENT(i, +- META_ARGV_PID, +- META_ARGV_UID, +- META_ARGV_GID, +- META_ARGV_SIGNAL, +- META_ARGV_TIMESTAMP, +- META_ARGV_RLIMIT, +- META_ARGV_HOSTNAME, +- META_COMM) ++ /* Make sure we received at least all fields we need. */ ++ for (int i = 0; i < _META_MANDATORY_MAX; i++) + if (!context.meta[i]) +- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), +- "Mandatory argument %s not received on socket, aborting.", +- meta_field_names[i]); ++ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "A mandatory argument (%i) has not been sent, aborting.", i); + + return submit_coredump(&context, &iovw, input_fd); + } diff --git a/0460-Revert-coredump-wrap-long-lines-fix-grammar-in-comme.patch b/0460-Revert-coredump-wrap-long-lines-fix-grammar-in-comme.patch new file mode 100644 index 0000000..f4f4853 --- /dev/null +++ b/0460-Revert-coredump-wrap-long-lines-fix-grammar-in-comme.patch @@ -0,0 +1,123 @@ +From 6474cfc2bd0274be6ee9de8cd8cebeee49e3073d Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 17:45:45 +0100 +Subject: [PATCH] Revert "coredump: wrap long lines, fix grammar in comments" + +This reverts commit ad1453257d69a74bf8e47493394c601d733774de. + +Reverts: RHEL-104135 +--- + src/coredump/coredump.c | 34 ++++++++++++++++------------------ + 1 file changed, 16 insertions(+), 18 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index c96b59b2f5..58bcd4910f 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -95,9 +95,9 @@ assert_cc(JOURNAL_SIZE_MAX <= DATA_SIZE_MAX); + enum { + /* We use these as array indexes for our process metadata cache. + * +- * The first indices of the cache stores the same metadata as the ones passed by the kernel via +- * argv[], i.e. the strings specified in our pattern defined in /proc/sys/kernel/core_pattern, +- * see core(5). */ ++ * The first indices of the cache stores the same metadata as the ones passed by ++ * the kernel via argv[], ie the strings array passed by the kernel according to ++ * our pattern defined in /proc/sys/kernel/core_pattern (see man:core(5)). */ + + META_ARGV_PID, /* %P: as seen in the initial pid namespace */ + META_ARGV_UID, /* %u: as seen in the initial user namespace */ +@@ -274,6 +274,7 @@ static int fix_acl(int fd, uid_t uid, bool allow_user) { + } + + 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", +@@ -1031,9 +1032,9 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + bool have_signal_name = false; + FOREACH_ARRAY(iovec, iovw->iovec, iovw->count) { + for (size_t i = 0; i < ELEMENTSOF(meta_field_names); i++) { +- /* Note that these strings are NUL-terminated, because we made sure that a ++ /* 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_*()). */ ++ * count (see process_socket() and gather_pid_metadata_*()) */ + assert(((char*) iovec->iov_base)[iovec->iov_len] == 0); + + const char *p = memory_startswith(iovec->iov_base, iovec->iov_len, meta_field_names[i]); +@@ -1048,11 +1049,10 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + memory_startswith(iovec->iov_base, iovec->iov_len, "COREDUMP_SIGNAL_NAME="); + } + +- /* The basic fields from argv[] should always be there, refuse early if not. */ ++ /* The basic fields from argv[] should always be there, refuse early if not */ + 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]); ++ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "A required (%s) has not been sent, aborting.", meta_field_names[i]); + + pid_t parsed_pid; + r = parse_pid(context->meta[META_ARGV_PID], &parsed_pid); +@@ -1060,8 +1060,7 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + return log_error_errno(r, "Failed to parse PID \"%s\": %m", context->meta[META_ARGV_PID]); + if (pidref_is_set(&context->pidref)) { + if (context->pidref.pid != parsed_pid) +- return log_error_errno(r, "Passed PID " PID_FMT " does not match passed " PID_FMT ": %m", +- parsed_pid, context->pidref.pid); ++ return log_error_errno(r, "Passed PID " PID_FMT " does not match passed " PID_FMT ": %m", parsed_pid, context->pidref.pid); + } else { + r = pidref_set_pid(&context->pidref, parsed_pid); + if (r < 0) +@@ -1159,8 +1158,7 @@ static int process_socket(int fd) { + * that's permissible for the final two fds. Hence let's be strict on the + * first fd, but lenient on the other two. */ + +- if (!cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, (socklen_t) -1) && state != STATE_PAYLOAD) +- /* No fds, and already got the first fd → we are done. */ ++ if (!cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, (socklen_t) -1) && state != STATE_PAYLOAD) /* no fds, and already got the first fd → we are done */ + break; + + cmsg_close_all(&mh); +@@ -1352,7 +1350,7 @@ 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. */ ++ * access soon */ + return context_parse_iovw(context, iovw); + } + +@@ -1467,12 +1465,12 @@ static int gather_pid_metadata_from_procfs(struct iovec_wrapper *iovw, Context * + if (get_process_environ(pid, &t) >= 0) + (void) iovw_put_string_field_free(iovw, "COREDUMP_ENVIRON=", t); + +- /* Now that we have parsed info from /proc/ ensure the pidfd is still valid before continuing. */ ++ /* Now that we have parsed info from /proc/ ensure the pidfd is still valid before continuing */ + r = pidref_verify(&context->pidref); + if (r < 0) + return log_error_errno(r, "PIDFD validation failed: %m"); + +- /* We successfully acquired all metadata. */ ++ /* we successfully acquired all metadata */ + return context_parse_iovw(context, iovw); + } + +@@ -1828,12 +1826,12 @@ static int process_kernel(int argc, char* argv[]) { + log_warning_errno(r, "Failed to access the mount tree of a container, ignoring: %m"); + } + +- /* If this is PID 1, disable coredump collection, we'll unlikely be able to process ++ /* If this is PID 1 disable coredump collection, we'll unlikely be able to process + * it later on. + * + * FIXME: maybe we should disable coredumps generation from the beginning and +- * re-enable it only when we know it's either safe (i.e. we're not running OOM) or +- * it's not PID 1 ? */ ++ * re-enable it only when we know it's either safe (ie we're not running OOM) or ++ * it's not pid1 ? */ + if (context.is_pid1) { + log_notice("Due to PID 1 having crashed coredump collection will now be turned off."); + disable_coredumps(); diff --git a/0461-Revert-coredump-restore-compatibility-with-older-pat.patch b/0461-Revert-coredump-restore-compatibility-with-older-pat.patch new file mode 100644 index 0000000..fdeb214 --- /dev/null +++ b/0461-Revert-coredump-restore-compatibility-with-older-pat.patch @@ -0,0 +1,102 @@ +From 1e9bb0d1a4a8c4fba9bb2f9a4282c4f71a8475b7 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 17:45:45 +0100 +Subject: [PATCH] Revert "coredump: restore compatibility with older patterns" + +This reverts commit 942d050f98cc0b6c89dbe30157163a8610cf7f78. + +Reverts: RHEL-104135 +--- + src/coredump/coredump.c | 23 ++++++++--------------- + test/units/TEST-74-AUX-UTILS.coredump.sh | 18 +++++++----------- + 2 files changed, 15 insertions(+), 26 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 58bcd4910f..db7f76f6c4 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -105,12 +105,8 @@ 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_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_HOSTNAME, /* %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 +@@ -121,7 +117,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 in a message sent over the socket. */ ++ * them is missing. */ + + META_EXE = _META_MANDATORY_MAX, + META_UNIT, +@@ -1050,7 +1046,7 @@ static int context_parse_iovw(Context *context, struct iovec_wrapper *iovw) { + } + + /* The basic fields from argv[] should always be there, refuse early if not */ +- for (int i = 0; i < _META_ARGV_REQUIRED; i++) ++ 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]); + +@@ -1318,17 +1314,14 @@ static int gather_pid_metadata_from_argv( + assert(context); + + /* We gather all metadata that were passed via argv[] into an array of iovecs that +- * 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. */ ++ * we'll forward to the socket unit */ + +- if (argc < _META_ARGV_REQUIRED) ++ if (argc < _META_ARGV_MAX) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), +- "Not enough arguments passed by the kernel (%i, expected between %i and %i).", +- argc, _META_ARGV_REQUIRED, _META_ARGV_MAX); ++ "Not enough arguments passed by the kernel (%i, expected %i).", ++ argc, _META_ARGV_MAX); + +- for (int i = 0; i < MIN(argc, _META_ARGV_MAX); i++) { ++ for (int i = 0; i < _META_ARGV_MAX; i++) { + _cleanup_free_ char *buf = NULL; + const char *t = argv[i]; + +diff --git a/test/units/TEST-74-AUX-UTILS.coredump.sh b/test/units/TEST-74-AUX-UTILS.coredump.sh +index 8173a23162..2c084f54d2 100755 +--- a/test/units/TEST-74-AUX-UTILS.coredump.sh ++++ b/test/units/TEST-74-AUX-UTILS.coredump.sh +@@ -194,18 +194,14 @@ 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. +-# 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] ++# 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 + 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 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 ++ /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 "$$" + coredumpctl info COREDUMP_HOSTNAME="mymachine" + + # This used to cause a stack overflow diff --git a/0462-Revert-coredump-verify-pidfd-after-parsing-data-in-u.patch b/0462-Revert-coredump-verify-pidfd-after-parsing-data-in-u.patch new file mode 100644 index 0000000..99cca19 --- /dev/null +++ b/0462-Revert-coredump-verify-pidfd-after-parsing-data-in-u.patch @@ -0,0 +1,29 @@ +From 38b2ad72c1926c45790e678ce8c6207b3a93b2e5 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 17:45:45 +0100 +Subject: [PATCH] Revert "coredump: verify pidfd after parsing data in usermode + helper" + +This reverts commit ae1394abcded51ed5e443d1124059b2e31748baa. + +Reverts: RHEL-104135 +--- + src/coredump/coredump.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index db7f76f6c4..d3a1f7c09d 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -1458,11 +1458,6 @@ static int gather_pid_metadata_from_procfs(struct iovec_wrapper *iovw, Context * + if (get_process_environ(pid, &t) >= 0) + (void) iovw_put_string_field_free(iovw, "COREDUMP_ENVIRON=", t); + +- /* Now that we have parsed info from /proc/ ensure the pidfd is still valid before continuing */ +- r = pidref_verify(&context->pidref); +- if (r < 0) +- return log_error_errno(r, "PIDFD validation failed: %m"); +- + /* we successfully acquired all metadata */ + return context_parse_iovw(context, iovw); + } diff --git a/0463-ci-re-enable-bpf-framework-option-for-build-and-unit.patch b/0463-ci-re-enable-bpf-framework-option-for-build-and-unit.patch new file mode 100644 index 0000000..c467682 --- /dev/null +++ b/0463-ci-re-enable-bpf-framework-option-for-build-and-unit.patch @@ -0,0 +1,89 @@ +From 2307a76cb78af02167bef314906f9ad0f9f9d339 Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Fri, 17 Oct 2025 14:00:23 +0100 +Subject: [PATCH] ci: re-enable bpf-framework option for build and unit test + jobs + +Use the same trickery we do in the package build and search for +the actual bpftool binary. For the CI job any one we find is +good enough. +When we switch all jobs to 26.04 we can drop all of this. + +This reverts commit cc814110af7a453db898ea2990a0281616d5ceff. + +(cherry picked from commit 3b11139c0db9dd0a37b0493a8d2ad5f531a92344) + +Related: RHEL-155394 +--- + .github/workflows/build_test.sh | 12 ++++++++++++ + .github/workflows/unit_tests.sh | 13 +++++++++++++ + 2 files changed, 25 insertions(+) + +diff --git a/.github/workflows/build_test.sh b/.github/workflows/build_test.sh +index 113af704a8..462203be9a 100755 +--- a/.github/workflows/build_test.sh ++++ b/.github/workflows/build_test.sh +@@ -47,6 +47,7 @@ PACKAGES=( + libxkbcommon-dev + libxtables-dev + libzstd-dev ++ linux-tools-generic + mold + mount + net-tools +@@ -131,6 +132,17 @@ sudo apt-get -y install "${PACKAGES[@]}" + pip3 install --user -r .github/workflows/requirements.txt --require-hashes --break-system-packages + export PATH="$HOME/.local/bin:$PATH" + ++# TODO: drop after we switch to ubuntu 26.04 ++bpftool_dir=$(dirname "$(find /usr/lib/linux-tools/ /usr/lib/linux-tools-* -name 'bpftool' -perm /u=x 2>/dev/null | sort -r | head -n1)") ++if [ -n "$bpftool_dir" ]; then ++ export PATH="$bpftool_dir:$PATH" ++fi ++ ++if [[ -n "$CUSTOM_PYTHON" ]]; then ++ # If CUSTOM_PYTHON is set we need to pull jinja2 from pip, as a local interpreter is used ++ pip3 install --user --break-system-packages jinja2 ++fi ++ + $CC --version + meson --version + ninja --version +diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh +index 168bcc55c3..3acaf75417 100755 +--- a/.github/workflows/unit_tests.sh ++++ b/.github/workflows/unit_tests.sh +@@ -18,6 +18,7 @@ ADDITIONAL_DEPS=( + libtss2-dev + libxkbcommon-dev + libzstd-dev ++ linux-tools-generic + python3-libevdev + python3-pefile + python3-pyelftools +@@ -70,6 +71,12 @@ for phase in "${PHASES[@]}"; do + capsh --drop=all -- -c "stat $PWD/meson.build" + ;; + RUN|RUN_GCC|RUN_CLANG|RUN_CLANG_RELEASE) ++ # TODO: drop after we switch to ubuntu 26.04 ++ bpftool_dir=$(dirname "$(find /usr/lib/linux-tools/ /usr/lib/linux-tools-* -name 'bpftool' -perm /u=x 2>/dev/null | sort -r | head -n1)") ++ if [ -n "$bpftool_dir" ]; then ++ export PATH="$bpftool_dir:$PATH" ++ fi ++ + if [[ "$phase" =~ ^RUN_CLANG ]]; then + export CC=clang + export CXX=clang++ +@@ -94,6 +101,12 @@ for phase in "${PHASES[@]}"; do + TZ=GMT+12 meson test -C build --print-errorlogs + ;; + RUN_ASAN_UBSAN|RUN_GCC_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN_NO_DEPS) ++ # TODO: drop after we switch to ubuntu 26.04 ++ bpftool_dir=$(dirname "$(find /usr/lib/linux-tools/ /usr/lib/linux-tools-* -name 'bpftool' -perm /u=x 2>/dev/null | sort -r | head -n1)") ++ if [ -n "$bpftool_dir" ]; then ++ export PATH="$bpftool_dir:$PATH" ++ fi ++ + MESON_ARGS=(--optimization=1) + + if [[ "$phase" =~ ^RUN_CLANG_ASAN_UBSAN ]]; then diff --git a/0464-ci-add-bpftool-workaround-to-codeql-job-too.patch b/0464-ci-add-bpftool-workaround-to-codeql-job-too.patch new file mode 100644 index 0000000..8091ce6 --- /dev/null +++ b/0464-ci-add-bpftool-workaround-to-codeql-job-too.patch @@ -0,0 +1,32 @@ +From 5cb269a74ace5da67a9065ae1520c5420858bf9d Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Fri, 17 Oct 2025 15:39:09 +0100 +Subject: [PATCH] ci: add bpftool workaround to codeql job too + +(cherry picked from commit e9fd2bbfffc5c2c7cd1ea0a288d5435fc15e387f) + +Related: RHEL-155394 +--- + .github/workflows/codeql.yml | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml +index 51034783ca..443221fa11 100644 +--- a/.github/workflows/codeql.yml ++++ b/.github/workflows/codeql.yml +@@ -44,7 +44,14 @@ jobs: + languages: ${{ matrix.language }} + config-file: ./.github/codeql-config.yml + +- - run: sudo -E .github/workflows/unit_tests.sh SETUP ++ - run: | ++ sudo -E .github/workflows/unit_tests.sh SETUP ++ # TODO: drop after we switch to ubuntu 26.04 ++ bpftool_binary=$(find /usr/lib/linux-tools/ /usr/lib/linux-tools-* -name 'bpftool' -perm /u=x 2>/dev/null | sort -r | head -n1) ++ if [ -n "$bpftool_binary" ]; then ++ sudo rm -f /usr/bin/bpftool ++ sudo ln -s "$bpftool_binary" /usr/bin/ ++ fi + + - name: Autobuild + uses: github/codeql-action/autobuild@f09c1c0a94de965c15400f5634aa42fac8fb8f88 diff --git a/0465-ci-fix-workaround-about-bpftool-for-codeql.patch b/0465-ci-fix-workaround-about-bpftool-for-codeql.patch new file mode 100644 index 0000000..8d2e157 --- /dev/null +++ b/0465-ci-fix-workaround-about-bpftool-for-codeql.patch @@ -0,0 +1,27 @@ +From 633ed4d425167afe0bf692d47c7767085247d871 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sat, 18 Oct 2025 10:39:13 +0900 +Subject: [PATCH] ci: fix workaround about bpftool for codeql + +Follow-up for e9fd2bbfffc5c2c7cd1ea0a288d5435fc15e387f. + +(cherry picked from commit a6836cfa0bdf1bb1fcf05686c5af3f2b5ad97f6b) + +Related: RHEL-155394 +--- + .github/workflows/codeql.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml +index 443221fa11..cfe54d59ac 100644 +--- a/.github/workflows/codeql.yml ++++ b/.github/workflows/codeql.yml +@@ -49,7 +49,7 @@ jobs: + # TODO: drop after we switch to ubuntu 26.04 + bpftool_binary=$(find /usr/lib/linux-tools/ /usr/lib/linux-tools-* -name 'bpftool' -perm /u=x 2>/dev/null | sort -r | head -n1) + if [ -n "$bpftool_binary" ]; then +- sudo rm -f /usr/bin/bpftool ++ sudo rm -f /usr/{bin,sbin}/bpftool + sudo ln -s "$bpftool_binary" /usr/bin/ + fi + diff --git a/0466-ci-add-bpftool-workaround-to-coverity-too.patch b/0466-ci-add-bpftool-workaround-to-coverity-too.patch new file mode 100644 index 0000000..0db6b1d --- /dev/null +++ b/0466-ci-add-bpftool-workaround-to-coverity-too.patch @@ -0,0 +1,31 @@ +From 71097b7dc72abeaca5cb8389c0f7384521835eef Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Sat, 18 Oct 2025 14:23:59 +0100 +Subject: [PATCH] ci: add bpftool workaround to coverity too + +(cherry picked from commit d29f181cf02100c146fc8691a5515a708d06ddbf) + +Related: RHEL-155394 +--- + .github/workflows/coverity.yml | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml +index 66204069c4..80d25d380a 100644 +--- a/.github/workflows/coverity.yml ++++ b/.github/workflows/coverity.yml +@@ -25,6 +25,13 @@ jobs: + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + # Reuse the setup phase of the unit test script to avoid code duplication + - name: Install build dependencies +- run: sudo -E .github/workflows/unit_tests.sh SETUP ++ run: | ++ sudo -E .github/workflows/unit_tests.sh SETUP ++ # TODO: drop after we switch to ubuntu 26.04 ++ bpftool_binary=$(find /usr/lib/linux-tools/ /usr/lib/linux-tools-* -name 'bpftool' -perm /u=x 2>/dev/null | sort -r | head -n1) ++ if [ -n "$bpftool_binary" ]; then ++ sudo rm -f /usr/{bin,sbin}/bpftool ++ sudo ln -s "$bpftool_binary" /usr/bin/ ++ fi + - name: Build & upload the results + run: tools/coverity.sh diff --git a/0467-ci-pin-Packit-mkosi-to-the-latest-RHEL-10.1-commit.patch b/0467-ci-pin-Packit-mkosi-to-the-latest-RHEL-10.1-commit.patch new file mode 100644 index 0000000..5f1346d --- /dev/null +++ b/0467-ci-pin-Packit-mkosi-to-the-latest-RHEL-10.1-commit.patch @@ -0,0 +1,40 @@ +From 9c2aea3a3811a194bb3b9710cf521b68c5809b82 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Jan 2026 18:26:48 +0100 +Subject: [PATCH] ci: pin Packit/mkosi to the latest RHEL 10.1 commit + +rhel-only: ci +Related: RHEL-155394 +--- + .packit.yml | 3 ++- + mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.conf | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/.packit.yml b/.packit.yml +index a5d9aca0e1..0c2b256102 100644 +--- a/.packit.yml ++++ b/.packit.yml +@@ -24,7 +24,8 @@ actions: + + post-upstream-clone: + # Use the CentOS Stream 10 specfile +- - "git clone -b c10s https://gitlab.com/redhat/centos-stream/rpms/systemd.git .packit_rpm --depth=1" ++ # Pin this to the latest 10.1 version (systemd-257-13) ++ - "git clone https://gitlab.com/redhat/centos-stream/rpms/systemd.git .packit_rpm --depth=1 --revision=8adcfa40b029b11bb2512c8cc7e6301ee3a77df9" + # Drop the "sources" file so rebase-helper doesn't think we're a dist-git + - "rm -fv .packit_rpm/sources" + # Drop all patches, since they're already included in the tarball +diff --git a/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.conf b/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.conf +index 31f03ca120..ea922ec18c 100644 +--- a/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.conf ++++ b/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.conf +@@ -8,7 +8,8 @@ Distribution=|fedora + Environment= + GIT_URL=https://gitlab.com/redhat/centos-stream/rpms/systemd/ + GIT_BRANCH=c10s +- GIT_COMMIT=c10s ++ # Pin this to the latest 10.1 version (systemd-257-13) ++ GIT_COMMIT=8adcfa40b029b11bb2512c8cc7e6301ee3a77df9 + PKG_SUBDIR=fedora + + [Content] diff --git a/0468-ci-run-apt-get-update-before-running-mkosi.patch b/0468-ci-run-apt-get-update-before-running-mkosi.patch new file mode 100644 index 0000000..32f405d --- /dev/null +++ b/0468-ci-run-apt-get-update-before-running-mkosi.patch @@ -0,0 +1,50 @@ +From c5d5e72f711379c032259897a34d8f177d333d46 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 6 Feb 2026 14:17:54 +0100 +Subject: [PATCH] ci: run apt-get update before running mkosi + +This is alternative to https://github.com/systemd/mkosi/commit/8c9f6cc6586c4f3b8fedafc5a19e6bf30531ebfc + +The repository metadata in the image can get out of date. Let's run +apt-get update to make sure it is fresh. + +``` +Err:21 https://security.ubuntu.com/ubuntu noble-updates/main amd64 libboost-thread1.83.0 amd64 1.83.0-2.1ubuntu3.1 + 404 Not Found [IP: 52.161.185.214 80] +E: Failed to fetch https://security.ubuntu.com/ubuntu/pool/main/b/boost1.83/libboost-thread1.83.0_1.83.0-2.1ubuntu3.1_amd64.deb 404 Not Found [IP: 52.161.185.214 80] +Fetched 8320 kB in 2s (3488 kB/s) +E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing? +Error: Process completed with exit code 100. +``` + +rhel-only: ci +Related: RHEL-155394 +--- + .github/workflows/coverage.yml | 1 + + .github/workflows/mkosi.yml | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml +index 1cce9a97f3..bf918bc399 100644 +--- a/.github/workflows/coverage.yml ++++ b/.github/workflows/coverage.yml +@@ -16,6 +16,7 @@ jobs: + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 ++ - run: sudo apt-get update + - uses: systemd/mkosi@d501139032aa659fa8d34bdb850f4eb6b5f458ed + + # Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space +diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml +index 6ddfaf1a87..fe2922ac70 100644 +--- a/.github/workflows/mkosi.yml ++++ b/.github/workflows/mkosi.yml +@@ -83,6 +83,7 @@ jobs: + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 ++ - run: sudo apt-get update + - uses: systemd/mkosi@d501139032aa659fa8d34bdb850f4eb6b5f458ed + + # Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space diff --git a/0469-path-util-add-flavour-of-path_startswith-that-leaves.patch b/0469-path-util-add-flavour-of-path_startswith-that-leaves.patch new file mode 100644 index 0000000..8eeb631 --- /dev/null +++ b/0469-path-util-add-flavour-of-path_startswith-that-leaves.patch @@ -0,0 +1,162 @@ +From 15e39369ff74425283c401f0b4c335c806c8fb99 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 May 2025 12:58:52 +0200 +Subject: [PATCH] path-util: add flavour of path_startswith() that leaves a + leading slash in place + +(cherry picked from commit ee19edbb9f3455db3f750089082f3e5a925e3a0c) + +Related: RHEL-155394 +--- + src/basic/fs-util.c | 2 +- + src/basic/mkdir.c | 2 +- + src/basic/path-util.c | 39 ++++++++++++++++++++++++++++----------- + src/basic/path-util.h | 10 ++++++++-- + src/test/test-path-util.c | 16 ++++++++++++++++ + 5 files changed, 54 insertions(+), 15 deletions(-) + +diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c +index 4ede324c34..21a670c9e8 100644 +--- a/src/basic/fs-util.c ++++ b/src/basic/fs-util.c +@@ -66,7 +66,7 @@ int rmdir_parents(const char *path, const char *stop) { + assert(*slash == '/'); + *slash = '\0'; + +- if (path_startswith_full(stop, p, /* accept_dot_dot= */ false)) ++ if (path_startswith_full(stop, p, /* flags= */ 0)) + return 0; + + if (rmdir(p) < 0 && errno != ENOENT) +diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c +index 3e1545a58b..6fc2a79944 100644 +--- a/src/basic/mkdir.c ++++ b/src/basic/mkdir.c +@@ -149,7 +149,7 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, ui + assert(_mkdirat != mkdirat); + + if (prefix) { +- p = path_startswith_full(path, prefix, /* accept_dot_dot= */ false); ++ p = path_startswith_full(path, prefix, /* flags= */ 0); + if (!p) + return -EINVAL; + +diff --git a/src/basic/path-util.c b/src/basic/path-util.c +index 78ba10ed80..a4709e1b7d 100644 +--- a/src/basic/path-util.c ++++ b/src/basic/path-util.c +@@ -405,8 +405,8 @@ char* path_simplify_full(char *path, PathSimplifyFlags flags) { + return path; + } + +-char* path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) { +- assert(path); ++char* path_startswith_full(const char *original_path, const char *prefix, PathStartWithFlags flags) { ++ assert(original_path); + assert(prefix); + + /* Returns a pointer to the start of the first component after the parts matched by +@@ -419,28 +419,45 @@ char* path_startswith_full(const char *path, const char *prefix, bool accept_dot + * Returns NULL otherwise. + */ + ++ const char *path = original_path; ++ + if ((path[0] == '/') != (prefix[0] == '/')) + return NULL; + + for (;;) { + const char *p, *q; +- int r, k; ++ int m, n; + +- r = path_find_first_component(&path, accept_dot_dot, &p); +- if (r < 0) ++ m = path_find_first_component(&path, FLAGS_SET(flags, PATH_STARTSWITH_ACCEPT_DOT_DOT), &p); ++ if (m < 0) + return NULL; + +- k = path_find_first_component(&prefix, accept_dot_dot, &q); +- if (k < 0) ++ n = path_find_first_component(&prefix, FLAGS_SET(flags, PATH_STARTSWITH_ACCEPT_DOT_DOT), &q); ++ if (n < 0) + return NULL; + +- if (k == 0) +- return (char*) (p ?: path); ++ if (n == 0) { ++ if (!p) ++ p = path; ++ ++ if (FLAGS_SET(flags, PATH_STARTSWITH_RETURN_LEADING_SLASH)) { ++ ++ if (p <= original_path) ++ return NULL; ++ ++ p--; ++ ++ if (*p != '/') ++ return NULL; ++ } ++ ++ return (char*) p; ++ } + +- if (r != k) ++ if (m != n) + return NULL; + +- if (!strneq(p, q, r)) ++ if (!strneq(p, q, m)) + return NULL; + } + } +diff --git a/src/basic/path-util.h b/src/basic/path-util.h +index dff5a3a549..d1e9f4b785 100644 +--- a/src/basic/path-util.h ++++ b/src/basic/path-util.h +@@ -52,9 +52,15 @@ int safe_getcwd(char **ret); + int path_make_absolute_cwd(const char *p, char **ret); + int path_make_relative(const char *from, const char *to, char **ret); + int path_make_relative_parent(const char *from_child, const char *to, char **ret); +-char* path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) _pure_; ++ ++typedef enum PathStartWithFlags { ++ PATH_STARTSWITH_ACCEPT_DOT_DOT = 1U << 0, ++ PATH_STARTSWITH_RETURN_LEADING_SLASH = 1U << 1, ++} PathStartWithFlags; ++ ++char* path_startswith_full(const char *path, const char *prefix, PathStartWithFlags flags) _pure_; + static inline char* path_startswith(const char *path, const char *prefix) { +- return path_startswith_full(path, prefix, true); ++ return path_startswith_full(path, prefix, PATH_STARTSWITH_ACCEPT_DOT_DOT); + } + + int path_compare(const char *a, const char *b) _pure_; +diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c +index e02bd8c857..8aa477bd69 100644 +--- a/src/test/test-path-util.c ++++ b/src/test/test-path-util.c +@@ -756,6 +756,22 @@ TEST(path_startswith) { + test_path_startswith_one("/foo/bar/barfoo/", "/fo", NULL, NULL); + } + ++static void test_path_startswith_return_leading_slash_one(const char *path, const char *prefix, const char *expected) { ++ const char *p; ++ ++ log_debug("/* %s(%s, %s) */", __func__, path, prefix); ++ ++ p = path_startswith_full(path, prefix, PATH_STARTSWITH_RETURN_LEADING_SLASH); ++ ASSERT_STREQ(p, expected); ++} ++ ++TEST(path_startswith_return_leading_slash) { ++ test_path_startswith_return_leading_slash_one("/foo/bar", "/", "/foo/bar"); ++ test_path_startswith_return_leading_slash_one("/foo/bar", "/foo", "/bar"); ++ test_path_startswith_return_leading_slash_one("/foo/bar", "/foo/bar", NULL); ++ test_path_startswith_return_leading_slash_one("/foo/bar/", "/foo/bar", "/"); ++} ++ + static void test_prefix_root_one(const char *r, const char *p, const char *expected) { + _cleanup_free_ char *s = NULL; + const char *t; diff --git a/0470-cgroup-port-some-code-over-to-path_startswith_full.patch b/0470-cgroup-port-some-code-over-to-path_startswith_full.patch new file mode 100644 index 0000000..faea60a --- /dev/null +++ b/0470-cgroup-port-some-code-over-to-path_startswith_full.patch @@ -0,0 +1,45 @@ +From 6128d02c345422150a2e702b5fd1e51212236577 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 22 May 2025 18:35:25 +0200 +Subject: [PATCH] cgroup: port some code over to path_startswith_full() + +(cherry picked from commit 482107724f64cb8dd24db3e65b6ea3151a330301) + +Related: RHEL-155394 +--- + src/basic/cgroup-util.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c +index 309dccb45a..b8a17badea 100644 +--- a/src/basic/cgroup-util.c ++++ b/src/basic/cgroup-util.c +@@ -1013,13 +1013,12 @@ int cg_get_root_path(char **ret_path) { + } + + int cg_shift_path(const char *cgroup, const char *root, const char **ret_shifted) { +- _cleanup_free_ char *rt = NULL; +- char *p; + int r; + + assert(cgroup); + assert(ret_shifted); + ++ _cleanup_free_ char *rt = NULL; + if (!root) { + /* If the root was specified let's use that, otherwise + * let's determine it from PID 1 */ +@@ -1031,12 +1030,7 @@ int cg_shift_path(const char *cgroup, const char *root, const char **ret_shifted + root = rt; + } + +- p = path_startswith(cgroup, root); +- if (p && p > cgroup) +- *ret_shifted = p - 1; +- else +- *ret_shifted = cgroup; +- ++ *ret_shifted = path_startswith_full(cgroup, root, PATH_STARTSWITH_RETURN_LEADING_SLASH) ?: cgroup; + return 0; + } + diff --git a/0471-path-util-invert-PATH_STARTSWITH_ACCEPT_DOT_DOT-flag.patch b/0471-path-util-invert-PATH_STARTSWITH_ACCEPT_DOT_DOT-flag.patch new file mode 100644 index 0000000..776227d --- /dev/null +++ b/0471-path-util-invert-PATH_STARTSWITH_ACCEPT_DOT_DOT-flag.patch @@ -0,0 +1,95 @@ +From 324340b11bbdef8a0b1e607acd741bc453b222dc Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 23 May 2025 06:45:40 +0200 +Subject: [PATCH] path-util: invert PATH_STARTSWITH_ACCEPT_DOT_DOT flag + +As requested: https://github.com/systemd/systemd/pull/37572#pullrequestreview-2861928094 + +(cherry picked from commit ceed11e465f1c8efff1931412a85924d9de7c08d) + +Related: RHEL-155394 +--- + src/basic/cgroup-util.c | 2 +- + src/basic/fs-util.c | 2 +- + src/basic/mkdir.c | 2 +- + src/basic/path-util.c | 4 ++-- + src/basic/path-util.h | 4 ++-- + 5 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c +index b8a17badea..925b753c39 100644 +--- a/src/basic/cgroup-util.c ++++ b/src/basic/cgroup-util.c +@@ -1030,7 +1030,7 @@ int cg_shift_path(const char *cgroup, const char *root, const char **ret_shifted + root = rt; + } + +- *ret_shifted = path_startswith_full(cgroup, root, PATH_STARTSWITH_RETURN_LEADING_SLASH) ?: cgroup; ++ *ret_shifted = path_startswith_full(cgroup, root, PATH_STARTSWITH_RETURN_LEADING_SLASH|PATH_STARTSWITH_REFUSE_DOT_DOT) ?: cgroup; + return 0; + } + +diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c +index 21a670c9e8..69e76653ab 100644 +--- a/src/basic/fs-util.c ++++ b/src/basic/fs-util.c +@@ -66,7 +66,7 @@ int rmdir_parents(const char *path, const char *stop) { + assert(*slash == '/'); + *slash = '\0'; + +- if (path_startswith_full(stop, p, /* flags= */ 0)) ++ if (path_startswith_full(stop, p, PATH_STARTSWITH_REFUSE_DOT_DOT)) + return 0; + + if (rmdir(p) < 0 && errno != ENOENT) +diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c +index 6fc2a79944..f1e5f2dc8d 100644 +--- a/src/basic/mkdir.c ++++ b/src/basic/mkdir.c +@@ -149,7 +149,7 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, ui + assert(_mkdirat != mkdirat); + + if (prefix) { +- p = path_startswith_full(path, prefix, /* flags= */ 0); ++ p = path_startswith_full(path, prefix, PATH_STARTSWITH_REFUSE_DOT_DOT); + if (!p) + return -EINVAL; + +diff --git a/src/basic/path-util.c b/src/basic/path-util.c +index a4709e1b7d..fda6066bc6 100644 +--- a/src/basic/path-util.c ++++ b/src/basic/path-util.c +@@ -428,11 +428,11 @@ char* path_startswith_full(const char *original_path, const char *prefix, PathSt + const char *p, *q; + int m, n; + +- m = path_find_first_component(&path, FLAGS_SET(flags, PATH_STARTSWITH_ACCEPT_DOT_DOT), &p); ++ m = path_find_first_component(&path, !FLAGS_SET(flags, PATH_STARTSWITH_REFUSE_DOT_DOT), &p); + if (m < 0) + return NULL; + +- n = path_find_first_component(&prefix, FLAGS_SET(flags, PATH_STARTSWITH_ACCEPT_DOT_DOT), &q); ++ n = path_find_first_component(&prefix, !FLAGS_SET(flags, PATH_STARTSWITH_REFUSE_DOT_DOT), &q); + if (n < 0) + return NULL; + +diff --git a/src/basic/path-util.h b/src/basic/path-util.h +index d1e9f4b785..429d7ac507 100644 +--- a/src/basic/path-util.h ++++ b/src/basic/path-util.h +@@ -54,13 +54,13 @@ int path_make_relative(const char *from, const char *to, char **ret); + int path_make_relative_parent(const char *from_child, const char *to, char **ret); + + typedef enum PathStartWithFlags { +- PATH_STARTSWITH_ACCEPT_DOT_DOT = 1U << 0, ++ PATH_STARTSWITH_REFUSE_DOT_DOT = 1U << 0, + PATH_STARTSWITH_RETURN_LEADING_SLASH = 1U << 1, + } PathStartWithFlags; + + char* path_startswith_full(const char *path, const char *prefix, PathStartWithFlags flags) _pure_; + static inline char* path_startswith(const char *path, const char *prefix) { +- return path_startswith_full(path, prefix, PATH_STARTSWITH_ACCEPT_DOT_DOT); ++ return path_startswith_full(path, prefix, 0); + } + + int path_compare(const char *a, const char *b) _pure_; diff --git a/0472-sd-json-fix-off-by-one-issue-when-updating-parent-fo.patch b/0472-sd-json-fix-off-by-one-issue-when-updating-parent-fo.patch new file mode 100644 index 0000000..06ec60a --- /dev/null +++ b/0472-sd-json-fix-off-by-one-issue-when-updating-parent-fo.patch @@ -0,0 +1,28 @@ +From 1f710e3d70ab5303adc27b61e2da86b039cd4caa Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Thu, 26 Feb 2026 11:07:39 +0100 +Subject: [PATCH] sd-json: fix off-by-one issue when updating parent for array + elements + +Follow-up for 8525bb369a09f488ec77f94e1557ecc2343eb4ab + +(cherry picked from commit 4e6e3b8707c84018051ae1885af20e06b2a5209e) + +Related: RHEL-155394 +--- + src/libsystemd/sd-json/sd-json.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c +index 64b59e0f3f..97897122b8 100644 +--- a/src/libsystemd/sd-json/sd-json.c ++++ b/src/libsystemd/sd-json/sd-json.c +@@ -2243,7 +2243,7 @@ _public_ int sd_json_variant_append_array(sd_json_variant **v, sd_json_variant * + + if (old != *v) + /* Readjust the parent pointers to the new address */ +- for (size_t i = 1; i < size; i++) ++ for (size_t i = 0; i < size; i++) + (*v)[1 + i].parent = *v; + + return json_variant_array_put_element(*v, element); diff --git a/0473-core-cgroup-avoid-one-unnecessary-strjoina.patch b/0473-core-cgroup-avoid-one-unnecessary-strjoina.patch new file mode 100644 index 0000000..2adada6 --- /dev/null +++ b/0473-core-cgroup-avoid-one-unnecessary-strjoina.patch @@ -0,0 +1,96 @@ +From 35cf009cf363a0657ca812246f7f9233677a2369 Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Thu, 26 Feb 2026 11:06:00 +0100 +Subject: [PATCH] core/cgroup: avoid one unnecessary strjoina() + +(cherry picked from commit 42aee39107fbdd7db1ccd402a2151822b2805e9f) + +Related: RHEL-155394 +--- + src/core/cgroup.c | 28 +++++++++++++--------------- + 1 file changed, 13 insertions(+), 15 deletions(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 22a29666b6..88ba883f77 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -2961,12 +2961,13 @@ static int unit_update_cgroup( + return 0; + } + +-static int unit_attach_pid_to_cgroup_via_bus(Unit *u, pid_t pid, const char *suffix_path) { ++static int unit_attach_pid_to_cgroup_via_bus(Unit *u, const char *cgroup_path, pid_t pid) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- char *pp; + int r; + + assert(u); ++ assert(cgroup_path); ++ assert(pid_is_valid(pid)); + + if (MANAGER_IS_SYSTEM(u->manager)) + return -EINVAL; +@@ -2974,18 +2975,13 @@ static int unit_attach_pid_to_cgroup_via_bus(Unit *u, pid_t pid, const char *suf + if (!u->manager->system_bus) + return -EIO; + +- CGroupRuntime *crt = unit_get_cgroup_runtime(u); +- if (!crt || !crt->cgroup_path) +- return -EOWNERDEAD; +- + /* Determine this unit's cgroup path relative to our cgroup root */ +- pp = path_startswith(crt->cgroup_path, u->manager->cgroup_root); ++ const char *pp = path_startswith_full(cgroup_path, ++ u->manager->cgroup_root, ++ PATH_STARTSWITH_RETURN_LEADING_SLASH|PATH_STARTSWITH_REFUSE_DOT_DOT); + if (!pp) + return -EINVAL; + +- pp = strjoina("/", pp, suffix_path); +- path_simplify(pp); +- + r = bus_call_method(u->manager->system_bus, + bus_systemd_mgr, + "AttachProcessesToUnit", +@@ -3026,8 +3022,10 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) { + CGroupRuntime *crt = ASSERT_PTR(unit_get_cgroup_runtime(u)); + + if (isempty(suffix_path)) +- p = crt->cgroup_path; ++ p = empty_to_root(crt->cgroup_path); + else { ++ assert(path_is_absolute(suffix_path)); ++ + joined = path_join(crt->cgroup_path, suffix_path); + if (!joined) + return -ENOMEM; +@@ -3045,7 +3043,7 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) { + * before we use it */ + r = pidref_verify(pid); + if (r < 0) { +- log_unit_info_errno(u, r, "PID " PID_FMT " vanished before we could move it to target cgroup '%s', skipping: %m", pid->pid, empty_to_root(p)); ++ log_unit_info_errno(u, r, "PID " PID_FMT " vanished before we could move it to target cgroup '%s', skipping: %m", pid->pid, p); + continue; + } + +@@ -3056,7 +3054,7 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) { + + log_unit_full_errno(u, again ? LOG_DEBUG : LOG_INFO, r, + "Couldn't move process "PID_FMT" to%s requested cgroup '%s': %m", +- pid->pid, again ? " directly" : "", empty_to_root(p)); ++ pid->pid, again ? " directly" : "", p); + + if (again) { + int z; +@@ -3066,9 +3064,9 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) { + * Since it's more privileged it might be able to move the process across the + * leaves of a subtree whose top node is not owned by us. */ + +- z = unit_attach_pid_to_cgroup_via_bus(u, pid->pid, suffix_path); ++ z = unit_attach_pid_to_cgroup_via_bus(u, p, pid->pid); + if (z < 0) +- log_unit_info_errno(u, z, "Couldn't move process "PID_FMT" to requested cgroup '%s' (directly or via the system bus): %m", pid->pid, empty_to_root(p)); ++ log_unit_info_errno(u, z, "Couldn't move process "PID_FMT" to requested cgroup '%s' (directly or via the system bus): %m", pid->pid, p); + else { + if (ret >= 0) + ret++; /* Count successful additions */ diff --git a/0474-core-validate-input-cgroup-path-more-prudently.patch b/0474-core-validate-input-cgroup-path-more-prudently.patch new file mode 100644 index 0000000..97f7902 --- /dev/null +++ b/0474-core-validate-input-cgroup-path-more-prudently.patch @@ -0,0 +1,29 @@ +From 5d45ce22093b7dc6911a94213b0cc29898aff393 Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Thu, 26 Feb 2026 11:06:34 +0100 +Subject: [PATCH] core: validate input cgroup path more prudently + +(cherry picked from commit efa6ba2ab625aaa160ac435a09e6482fc63bdbe8) + +Resolves: RHEL-155394 +--- + src/core/dbus-manager.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index 8e39d67a00..d516f30c96 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -622,6 +622,12 @@ static int method_get_unit_by_control_group(sd_bus_message *message, void *userd + if (r < 0) + return r; + ++ if (!path_is_absolute(cgroup)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Control group path is not absolute: %s", cgroup); ++ ++ if (!path_is_normalized(cgroup)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Control group path is not normalized: %s", cgroup); ++ + u = manager_get_unit_by_cgroup(m, cgroup); + if (!u) + return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, diff --git a/systemd.spec b/systemd.spec index 1b2bfd7..100419b 100644 --- a/systemd.spec +++ b/systemd.spec @@ -48,7 +48,7 @@ Url: https://systemd.io # Allow users to specify the version and release when building the rpm by # setting the %%version_override and %%release_override macros. Version: %{?version_override}%{!?version_override:257} -Release: 13%{?dist} +Release: 13%{?dist}.3 %global stable %(c="%version"; [ "$c" = "${c#*.*}" ]; echo $?) @@ -548,6 +548,42 @@ Patch0435: 0435-hwdb-Add-launch-emoji-keyboard-mapping-for-Asus-M160.patch Patch0436: 0436-Enable-KEY_PERFORMANCE-key-present-on-Linux-6.17.patch Patch0437: 0437-hwdb-add-HP-150-Wired-Mouse-37341.patch Patch0438: 0438-core-transaction-do-not-attempt-to-log-n-a-as-a-jour.patch +Patch0439: 0439-coredump-verify-pidfd-after-parsing-data-in-usermode.patch +Patch0440: 0440-coredump-restore-compatibility-with-older-patterns.patch +Patch0441: 0441-coredump-wrap-long-lines-fix-grammar-in-comments.patch +Patch0442: 0442-coredump-get-rid-of-_META_MANDATORY_MAX.patch +Patch0443: 0443-coredump-use-d-in-kernel-core-pattern.patch +Patch0444: 0444-coredump-also-stop-forwarding-non-dumpable-processes.patch +Patch0445: 0445-coredump-get-rid-of-a-bogus-assertion.patch +Patch0446: 0446-coredump-add-support-for-new-F-PIDFD-specifier.patch +Patch0447: 0447-coredump-when-F-pidfd-is-used-again-allow-forwarding.patch +Patch0448: 0448-coredump-introduce-an-enum-to-wrap-dumpable-constant.patch +Patch0449: 0449-Define-helper-to-call-PR_SET_DUMPABLE.patch +Patch0450: 0450-coredump-fix-0-passed-as-pointer-warning.patch +Patch0451: 0451-Revert-coredump-fix-0-passed-as-pointer-warning.patch +Patch0452: 0452-Revert-Define-helper-to-call-PR_SET_DUMPABLE.patch +Patch0453: 0453-Revert-coredump-introduce-an-enum-to-wrap-dumpable-c.patch +Patch0454: 0454-Revert-coredump-when-F-pidfd-is-used-again-allow-for.patch +Patch0455: 0455-Revert-coredump-add-support-for-new-F-PIDFD-specifie.patch +Patch0456: 0456-Revert-coredump-get-rid-of-a-bogus-assertion.patch +Patch0457: 0457-Revert-coredump-also-stop-forwarding-non-dumpable-pr.patch +Patch0458: 0458-Revert-coredump-use-d-in-kernel-core-pattern.patch +Patch0459: 0459-Revert-coredump-get-rid-of-_META_MANDATORY_MAX.patch +Patch0460: 0460-Revert-coredump-wrap-long-lines-fix-grammar-in-comme.patch +Patch0461: 0461-Revert-coredump-restore-compatibility-with-older-pat.patch +Patch0462: 0462-Revert-coredump-verify-pidfd-after-parsing-data-in-u.patch +Patch0463: 0463-ci-re-enable-bpf-framework-option-for-build-and-unit.patch +Patch0464: 0464-ci-add-bpftool-workaround-to-codeql-job-too.patch +Patch0465: 0465-ci-fix-workaround-about-bpftool-for-codeql.patch +Patch0466: 0466-ci-add-bpftool-workaround-to-coverity-too.patch +Patch0467: 0467-ci-pin-Packit-mkosi-to-the-latest-RHEL-10.1-commit.patch +Patch0468: 0468-ci-run-apt-get-update-before-running-mkosi.patch +Patch0469: 0469-path-util-add-flavour-of-path_startswith-that-leaves.patch +Patch0470: 0470-cgroup-port-some-code-over-to-path_startswith_full.patch +Patch0471: 0471-path-util-invert-PATH_STARTSWITH_ACCEPT_DOT_DOT-flag.patch +Patch0472: 0472-sd-json-fix-off-by-one-issue-when-updating-parent-fo.patch +Patch0473: 0473-core-cgroup-avoid-one-unnecessary-strjoina.patch +Patch0474: 0474-core-validate-input-cgroup-path-more-prudently.patch # Downstream-only patches (9000–9999) %endif @@ -1494,6 +1530,48 @@ rm -f .file-list-* rm -f %{name}.lang %changelog +* Wed Apr 08 2026 systemd maintenance team - 257-13.3 +- ci: re-enable bpf-framework option for build and unit test jobs (RHEL-155394) +- ci: add bpftool workaround to codeql job too (RHEL-155394) +- ci: fix workaround about bpftool for codeql (RHEL-155394) +- ci: add bpftool workaround to coverity too (RHEL-155394) +- ci: pin Packit/mkosi to the latest RHEL 10.1 commit (RHEL-155394) +- ci: run apt-get update before running mkosi (RHEL-155394) +- path-util: add flavour of path_startswith() that leaves a leading slash in place (RHEL-155394) +- cgroup: port some code over to path_startswith_full() (RHEL-155394) +- path-util: invert PATH_STARTSWITH_ACCEPT_DOT_DOT flag (RHEL-155394) +- sd-json: fix off-by-one issue when updating parent for array elements (RHEL-155394) +- core/cgroup: avoid one unnecessary strjoina() (RHEL-155394) +- core: validate input cgroup path more prudently (RHEL-155394) + +* Thu Jan 22 2026 systemd maintenance team - 257-13.2 +- Revert "coredump: fix 0-passed-as-pointer warning" (RHEL-104135) +- Revert "Define helper to call PR_SET_DUMPABLE" (RHEL-104135) +- Revert "coredump: introduce an enum to wrap dumpable constants" (RHEL-104135) +- Revert "coredump: when %F/pidfd is used, again allow forwarding to containers" (RHEL-104135) +- Revert "coredump: add support for new %F PIDFD specifier" (RHEL-104135) +- Revert "coredump: get rid of a bogus assertion" (RHEL-104135) +- Revert "coredump: also stop forwarding non-dumpable processes" (RHEL-104135) +- Revert "coredump: use %d in kernel core pattern" (RHEL-104135) +- Revert "coredump: get rid of _META_MANDATORY_MAX" (RHEL-104135) +- Revert "coredump: wrap long lines, fix grammar in comments" (RHEL-104135) +- Revert "coredump: restore compatibility with older patterns" (RHEL-104135) +- Revert "coredump: verify pidfd after parsing data in usermode helper" (RHEL-104135) + +* Fri Nov 21 2025 systemd maintenance team - 257-13.1 +- coredump: verify pidfd after parsing data in usermode helper (RHEL-104135) +- coredump: restore compatibility with older patterns (RHEL-104135) +- coredump: wrap long lines, fix grammar in comments (RHEL-104135) +- coredump: get rid of _META_MANDATORY_MAX (RHEL-104135) +- coredump: use %d in kernel core pattern (RHEL-104135) +- coredump: also stop forwarding non-dumpable processes (RHEL-104135) +- coredump: get rid of a bogus assertion (RHEL-104135) +- coredump: add support for new %F PIDFD specifier (RHEL-104135) +- coredump: when %F/pidfd is used, again allow forwarding to containers (RHEL-104135) +- coredump: introduce an enum to wrap dumpable constants (RHEL-104135) +- Define helper to call PR_SET_DUMPABLE (RHEL-104135) +- coredump: fix 0-passed-as-pointer warning (RHEL-104135) + * Fri Aug 15 2025 systemd maintenance team - 257-13 - core/transaction: do not attempt to log "n/a" as a journal field (RHEL-106260)