From ce6f3446e8680eeb37f485cde12b9ce91b61ece5 Mon Sep 17 00:00:00 2001 From: Jan Macku Date: Fri, 26 Apr 2024 13:33:35 +0200 Subject: [PATCH] systemd-252-33 Resolves: RHEL-15501,RHEL-29430,RHEL-30372,RHEL-31783 --- 0717-execute-Pass-AT_FDCWD-instead-of-1.patch | 36 ++ ...it-update-list-of-supported-products.patch | 48 ++ ...ult-process-and-store-core-files-up-.patch | 46 ++ ...redump-keep-core-files-for-two-weeks.patch | 35 ++ ...e-test-happy-with-the-latest-OpenSSL.patch | 42 ++ ...t_ukify-use-raw-string-for-the-regex.patch | 32 ++ ...e-stacktraces-also-for-processes-run.patch | 530 ++++++++++++++++++ ...couple-of-tests-for-systemd-coredump.patch | 194 +++++++ ...d-the-subshell-expression-prematurel.patch | 54 ++ ...p-filter-fix-stack-overflow-with-all.patch | 63 +++ ...add-mask-for-all-using-UINT32_MAX-no.patch | 59 ++ ...-add-coverage-for-CoredumpFilter-all.patch | 26 + ...ate-journal-before-storing-coredumps.patch | 52 ++ ...th-the-fake-binary-before-killing-it.patch | 77 +++ ...ump-handling-in-containers-namespace.patch | 112 ++++ systemd-container-coredump.pp.bz2 | Bin 0 -> 315 bytes systemd.spec | 55 +- 17 files changed, 1460 insertions(+), 1 deletion(-) create mode 100644 0717-execute-Pass-AT_FDCWD-instead-of-1.patch create mode 100644 0718-ci-src-git-update-list-of-supported-products.patch create mode 100644 0719-coredump-by-default-process-and-store-core-files-up-.patch create mode 100644 0720-coredump-keep-core-files-for-two-weeks.patch create mode 100644 0721-ukify-make-the-test-happy-with-the-latest-OpenSSL.patch create mode 100644 0722-test_ukify-use-raw-string-for-the-regex.patch create mode 100644 0723-coredump-generate-stacktraces-also-for-processes-run.patch create mode 100644 0724-test-add-a-couple-of-tests-for-systemd-coredump.patch create mode 100644 0725-test-don-t-expand-the-subshell-expression-prematurel.patch create mode 100644 0726-coredump-filter-fix-stack-overflow-with-all.patch create mode 100644 0727-coredump-filter-add-mask-for-all-using-UINT32_MAX-no.patch create mode 100644 0728-test-add-coverage-for-CoredumpFilter-all.patch create mode 100644 0729-test-rotate-journal-before-storing-coredumps.patch create mode 100644 0730-test-sync-with-the-fake-binary-before-killing-it.patch create mode 100644 0731-test-check-coredump-handling-in-containers-namespace.patch create mode 100644 systemd-container-coredump.pp.bz2 diff --git a/0717-execute-Pass-AT_FDCWD-instead-of-1.patch b/0717-execute-Pass-AT_FDCWD-instead-of-1.patch new file mode 100644 index 0000000..f3b6b3f --- /dev/null +++ b/0717-execute-Pass-AT_FDCWD-instead-of-1.patch @@ -0,0 +1,36 @@ +From 7d3b9e98e22f92561c98f6bf838cc830324834e3 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Tue, 13 Dec 2022 10:50:01 +0000 +Subject: [PATCH] execute: Pass AT_FDCWD instead of -1 + +Let's enforce that callers pass AT_FDCWD as read_dfd to load_credential() +to avoid an assert() in read_full_file_full() if read_dfd is -1. + +(cherry picked from commit 661e4251a5b157d1aee1df98fbd2f0c95285ebba) + +Resolves: RHEL-31783 +--- + src/core/execute.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index ea36254241..13222ddea3 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -2662,6 +2662,7 @@ static int load_credential( + assert(id); + assert(path); + assert(unit); ++ assert(read_dfd >= 0 || read_dfd == AT_FDCWD); + assert(write_dfd >= 0); + assert(left); + +@@ -2888,7 +2889,7 @@ static int acquire_credentials( + lc->path, + lc->encrypted, + unit, +- -1, ++ AT_FDCWD, + dfd, + uid, + ownership_ok, diff --git a/0718-ci-src-git-update-list-of-supported-products.patch b/0718-ci-src-git-update-list-of-supported-products.patch new file mode 100644 index 0000000..2a6a543 --- /dev/null +++ b/0718-ci-src-git-update-list-of-supported-products.patch @@ -0,0 +1,48 @@ +From 06a6d5c5d5c6f3a9eb7ae55a7635d69158593181 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 11 Apr 2024 10:01:04 +0200 +Subject: [PATCH] ci(src-git): update list of supported products + +rhel-only + +Related: RHEL-30372 +--- + .github/tracker-validator.yml | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/.github/tracker-validator.yml b/.github/tracker-validator.yml +index f88cc0a572..31ef28f6ea 100644 +--- a/.github/tracker-validator.yml ++++ b/.github/tracker-validator.yml +@@ -12,17 +12,17 @@ products: + - rhel-9.2.0.z + - rhel-9.3.0 + - rhel-9.3.0.z +- - rhel-9.4.0 +- - rhel-9.4.0.z +- - rhel-9.5.0 +- - rhel-9.5.0.z +- - rhel-9.6.0 +- - rhel-9.6.0.z +- - rhel-9.7.0 +- - rhel-9.7.0.z +- - rhel-9.8.0 +- - rhel-9.8.0.z +- - rhel-9.9.0 +- - rhel-9.9.0.z +- - rhel-9.10.0 +- - rhel-9.10.0.z ++ - rhel-9.4 ++ - rhel-9.4.z ++ - rhel-9.5 ++ - rhel-9.5.z ++ - rhel-9.6 ++ - rhel-9.6.z ++ - rhel-9.7 ++ - rhel-9.7.z ++ - rhel-9.8 ++ - rhel-9.8.z ++ - rhel-9.9 ++ - rhel-9.9.z ++ - rhel-9.10 ++ - rhel-9.10.z diff --git a/0719-coredump-by-default-process-and-store-core-files-up-.patch b/0719-coredump-by-default-process-and-store-core-files-up-.patch new file mode 100644 index 0000000..48e96d9 --- /dev/null +++ b/0719-coredump-by-default-process-and-store-core-files-up-.patch @@ -0,0 +1,46 @@ +From f387005b548bee7695c663167f9bd54e45636f6b Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 5 Apr 2024 15:56:58 +0200 +Subject: [PATCH] coredump: by default process and store core files up to 1GiB + +This is a major departure from our previous policy of soft core file +limit set to 0, i.e. core file processing and storage by +systemd-coredump was disabled. However, that policy made very difficult +for people to debug sporadic crashes with no known reproducer. + +RHEL-only + +Resolves: RHEL-15501 +--- + src/core/system.conf.in | 2 +- + src/coredump/coredump.conf | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/core/system.conf.in b/src/core/system.conf.in +index 624746e512..5d1f6d24f0 100644 +--- a/src/core/system.conf.in ++++ b/src/core/system.conf.in +@@ -61,7 +61,7 @@ + #DefaultLimitFSIZE= + #DefaultLimitDATA= + #DefaultLimitSTACK= +-DefaultLimitCORE=0:infinity ++#DefaultLimitCORE= + #DefaultLimitRSS= + #DefaultLimitNOFILE=1024:{{HIGH_RLIMIT_NOFILE}} + #DefaultLimitAS= +diff --git a/src/coredump/coredump.conf b/src/coredump/coredump.conf +index 1f75d48d33..b934c2afb7 100644 +--- a/src/coredump/coredump.conf ++++ b/src/coredump/coredump.conf +@@ -17,8 +17,8 @@ + [Coredump] + #Storage=external + #Compress=yes +-#ProcessSizeMax=2G +-#ExternalSizeMax=2G ++ProcessSizeMax=1G ++ExternalSizeMax=1G + #JournalSizeMax=767M + #MaxUse= + #KeepFree= diff --git a/0720-coredump-keep-core-files-for-two-weeks.patch b/0720-coredump-keep-core-files-for-two-weeks.patch new file mode 100644 index 0000000..78ae54b --- /dev/null +++ b/0720-coredump-keep-core-files-for-two-weeks.patch @@ -0,0 +1,35 @@ +From e100e3855305a86367c690689833a460fa166428 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 5 Dec 2023 15:56:54 +0100 +Subject: [PATCH] coredump: keep core files for two weeks + +We have two mechanisms that remove old coredumps: systemd-coredump has +parameters based on disk use / remaining disk free, and systemd-tmpfiles does +cleanup based on time. The first mechanism should prevent us from using too much +disk space in case something is crashing continuously or there are very large +core files. + +The limit of 3 days makes it likely that the core file will be gone by the time +the admin looks at the issue. E.g. if something crashes on Friday, the coredump +would likely be gone before people are back on Monday to look at it. + +(cherry picked from commit f8d67130b8b492a1f2eedd07a3189051f98db648) + +Related: RHEL-15501 +--- + tmpfiles.d/systemd.conf.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tmpfiles.d/systemd.conf.in b/tmpfiles.d/systemd.conf.in +index fa838d8d06..958935a04f 100644 +--- a/tmpfiles.d/systemd.conf.in ++++ b/tmpfiles.d/systemd.conf.in +@@ -59,7 +59,7 @@ a+ /var/log/journal/%m/system.journal - - - - group:wheel:r-- + {% endif %} + + d /var/lib/systemd 0755 root root - +-d /var/lib/systemd/coredump 0755 root root 3d ++d /var/lib/systemd/coredump 0755 root root 2w + + d /var/lib/private 0700 root root - + d /var/log/private 0700 root root - diff --git a/0721-ukify-make-the-test-happy-with-the-latest-OpenSSL.patch b/0721-ukify-make-the-test-happy-with-the-latest-OpenSSL.patch new file mode 100644 index 0000000..bcd7e2f --- /dev/null +++ b/0721-ukify-make-the-test-happy-with-the-latest-OpenSSL.patch @@ -0,0 +1,42 @@ +From af01ea4040e2d6fdd15641793db688d01f2da046 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Sat, 23 Dec 2023 12:20:03 +0100 +Subject: [PATCH] ukify: make the test happy with the latest OpenSSL + +Which dropped some whitespaces in the output: + +$ openssl version +OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023) +$ openssl x509 -in cert.pem -text -noout | grep Issuer + Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd + +$ openssl version +OpenSSL 3.0.9 30 May 2023 (Library: OpenSSL 3.0.9 30 May 2023) +$ openssl x509 -in cert.pem -text -noout | grep Issuer + Issuer: C = XX, L = Default City, O = Default Company Ltd + +Making test-ukify unhappy: + +> assert 'Issuer: CN = SecureBoot signing key on host' in out +E AssertionError: assert 'Issuer: CN = SecureBoot signing key on host' in '<...snip...>Issuer: CN=SecureBoot signing key on host archlinux2\n...' + +(cherry picked from commit 338ed5bea4fcd0b5b1cdcfb96a789edf6251bbdd) + +Related: RHEL-30372 +--- + src/ukify/test/test_ukify.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ukify/test/test_ukify.py b/src/ukify/test/test_ukify.py +index 5a42a94799..31054eabea 100755 +--- a/src/ukify/test/test_ukify.py ++++ b/src/ukify/test/test_ukify.py +@@ -850,7 +850,7 @@ def test_key_cert_generation(tmpdir): + '-noout', + ], text = True) + assert 'Certificate' in out +- assert 'Issuer: CN = SecureBoot signing key on host' in out ++ assert re.search('Issuer: CN\s?=\s?SecureBoot signing key on host', out) + + if __name__ == '__main__': + sys.exit(pytest.main(sys.argv)) diff --git a/0722-test_ukify-use-raw-string-for-the-regex.patch b/0722-test_ukify-use-raw-string-for-the-regex.patch new file mode 100644 index 0000000..3ca8854 --- /dev/null +++ b/0722-test_ukify-use-raw-string-for-the-regex.patch @@ -0,0 +1,32 @@ +From 1c4640a859937b84d3f31dd2fa054f7d744d65f4 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Sat, 3 Feb 2024 15:46:26 +0100 +Subject: [PATCH] test_ukify: use raw string for the regex + +To get rid of the "invalid escape sequence" warning: + +=============================== warnings summary =============================== +../src/ukify/test/test_ukify.py:876 + ../src/ukify/test/test_ukify.py:876: SyntaxWarning: invalid escape sequence '\s' + assert re.search('Issuer: CN\s?=\s?SecureBoot signing key on host', out) + +(cherry picked from commit a0485e07b38b3b1195a92ba86a173742f2bb867a) + +Related: RHEL-30372 +--- + src/ukify/test/test_ukify.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ukify/test/test_ukify.py b/src/ukify/test/test_ukify.py +index 31054eabea..f233e25cf7 100755 +--- a/src/ukify/test/test_ukify.py ++++ b/src/ukify/test/test_ukify.py +@@ -850,7 +850,7 @@ def test_key_cert_generation(tmpdir): + '-noout', + ], text = True) + assert 'Certificate' in out +- assert re.search('Issuer: CN\s?=\s?SecureBoot signing key on host', out) ++ assert re.search(r'Issuer: CN\s?=\s?SecureBoot signing key on host', out) + + if __name__ == '__main__': + sys.exit(pytest.main(sys.argv)) diff --git a/0723-coredump-generate-stacktraces-also-for-processes-run.patch b/0723-coredump-generate-stacktraces-also-for-processes-run.patch new file mode 100644 index 0000000..dc335fc --- /dev/null +++ b/0723-coredump-generate-stacktraces-also-for-processes-run.patch @@ -0,0 +1,530 @@ +From d0427b44ecb56cdbc40ca156af8e013b64cce74d Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 18 Mar 2024 13:01:40 +0100 +Subject: [PATCH] coredump: generate stacktraces also for processes running in + containers w/o coredump forwarding + +Note that entering container namespace has to be explicitly enabled by +setting SYSTEMD_COREDUMP_ALLOW_NAMESPACE_CHANGE environment variable. + +RHEL-only + +Resolves: RHEL-29430 +--- + src/analyze/analyze-inspect-elf.c | 2 +- + src/basic/socket-util.c | 52 +++++++++++ + src/basic/socket-util.h | 15 ++++ + src/coredump/coredump.c | 143 +++++++++++++++++++----------- + src/shared/elf-util.c | 46 +++++++++- + src/shared/elf-util.h | 4 +- + 6 files changed, 202 insertions(+), 60 deletions(-) + +diff --git a/src/analyze/analyze-inspect-elf.c b/src/analyze/analyze-inspect-elf.c +index 155c611c71..b8074100a5 100644 +--- a/src/analyze/analyze-inspect-elf.c ++++ b/src/analyze/analyze-inspect-elf.c +@@ -30,7 +30,7 @@ static int analyze_elf(char **filenames, JsonFormatFlags json_flags) { + if (fd < 0) + return log_error_errno(fd, "Could not open \"%s\": %m", abspath); + +- r = parse_elf_object(fd, abspath, /* fork_disable_dump= */false, NULL, &package_metadata); ++ r = parse_elf_object(fd, -EBADF, UID_NOBODY, GID_NOBODY, abspath, /* fork_disable_dump= */false, NULL, &package_metadata); + if (r < 0) + return log_error_errno(r, "Parsing \"%s\" as ELF object failed: %m", abspath); + +diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c +index f39be19a59..1d86ca3f55 100644 +--- a/src/basic/socket-util.c ++++ b/src/basic/socket-util.c +@@ -41,6 +41,11 @@ + # define IDN_FLAGS 0 + #endif + ++/* From the kernel's include/net/scm.h */ ++#ifndef SCM_MAX_FD ++# define SCM_MAX_FD 253 ++#endif ++ + static const char* const socket_address_type_table[] = { + [SOCK_STREAM] = "Stream", + [SOCK_DGRAM] = "Datagram", +@@ -951,6 +956,53 @@ int getpeergroups(int fd, gid_t **ret) { + return (int) n; + } + ++ssize_t send_many_fds_iov_sa( ++ int transport_fd, ++ int *fds_array, size_t n_fds_array, ++ const struct iovec *iov, size_t iovlen, ++ const struct sockaddr *sa, socklen_t len, ++ int flags) { ++ ++ _cleanup_free_ struct cmsghdr *cmsg = NULL; ++ struct msghdr mh = { ++ .msg_name = (struct sockaddr*) sa, ++ .msg_namelen = len, ++ .msg_iov = (struct iovec *)iov, ++ .msg_iovlen = iovlen, ++ }; ++ ssize_t k; ++ ++ assert(transport_fd >= 0); ++ assert(fds_array || n_fds_array == 0); ++ ++ /* The kernel will reject sending more than SCM_MAX_FD FDs at once */ ++ if (n_fds_array > SCM_MAX_FD) ++ return -E2BIG; ++ ++ /* We need either an FD array or data to send. If there's nothing, return an error. */ ++ if (n_fds_array == 0 && !iov) ++ return -EINVAL; ++ ++ if (n_fds_array > 0) { ++ mh.msg_controllen = CMSG_SPACE(sizeof(int) * n_fds_array); ++ mh.msg_control = cmsg = malloc(mh.msg_controllen); ++ if (!cmsg) ++ return -ENOMEM; ++ ++ *cmsg = (struct cmsghdr) { ++ .cmsg_len = CMSG_LEN(sizeof(int) * n_fds_array), ++ .cmsg_level = SOL_SOCKET, ++ .cmsg_type = SCM_RIGHTS, ++ }; ++ memcpy(CMSG_DATA(cmsg), fds_array, sizeof(int) * n_fds_array); ++ } ++ k = sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags); ++ if (k < 0) ++ return (ssize_t) -errno; ++ ++ return k; ++} ++ + ssize_t send_one_fd_iov_sa( + int transport_fd, + int fd, +diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h +index 2e36e1a56b..61bf8ff32b 100644 +--- a/src/basic/socket-util.h ++++ b/src/basic/socket-util.h +@@ -153,6 +153,13 @@ int getpeercred(int fd, struct ucred *ucred); + int getpeersec(int fd, char **ret); + int getpeergroups(int fd, gid_t **ret); + ++ssize_t send_many_fds_iov_sa( ++ int transport_fd, ++ int *fds_array, size_t n_fds_array, ++ const struct iovec *iov, size_t iovlen, ++ const struct sockaddr *sa, socklen_t len, ++ int flags); ++ + ssize_t send_one_fd_iov_sa( + int transport_fd, + int fd, +@@ -163,6 +170,14 @@ int send_one_fd_sa(int transport_fd, + int fd, + const struct sockaddr *sa, socklen_t len, + int flags); ++static inline int send_many_fds( ++ int transport_fd, ++ int *fds_array, ++ size_t n_fds_array, ++ int flags) { ++ ++ return send_many_fds_iov_sa(transport_fd, fds_array, n_fds_array, NULL, 0, NULL, 0, flags); ++} + #define send_one_fd_iov(transport_fd, fd, iov, iovlen, flags) send_one_fd_iov_sa(transport_fd, fd, iov, iovlen, NULL, 0, flags) + #define send_one_fd(transport_fd, fd, flags) send_one_fd_iov_sa(transport_fd, fd, NULL, 0, NULL, 0, flags) + ssize_t receive_one_fd_iov(int transport_fd, struct iovec *iov, size_t iovlen, int flags, int *ret_fd); +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index b9c5f3ad04..dca78fa72c 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -24,6 +24,7 @@ + #include "coredump-vacuum.h" + #include "dirent-util.h" + #include "elf-util.h" ++#include "env-util.h" + #include "escape.h" + #include "fd-util.h" + #include "fileio.h" +@@ -36,6 +37,7 @@ + #include "main-func.h" + #include "memory-util.h" + #include "mkdir-label.h" ++#include "namespace-util.h" + #include "parse-util.h" + #include "process-util.h" + #include "signal-util.h" +@@ -130,6 +132,8 @@ typedef struct Context { + const char *meta[_META_MAX]; + size_t meta_size[_META_MAX]; + pid_t pid; ++ uid_t uid; ++ gid_t gid; + bool is_pid1; + bool is_journald; + } Context; +@@ -866,36 +870,11 @@ static int get_process_container_parent_cmdline(pid_t pid, char** cmdline) { + return 1; + } + +-static int change_uid_gid(const Context *context) { +- uid_t uid; +- gid_t gid; +- int r; +- +- r = parse_uid(context->meta[META_ARGV_UID], &uid); +- if (r < 0) +- return r; +- +- if (uid_is_system(uid)) { +- const char *user = "systemd-coredump"; +- +- r = get_user_creds(&user, &uid, &gid, NULL, NULL, 0); +- if (r < 0) { +- log_warning_errno(r, "Cannot resolve %s user. Proceeding to dump core as root: %m", user); +- uid = gid = 0; +- } +- } else { +- r = parse_gid(context->meta[META_ARGV_GID], &gid); +- if (r < 0) +- return r; +- } +- +- return drop_privileges(uid, gid, 0); +-} +- + static int submit_coredump( + const Context *context, + struct iovec_wrapper *iovw, +- int input_fd) { ++ int input_fd, ++ int mntns_fd) { + + _cleanup_(json_variant_unrefp) JsonVariant *json_metadata = NULL; + _cleanup_close_ int coredump_fd = -1, coredump_node_fd = -1; +@@ -938,15 +917,6 @@ static int submit_coredump( + /* Vacuum again, but exclude the coredump we just created */ + (void) coredump_vacuum(coredump_node_fd >= 0 ? coredump_node_fd : coredump_fd, arg_keep_free, arg_max_use); + +- /* Now, let's drop privileges to become the user who owns the segfaulted process +- * and allocate the coredump memory under the user's uid. This also ensures that +- * the credentials journald will see are the ones of the coredumping user, thus +- * making sure the user gets access to the core dump. Let's also get rid of all +- * capabilities, if we run as root, we won't need them anymore. */ +- r = change_uid_gid(context); +- if (r < 0) +- return log_error_errno(r, "Failed to drop privileges: %m"); +- + /* Try to get a stack trace if we can */ + if (coredump_size > arg_process_size_max) + log_debug("Not generating stack trace: core size %"PRIu64" is greater " +@@ -956,12 +926,23 @@ static int submit_coredump( + bool skip = startswith(context->meta[META_COMM], "systemd-coredum"); /* COMM is 16 bytes usually */ + + (void) parse_elf_object(coredump_fd, ++ mntns_fd, ++ context->uid, ++ context->gid, + context->meta[META_EXE], + /* fork_disable_dump= */ skip, /* avoid loops */ + &stacktrace, + &json_metadata); + } + ++ /* Now, let's drop privileges to become the user who owns the segfaulted process. This also ensures ++ * that the credentials journald will see are the ones of the coredumping user, thus making sure ++ * the user gets access to the core dump. Let's also get rid of all capabilities, if we run as root, ++ * we won't need them anymore. */ ++ r = drop_privileges(context->uid, context->gid, 0); ++ if (r < 0) ++ return log_error_errno(r, "Failed to drop privileges: %m"); ++ + log: + core_message = strjoina("Process ", context->meta[META_ARGV_PID], + " (", context->meta[META_COMM], ") of user ", +@@ -1094,6 +1075,15 @@ static int save_context(Context *context, const struct iovec_wrapper *iovw) { + if (r < 0) + return log_error_errno(r, "Failed to parse PID \"%s\": %m", context->meta[META_ARGV_PID]); + ++ r = parse_uid(context->meta[META_ARGV_UID], &context->uid); ++ if (r < 0) ++ return log_error_errno(r, "Failed to parse UID \"%s\": %m", context->meta[META_ARGV_UID]); ++ ++ r = parse_gid(context->meta[META_ARGV_GID], &context->gid); ++ if (r < 0) ++ return log_error_errno(r, "Failed to parse GID \"%s\": %m", context->meta[META_ARGV_GID]); ++ ++ + 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); +@@ -1102,11 +1092,11 @@ static int save_context(Context *context, const struct iovec_wrapper *iovw) { + } + + static int process_socket(int fd) { +- _cleanup_close_ int input_fd = -1; ++ _cleanup_close_ int input_fd = -EBADF, mntns_fd = -EBADF; + Context context = {}; + struct iovec_wrapper iovw = {}; + struct iovec iovec; +- int r; ++ int iterations = 0, r; + + assert(fd >= 0); + +@@ -1146,23 +1136,39 @@ static int process_socket(int fd) { + goto finish; + } + +- /* The final zero-length datagram carries the file descriptor and tells us ++ /* The final zero-length datagram carries the file descriptors and tells us + * that we're done. */ + if (n == 0) { + struct cmsghdr *found; + + free(iovec.iov_base); + +- found = cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, CMSG_LEN(sizeof(int))); +- if (!found) { +- cmsg_close_all(&mh); +- r = log_error_errno(SYNTHETIC_ERRNO(EBADMSG), +- "Coredump file descriptor missing."); +- goto finish; ++ found = cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, CMSG_LEN(sizeof(int) * 2)); ++ if (found) { ++ int fds[2] = { -EBADF, -EBADF }; ++ ++ memcpy(fds, CMSG_DATA(found), sizeof(int) * 2); ++ ++ assert(mntns_fd < 0); ++ ++ /* Maybe we already got coredump FD in previous iteration? */ ++ safe_close(input_fd); ++ ++ input_fd = fds[0]; ++ mntns_fd = fds[1]; ++ ++ /* We have all FDs we need let's take a shortcut here. */ ++ break; ++ } else { ++ found = cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, CMSG_LEN(sizeof(int))); ++ if (found) ++ input_fd = *CMSG_DATA(found); + } + +- assert(input_fd < 0); +- input_fd = *(int*) CMSG_DATA(found); ++ /* This is the first message that carries file descriptors, maybe there will be one more that actually contains array of descriptors. */ ++ if (iterations++ == 0) ++ continue; ++ + break; + } else + cmsg_close_all(&mh); +@@ -1177,7 +1183,11 @@ static int process_socket(int fd) { + } + + /* Make sure we got all data we really need */ +- assert(input_fd >= 0); ++ if (input_fd < 0) { ++ r = log_error_errno(SYNTHETIC_ERRNO(EBADMSG), ++ "Coredump file descriptor missing."); ++ goto finish; ++ } + + r = save_context(&context, &iovw); + if (r < 0) +@@ -1192,15 +1202,15 @@ static int process_socket(int fd) { + goto finish; + } + +- r = submit_coredump(&context, &iovw, input_fd); ++ r = submit_coredump(&context, &iovw, input_fd, mntns_fd); + + finish: + iovw_free_contents(&iovw, true); + return r; + } + +-static int send_iovec(const struct iovec_wrapper *iovw, int input_fd) { +- _cleanup_close_ int fd = -1; ++static int send_iovec(const struct iovec_wrapper *iovw, int input_fd, int mntns_fd) { ++ _cleanup_close_ int fd = -EBADF; + int r; + + assert(iovw); +@@ -1256,6 +1266,12 @@ static int send_iovec(const struct iovec_wrapper *iovw, int input_fd) { + if (r < 0) + return log_error_errno(r, "Failed to send coredump fd: %m"); + ++ if (mntns_fd >= 0) { ++ r = send_many_fds(fd, (int[]) { input_fd, mntns_fd }, 2, 0); ++ if (r < 0) ++ return log_error_errno(r, "Failed to send coredump fds: %m"); ++ } ++ + return 0; + } + +@@ -1428,7 +1444,7 @@ static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) { + static int process_kernel(int argc, char* argv[]) { + Context context = {}; + struct iovec_wrapper *iovw; +- int r; ++ int r, mntns_fd = -EBADF; + + /* When we're invoked by the kernel, stdout/stderr are closed which is dangerous because the fds + * could get reallocated. To avoid hard to debug issues, let's instead bind stdout/stderr to +@@ -1462,6 +1478,25 @@ static int process_kernel(int argc, char* argv[]) { + log_open(); + } + ++ r = in_same_namespace(getpid_cached(), context.pid, NAMESPACE_PID); ++ if (r < 0) ++ log_debug_errno(r, "Failed to check pidns of crashing process, ignoring: %m"); ++ ++ if (r == 0 && getenv_bool("SYSTEMD_COREDUMP_ALLOW_NAMESPACE_CHANGE") > 0) { ++ r = namespace_open(context.pid, NULL, &mntns_fd, NULL, NULL, NULL); ++ if (r < 0) ++ return log_error_errno(r, "Failed to open mntns of crashing process: %m"); ++ } else { ++ /* Crashing process is not running in the container or changing namespace is disabled, but we ++ still need to send mount namespace fd along side coredump fd so let's just open our own ++ mount namespace. Entering it will be NOP but that is OK. */ ++ r = namespace_open(getpid_cached(), NULL, &mntns_fd, NULL, NULL, NULL); ++ if (r < 0) ++ return log_error_errno(r, "Failed to open our mntns: %m"); ++ } ++ ++ assert(mntns_fd >= 0 && fd_is_ns(mntns_fd, CLONE_NEWNS) > 0); ++ + /* If this is PID 1 disable coredump collection, we'll unlikely be able to process + * it later on. + * +@@ -1474,9 +1509,9 @@ static int process_kernel(int argc, char* argv[]) { + } + + if (context.is_journald || context.is_pid1) +- r = submit_coredump(&context, iovw, STDIN_FILENO); ++ r = submit_coredump(&context, iovw, STDIN_FILENO, mntns_fd); + else +- r = send_iovec(iovw, STDIN_FILENO); ++ r = send_iovec(iovw, STDIN_FILENO, mntns_fd); + + finish: + iovw = iovw_free_free(iovw); +diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c +index bde5013b92..6a2969732d 100644 +--- a/src/shared/elf-util.c ++++ b/src/shared/elf-util.c +@@ -12,6 +12,7 @@ + #include + + #include "alloc-util.h" ++#include "capability-util.h" + #include "dlfcn-util.h" + #include "elf-util.h" + #include "errno-util.h" +@@ -21,9 +22,12 @@ + #include "hexdecoct.h" + #include "io-util.h" + #include "macro.h" ++#include "namespace-util.h" + #include "process-util.h" + #include "rlimit-util.h" + #include "string-util.h" ++#include "uid-alloc-range.h" ++#include "user-util.h" + #include "util.h" + + #define FRAMES_MAX 64 +@@ -752,11 +756,27 @@ static int parse_elf(int fd, const char *executable, char **ret, JsonVariant **r + return 0; + } + +-int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, char **ret, JsonVariant **ret_package_metadata) { ++static int core_change_uid_gid(uid_t uid, gid_t gid) { ++ uid_t u = uid; ++ gid_t g = gid; ++ int r; ++ ++ if (uid_is_system(u)) { ++ const char *user = "systemd-coredump"; ++ ++ r = get_user_creds(&user, &u, &g, NULL, NULL, 0); ++ if (r < 0) ++ log_warning_errno(r, "Cannot resolve %s user, ignoring: %m", user); ++ } ++ ++ return drop_privileges(u, g, 0); ++} ++ ++int parse_elf_object(int fd, int mntns_fd, uid_t uid, gid_t gid, const char *executable, bool fork_disable_dump, char **ret, JsonVariant **ret_package_metadata) { + _cleanup_close_pair_ int error_pipe[2] = { -1, -1 }, return_pipe[2] = { -1, -1 }, json_pipe[2] = { -1, -1 }; + _cleanup_(json_variant_unrefp) JsonVariant *package_metadata = NULL; + _cleanup_free_ char *buf = NULL; +- int r; ++ int flags, r; + + assert(fd >= 0); + +@@ -784,6 +804,10 @@ int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, cha + return r; + } + ++ flags = FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_USERNS|FORK_WAIT|FORK_REOPEN_LOG; ++ if (mntns_fd >= 0) ++ flags &= ~(FORK_CLOSE_ALL_FDS|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_USERNS); ++ + /* Parsing possibly malformed data is crash-happy, so fork. In case we crash, + * the core file will not be lost, and the messages will still be attached to + * the journal. Reading the elf object might be slow, but it still has an upper +@@ -793,7 +817,7 @@ int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, cha + r = safe_fork_full("(sd-parse-elf)", + (int[]){ fd, error_pipe[1], return_pipe[1], json_pipe[1] }, + 4, +- FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_USERNS|FORK_WAIT|FORK_REOPEN_LOG, ++ flags, + NULL); + if (r < 0) { + if (r == -EPROTO) { /* We should have the errno from the child, but don't clobber original error */ +@@ -811,6 +835,22 @@ int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, cha + return r; + } + if (r == 0) { ++ if (mntns_fd >= 0) { ++ r = namespace_enter(/* pidns_fd = */ -EBADF, ++ mntns_fd, ++ /* netns_fd = */ -EBADF, ++ /* userns_fd = */ -EBADF, ++ /* root_fd = */ -EBADF); ++ if (r < 0) ++ log_notice_errno(r, "Failed to enter mount namespace of crashing process, ignoring: %m"); ++ } ++ ++ if (uid != UID_NOBODY && gid != GID_NOBODY) { ++ r = core_change_uid_gid(uid, gid); ++ if (r < 0) ++ log_notice_errno(r, "Failed to drop privileges, ignoring: %m"); ++ } ++ + /* 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)); +diff --git a/src/shared/elf-util.h b/src/shared/elf-util.h +index b28e64cea6..350464941f 100644 +--- a/src/shared/elf-util.h ++++ b/src/shared/elf-util.h +@@ -10,9 +10,9 @@ int dlopen_elf(void); + /* Parse an ELF object in a forked process, so that errors while iterating over + * untrusted and potentially malicious data do not propagate to the main caller's process. + * If fork_disable_dump, the child process will not dump core if it crashes. */ +-int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, char **ret, JsonVariant **ret_package_metadata); ++int parse_elf_object(int fd, int mntns_fd, uid_t uid, gid_t gid, const char *executable, bool fork_disable_dump, char **ret, JsonVariant **ret_package_metadata); + #else +-static inline int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, char **ret, JsonVariant **ret_package_metadata) { ++static inline int parse_elf_object(int fd, int mntns_fd, uid_t uid, gid_t gid, const char *executable, bool fork_disable_dump, char **ret, JsonVariant **ret_package_metadata) { + return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "elfutils disabled, parsing ELF objects not supported"); + } + #endif diff --git a/0724-test-add-a-couple-of-tests-for-systemd-coredump.patch b/0724-test-add-a-couple-of-tests-for-systemd-coredump.patch new file mode 100644 index 0000000..293a927 --- /dev/null +++ b/0724-test-add-a-couple-of-tests-for-systemd-coredump.patch @@ -0,0 +1,194 @@ +From 6307dbb9cb25fd5a2131c043b89a52f032817178 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 21 Mar 2023 23:19:41 +0100 +Subject: [PATCH] test: add a couple of tests for systemd-coredump + +(cherry picked from commit aadbd81f7ffbc313d0541c15455211dddeedbfde) + +Related: RHEL-29430 +--- + test/units/testsuite-74.coredump.sh | 175 ++++++++++++++++++++++++++++ + 1 file changed, 175 insertions(+) + create mode 100755 test/units/testsuite-74.coredump.sh + +diff --git a/test/units/testsuite-74.coredump.sh b/test/units/testsuite-74.coredump.sh +new file mode 100755 +index 0000000000..6a299ecbfb +--- /dev/null ++++ b/test/units/testsuite-74.coredump.sh +@@ -0,0 +1,175 @@ ++#!/usr/bin/env bash ++# SPDX-License-Identifier: LGPL-2.1-or-later ++set -eux ++set -o pipefail ++ ++# Make sure the binary name fits into 15 characters ++CORE_TEST_BIN="/tmp/test-dump" ++CORE_TEST_UNPRIV_BIN="/tmp/test-usr-dump" ++MAKE_DUMP_SCRIPT="/tmp/make-dump" ++# Unset $PAGER so we don't have to use --no-pager everywhere ++export PAGER= ++ ++at_exit() { ++ rm -fv -- "$CORE_TEST_BIN" "$CORE_TEST_UNPRIV_BIN" "$MAKE_DUMP_SCRIPT" ++} ++ ++trap at_exit EXIT ++ ++if systemd-detect-virt -cq; then ++ echo "Running in a container, skipping the systemd-coredump test..." ++ exit 0 ++fi ++ ++# Check that we're the ones to receive coredumps ++sysctl kernel.core_pattern | grep systemd-coredump ++ ++# Prepare "fake" binaries for coredumps, so we can properly exercise ++# the matching stuff too ++cp -vf /bin/sleep "${CORE_TEST_BIN:?}" ++cp -vf /bin/sleep "${CORE_TEST_UNPRIV_BIN:?}" ++# Simple script that spawns given "fake" binary and then kills it with ++# given signal ++cat >"${MAKE_DUMP_SCRIPT:?}" <<\EOF ++#!/bin/bash -ex ++ ++bin="${1:?}" ++sig="${2:?}" ++ ++ulimit -c unlimited ++"$bin" infinity & ++pid=$! ++sleep 1 ++kill -s "$sig" "$pid" ++# This should always fail ++! wait "$pid" ++EOF ++chmod +x "$MAKE_DUMP_SCRIPT" ++ ++# Privileged stuff ++[[ "$(id -u)" -eq 0 ]] ++# Trigger a couple of coredumps ++"$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGTRAP" ++"$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGABRT" ++# In the tests we store the coredumps in journals, so let's generate a couple ++# with Storage=external as well ++mkdir -p /run/systemd/coredump.conf.d/ ++printf '[Coredump]\nStorage=external' >/run/systemd/coredump.conf.d/99-external.conf ++"$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGTRAP" ++"$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGABRT" ++rm -fv /run/systemd/coredump.conf.d/99-external.conf ++# Wait a bit for the coredumps to get processed ++timeout 30 bash -c "while [[ $(coredumpctl list -q --no-legend $CORE_TEST_BIN | wc -l) -lt 4 ]]; do sleep 1; done" ++ ++coredumpctl ++SYSTEMD_LOG_LEVEL=debug coredumpctl ++coredumpctl --help ++coredumpctl --version ++coredumpctl --no-pager --no-legend ++coredumpctl --all ++coredumpctl -1 ++coredumpctl -n 1 ++coredumpctl --reverse ++coredumpctl -F COREDUMP_EXE ++coredumpctl --json=short | jq ++coredumpctl --json=pretty | jq ++coredumpctl --json=off ++coredumpctl --root=/ ++coredumpctl --directory=/var/log/journal ++coredumpctl --file="/var/log/journal/$(/tmp/core.redirected ++test -s /tmp/core.redirected ++coredumpctl dump -o /tmp/core.output "${CORE_TEST_BIN##*/}" ++test -s /tmp/core.output ++rm -f /tmp/core.{output,redirected} ++ ++# Unprivileged stuff ++# Related issue: https://github.com/systemd/systemd/issues/26912 ++UNPRIV_CMD=(systemd-run --user --wait --pipe -M "testuser@.host" --) ++# Trigger a couple of coredumps as an unprivileged user ++"${UNPRIV_CMD[@]}" "$MAKE_DUMP_SCRIPT" "$CORE_TEST_UNPRIV_BIN" "SIGTRAP" ++"${UNPRIV_CMD[@]}" "$MAKE_DUMP_SCRIPT" "$CORE_TEST_UNPRIV_BIN" "SIGABRT" ++# In the tests we store the coredumps in journals, so let's generate a couple ++# with Storage=external as well ++mkdir -p /run/systemd/coredump.conf.d/ ++printf '[Coredump]\nStorage=external' >/run/systemd/coredump.conf.d/99-external.conf ++"${UNPRIV_CMD[@]}" "$MAKE_DUMP_SCRIPT" "$CORE_TEST_UNPRIV_BIN" "SIGTRAP" ++"${UNPRIV_CMD[@]}" "$MAKE_DUMP_SCRIPT" "$CORE_TEST_UNPRIV_BIN" "SIGABRT" ++rm -fv /run/systemd/coredump.conf.d/99-external.conf ++# Wait a bit for the coredumps to get processed ++timeout 30 bash -c "while [[ $(coredumpctl list -q --no-legend $CORE_TEST_UNPRIV_BIN | wc -l) -lt 4 ]]; do sleep 1; done" ++ ++# root should see coredumps from both binaries ++coredumpctl info "$CORE_TEST_UNPRIV_BIN" ++coredumpctl info "${CORE_TEST_UNPRIV_BIN##*/}" ++# The test user should see only their own coredumps ++"${UNPRIV_CMD[@]}" coredumpctl ++"${UNPRIV_CMD[@]}" coredumpctl info "$CORE_TEST_UNPRIV_BIN" ++"${UNPRIV_CMD[@]}" coredumpctl info "${CORE_TEST_UNPRIV_BIN##*/}" ++(! "${UNPRIV_CMD[@]}" coredumpctl info --all "$CORE_TEST_BIN") ++(! "${UNPRIV_CMD[@]}" coredumpctl info --all "${CORE_TEST_BIN##*/}") ++# We should have a couple of externally stored coredumps ++"${UNPRIV_CMD[@]}" coredumpctl --field=COREDUMP_FILENAME | tee /tmp/coredumpctl.out ++grep "/var/lib/systemd/coredump/core" /tmp/coredumpctl.out ++rm -f /tmp/coredumpctl.out ++ ++"${UNPRIV_CMD[@]}" coredumpctl debug --debugger=/bin/true "$CORE_TEST_UNPRIV_BIN" ++"${UNPRIV_CMD[@]}" coredumpctl debug --debugger=/bin/true --debugger-arguments="-this --does --not 'do anything' -a -t --all" "${CORE_TEST_UNPRIV_BIN##*/}" ++ ++"${UNPRIV_CMD[@]}" coredumpctl dump "$CORE_TEST_UNPRIV_BIN" >/tmp/core.redirected ++test -s /tmp/core.redirected ++"${UNPRIV_CMD[@]}" coredumpctl dump -o /tmp/core.output "${CORE_TEST_UNPRIV_BIN##*/}" ++test -s /tmp/core.output ++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 ++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 "$$" ++coredumpctl info COREDUMP_HOSTNAME="mymachine" ++ ++ ++(! coredumpctl --hello-world) ++(! coredumpctl -n 0) ++(! coredumpctl -n -1) ++(! coredumpctl --file=/dev/null) ++(! coredumpctl --since=0) ++(! coredumpctl --until='') ++(! coredumpctl --since=today --until=yesterday) ++(! coredumpctl --directory=/ --root=/) ++(! coredumpctl --json=foo) ++(! coredumpctl -F foo -F bar) ++(! coredumpctl list 0) ++(! coredumpctl list -- -1) ++(! coredumpctl list '') ++(! coredumpctl info /../.~=) ++(! coredumpctl info '') ++(! coredumpctl dump --output=/dev/full "$CORE_TEST_BIN") ++(! coredumpctl dump --output=/dev/null --output=/dev/null "$CORE_TEST_BIN") ++(! coredumpctl debug --debugger=/bin/false) ++(! coredumpctl debug --debugger=/bin/true --debugger-arguments='"') diff --git a/0725-test-don-t-expand-the-subshell-expression-prematurel.patch b/0725-test-don-t-expand-the-subshell-expression-prematurel.patch new file mode 100644 index 0000000..beff65a --- /dev/null +++ b/0725-test-don-t-expand-the-subshell-expression-prematurel.patch @@ -0,0 +1,54 @@ +From 687c8da38e766fe35a2710b0539576710c345f34 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Sat, 25 Mar 2023 12:02:15 +0100 +Subject: [PATCH] test: don't expand the subshell expression prematurely + +We need to expand the subshell expression during the `bash -c` +invocation, not before, to take the desired effect, as now it expands to: + +timeout 30 bash -c 'while [[ 0 -eq 0 ]]; do sleep 1; done' + +instead of the expected: + +timeout 30 bash -c 'while [[ $(coredumpctl list -q --no-legend 770 | wc -l) -eq 0 ]]; do sleep 1; done' + +Follow-up to aadbd81f7f. + +(cherry picked from commit 0b189ac84c432a085a1f10139260cec6b5032523) + +Related: RHEL-29430 +--- + test/units/testsuite-74.coredump.sh | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/test/units/testsuite-74.coredump.sh b/test/units/testsuite-74.coredump.sh +index 6a299ecbfb..3910abe0ec 100755 +--- a/test/units/testsuite-74.coredump.sh ++++ b/test/units/testsuite-74.coredump.sh +@@ -59,7 +59,7 @@ printf '[Coredump]\nStorage=external' >/run/systemd/coredump.conf.d/99-external. + "$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGABRT" + rm -fv /run/systemd/coredump.conf.d/99-external.conf + # Wait a bit for the coredumps to get processed +-timeout 30 bash -c "while [[ $(coredumpctl list -q --no-legend $CORE_TEST_BIN | wc -l) -lt 4 ]]; do sleep 1; done" ++timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $CORE_TEST_BIN | wc -l) -lt 4 ]]; do sleep 1; done" + + coredumpctl + SYSTEMD_LOG_LEVEL=debug coredumpctl +@@ -116,7 +116,7 @@ printf '[Coredump]\nStorage=external' >/run/systemd/coredump.conf.d/99-external. + "${UNPRIV_CMD[@]}" "$MAKE_DUMP_SCRIPT" "$CORE_TEST_UNPRIV_BIN" "SIGABRT" + rm -fv /run/systemd/coredump.conf.d/99-external.conf + # Wait a bit for the coredumps to get processed +-timeout 30 bash -c "while [[ $(coredumpctl list -q --no-legend $CORE_TEST_UNPRIV_BIN | wc -l) -lt 4 ]]; do sleep 1; done" ++timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $CORE_TEST_UNPRIV_BIN | wc -l) -lt 4 ]]; do sleep 1; done" + + # root should see coredumps from both binaries + coredumpctl info "$CORE_TEST_UNPRIV_BIN" +@@ -149,7 +149,7 @@ rm -f /tmp/core.{output,redirected} + 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" ++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" + diff --git a/0726-coredump-filter-fix-stack-overflow-with-all.patch b/0726-coredump-filter-fix-stack-overflow-with-all.patch new file mode 100644 index 0000000..901a847 --- /dev/null +++ b/0726-coredump-filter-fix-stack-overflow-with-all.patch @@ -0,0 +1,63 @@ +From f46d65bba43c519d8d2ed8fab86ea765166c0e72 Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Wed, 26 Apr 2023 14:18:04 +0100 +Subject: [PATCH] coredump filter: fix stack overflow with =all + +We translate 'all' to UNIT64_MAX, which has a lot more 'f's. Use the +helper macro, since a decimal uint64_t will always be >> than a hex +representation. + +root@image:~# systemd-run -t --property CoredumpFilter=all ls /tmp +Running as unit: run-u13.service +Press ^] three times within 1s to disconnect TTY. +*** stack smashing detected ***: terminated +[137256.320511] systemd[1]: run-u13.service: Main process exited, code=dumped, status=6/ABRT +[137256.320850] systemd[1]: run-u13.service: Failed with result 'core-dump'. + +(cherry picked from commit 37232d55a7bcace37280e28b207c85f5ca9b3f6b) + +Related: RHEL-29430 +--- + src/basic/macro.h | 4 ++++ + src/shared/coredump-util.c | 5 +++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/basic/macro.h b/src/basic/macro.h +index 2d378454a2..6893a1ff32 100644 +--- a/src/basic/macro.h ++++ b/src/basic/macro.h +@@ -268,6 +268,10 @@ static inline int __coverity_check_and_return__(int condition) { + + #define sizeof_field(struct_type, member) sizeof(((struct_type *) 0)->member) + ++/* Maximum buffer size needed for formatting an unsigned integer type as hex, including space for '0x' ++ * prefix and trailing NUL suffix. */ ++#define HEXADECIMAL_STR_MAX(type) (2 + sizeof(type) * 2 + 1) ++ + /* Returns the number of chars needed to format variables of the specified type as a decimal string. Adds in + * extra space for a negative '-' prefix for signed types. Includes space for the trailing NUL. */ + #define DECIMAL_STR_MAX(type) \ +diff --git a/src/shared/coredump-util.c b/src/shared/coredump-util.c +index a0b648bf79..aaf3e16eff 100644 +--- a/src/shared/coredump-util.c ++++ b/src/shared/coredump-util.c +@@ -3,6 +3,7 @@ + #include "coredump-util.h" + #include "extract-word.h" + #include "fileio.h" ++#include "stdio-util.h" + #include "string-table.h" + + static const char *const coredump_filter_table[_COREDUMP_FILTER_MAX] = { +@@ -65,9 +66,9 @@ int coredump_filter_mask_from_string(const char *s, uint64_t *ret) { + } + + int set_coredump_filter(uint64_t value) { +- char t[STRLEN("0xFFFFFFFF")]; ++ char t[HEXADECIMAL_STR_MAX(uint64_t)]; + +- sprintf(t, "0x%"PRIx64, value); ++ xsprintf(t, "0x%"PRIx64, value); + + return write_string_file("/proc/self/coredump_filter", t, + WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER); diff --git a/0727-coredump-filter-add-mask-for-all-using-UINT32_MAX-no.patch b/0727-coredump-filter-add-mask-for-all-using-UINT32_MAX-no.patch new file mode 100644 index 0000000..3cc03cd --- /dev/null +++ b/0727-coredump-filter-add-mask-for-all-using-UINT32_MAX-no.patch @@ -0,0 +1,59 @@ +From 8db17468f2c0dd07d5e9618e3b49fddda26724c6 Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Wed, 26 Apr 2023 14:19:33 +0100 +Subject: [PATCH] coredump filter: add mask for 'all' using UINT32_MAX, not + UINT64_MAX + +The kernel returns ERANGE when UINT64_MAX is passed. Create a mask +and use UINT32_max, which is accepted, so that future bits will also +be set. + +(cherry picked from commit 7f3bb8f20dcccaceea8b1ee05f0560b81162037b) + +Related: RHEL-29430 +--- + src/shared/coredump-util.c | 2 +- + src/shared/coredump-util.h | 3 +++ + src/test/test-coredump-util.c | 2 ++ + 3 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/shared/coredump-util.c b/src/shared/coredump-util.c +index aaf3e16eff..7a44816834 100644 +--- a/src/shared/coredump-util.c ++++ b/src/shared/coredump-util.c +@@ -43,7 +43,7 @@ int coredump_filter_mask_from_string(const char *s, uint64_t *ret) { + } + + if (streq(n, "all")) { +- m = UINT64_MAX; ++ m = COREDUMP_FILTER_MASK_ALL; + continue; + } + +diff --git a/src/shared/coredump-util.h b/src/shared/coredump-util.h +index 09e7ed443f..f4d4098136 100644 +--- a/src/shared/coredump-util.h ++++ b/src/shared/coredump-util.h +@@ -22,6 +22,9 @@ typedef enum CoredumpFilter { + 1u << COREDUMP_FILTER_ELF_HEADERS | \ + 1u << COREDUMP_FILTER_PRIVATE_HUGE) + ++/* 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 ++ + 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/test/test-coredump-util.c b/src/test/test-coredump-util.c +index 40b68df9f4..87dc371a88 100644 +--- a/src/test/test-coredump-util.c ++++ b/src/test/test-coredump-util.c +@@ -23,6 +23,8 @@ TEST(coredump_filter_mask_from_string) { + uint64_t f; + assert_se(coredump_filter_mask_from_string("default", &f) == 0); + assert_se(f == COREDUMP_FILTER_MASK_DEFAULT); ++ assert_se(coredump_filter_mask_from_string("all", &f) == 0); ++ assert_se(f == COREDUMP_FILTER_MASK_ALL); + + assert_se(coredump_filter_mask_from_string(" default\tdefault\tdefault ", &f) == 0); + assert_se(f == COREDUMP_FILTER_MASK_DEFAULT); diff --git a/0728-test-add-coverage-for-CoredumpFilter-all.patch b/0728-test-add-coverage-for-CoredumpFilter-all.patch new file mode 100644 index 0000000..37107eb --- /dev/null +++ b/0728-test-add-coverage-for-CoredumpFilter-all.patch @@ -0,0 +1,26 @@ +From 27538bb6224cdcd2ee04284b496449e0d2755e7b Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Wed, 26 Apr 2023 14:32:04 +0100 +Subject: [PATCH] test: add coverage for CoredumpFilter=all + +(cherry picked from commit cf636aa59eb8c848ed04d5b08aac0acf3f6683d9) + +Related: RHEL-29430 +--- + test/units/testsuite-74.coredump.sh | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/test/units/testsuite-74.coredump.sh b/test/units/testsuite-74.coredump.sh +index 3910abe0ec..0e5d050f45 100755 +--- a/test/units/testsuite-74.coredump.sh ++++ b/test/units/testsuite-74.coredump.sh +@@ -153,6 +153,9 @@ timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $$ | wc -l) -eq + coredumpctl info "$$" + coredumpctl info COREDUMP_HOSTNAME="mymachine" + ++# This used to cause a stack overflow ++systemd-run -t --property CoredumpFilter=all ls /tmp ++systemd-run -t --property CoredumpFilter=default ls /tmp + + (! coredumpctl --hello-world) + (! coredumpctl -n 0) diff --git a/0729-test-rotate-journal-before-storing-coredumps.patch b/0729-test-rotate-journal-before-storing-coredumps.patch new file mode 100644 index 0000000..267b189 --- /dev/null +++ b/0729-test-rotate-journal-before-storing-coredumps.patch @@ -0,0 +1,52 @@ +From cada47a50ea898f092c430508656ed717ab78dba Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 24 May 2023 10:31:41 +0900 +Subject: [PATCH] test: rotate journal before storing coredumps + +Hopefully fixes the failure like +https://jenkins-systemd.apps.ocp.cloud.ci.centos.org/job/upstream-vagrant-archlinux-sanitizers/2558/ +--- +[ 66.708894] testsuite-74.sh[728]: + coredumpctl --json=off +[ 66.709344] testsuite-74.sh[826]: TIME PID UID GID SIG COREFILE EXE SIZE +[ 66.709773] testsuite-74.sh[826]: Tue 2023-05-23 22:10:17 UTC 739 0 0 SIGTRAP journal /tmp/test-dump - +[ 66.711134] testsuite-74.sh[826]: Tue 2023-05-23 22:10:18 UTC 747 0 0 SIGABRT journal /tmp/test-dump - +[ 66.711789] testsuite-74.sh[826]: Tue 2023-05-23 22:10:19 UTC 763 0 0 SIGTRAP present /tmp/test-dump 53.5K +[ 66.712460] testsuite-74.sh[826]: Tue 2023-05-23 22:10:20 UTC 776 0 0 SIGABRT present /tmp/test-dump 53.3K +[ 66.713505] testsuite-74.sh[728]: + coredumpctl --root=/ +[ 66.714144] testsuite-74.sh[828]: TIME PID UID GID SIG COREFILE EXE SIZE +[ 66.714535] testsuite-74.sh[828]: Tue 2023-05-23 22:10:17 UTC 739 0 0 SIGTRAP journal /tmp/test-dump - +[ 66.715208] testsuite-74.sh[828]: Tue 2023-05-23 22:10:18 UTC 747 0 0 SIGABRT journal /tmp/test-dump - +[ 66.715907] testsuite-74.sh[828]: Tue 2023-05-23 22:10:19 UTC 763 0 0 SIGTRAP present /tmp/test-dump 53.5K +[ 66.716565] testsuite-74.sh[828]: Tue 2023-05-23 22:10:20 UTC 776 0 0 SIGABRT present /tmp/test-dump 53.3K +[ 66.717494] testsuite-74.sh[728]: + coredumpctl --directory=/var/log/journal +[ 66.718188] testsuite-74.sh[830]: TIME PID UID GID SIG COREFILE EXE SIZE +[ 66.882072] testsuite-74.sh[830]: Tue 2023-05-23 22:10:17 UTC 739 0 0 SIGTRAP journal /tmp/test-dump - +[ 66.882642] testsuite-74.sh[830]: Tue 2023-05-23 22:10:18 UTC 747 0 0 SIGABRT journal /tmp/test-dump - +[ 66.883450] testsuite-74.sh[830]: Tue 2023-05-23 22:10:19 UTC 763 0 0 SIGTRAP present /tmp/test-dump 53.5K +[ 66.883944] testsuite-74.sh[830]: Tue 2023-05-23 22:10:20 UTC 776 0 0 SIGABRT present /tmp/test-dump 53.3K +[ 66.885448] testsuite-74.sh[728]: + coredumpctl --file=/var/log/journal/2e1ed84be19a4e22adfc99ad849be1f6/system.journal +[ 66.885989] testsuite-74.sh[728]: + at_exit +[ 66.894162] coredumpctl[833]: No coredumps found. +--- + +(cherry picked from commit 5c4e96c28c4a2193ba0dd459ea3366614f9b262f) + +Related: RHEL-29430 +--- + test/units/testsuite-74.coredump.sh | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/test/units/testsuite-74.coredump.sh b/test/units/testsuite-74.coredump.sh +index 0e5d050f45..d5039b70f4 100755 +--- a/test/units/testsuite-74.coredump.sh ++++ b/test/units/testsuite-74.coredump.sh +@@ -21,6 +21,9 @@ if systemd-detect-virt -cq; then + exit 0 + fi + ++# To make all coredump entries stored in system.journal. ++journalctl --rotate ++ + # Check that we're the ones to receive coredumps + sysctl kernel.core_pattern | grep systemd-coredump + diff --git a/0730-test-sync-with-the-fake-binary-before-killing-it.patch b/0730-test-sync-with-the-fake-binary-before-killing-it.patch new file mode 100644 index 0000000..b543afa --- /dev/null +++ b/0730-test-sync-with-the-fake-binary-before-killing-it.patch @@ -0,0 +1,77 @@ +From 803900bb830163c13539a70ea56d82d27b06f52b Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 2 Jun 2023 13:24:32 +0200 +Subject: [PATCH] test: sync with the fake binary before killing it +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On faster machines we might be too fast and kill the fake binary during +fork() which then makes kernel report a "wrong" binary in the coredump, +e.g.: + +[ 31.408078] testsuite-74.sh[548]: + /tmp/make-dump /tmp/test-dump SIGTRAP +[ 31.409720] testsuite-74.sh[560]: + bin=/tmp/test-dump +[ 31.409720] testsuite-74.sh[560]: + sig=SIGTRAP +[ 31.409720] testsuite-74.sh[560]: + ulimit -c unlimited +[ 31.409720] testsuite-74.sh[560]: + pid=561 +[ 31.409720] testsuite-74.sh[560]: + sleep 1 +[ 31.409720] testsuite-74.sh[560]: + kill -s SIGTRAP 561 +[ 31.409720] testsuite-74.sh[560]: + wait 561 +[ 31.491757] systemd[1]: Created slice system-systemd\x2dcoredump.slice. +[ 31.524488] systemd[1]: Started systemd-coredump@0-563-0.service. +[ 31.616372] systemd-coredump[564]: [🡕] Process 561 (make-dump) of user 0 dumped core. + + Stack trace of thread 561: + #0 0x00007ff86bb49af7 _Fork (libc.so.6 + 0xd4af7) + #1 0x00007ff86bb4965f __libc_fork (libc.so.6 + 0xd465f) + #2 0x000055e88011b0ad make_child (bash + 0x550ad) + #3 0x000055e8800fd05f n/a (bash + 0x3705f) + #4 0x000055e880100116 execute_command_internal (bash + 0x3a116) + #5 0x000055e8801011f2 execute_command_internal (bash + 0x3b1f2) + #6 0x000055e8801025b6 execute_command (bash + 0x3c5b6) + #7 0x000055e8800f134b reader_loop (bash + 0x2b34b) + #8 0x000055e8800e757d main (bash + 0x2157d) + #9 0x00007ff86ba98850 n/a (libc.so.6 + 0x23850) + #10 0x00007ff86ba9890a __libc_start_main (libc.so.6 + 0x2390a) + #11 0x000055e8800e83b5 _start (bash + 0x223b5) + ELF object binary architecture: AMD x86-64 +[ 31.666617] testsuite-74.sh[560]: /tmp/make-dump: line 12: 561 Trace/breakpoint trap (core dumped) "$bin" infinity +... +$ coredumpctl list --file system.journal +TIME PID UID GID SIG COREFILE EXE SIZE +Fri 2023-06-02 10:42:10 CEST 561 0 0 SIGTRAP journal /usr/bin/bash - +Fri 2023-06-02 10:42:11 CEST 570 0 0 SIGABRT journal /tmp/test-dump - +Fri 2023-06-02 10:42:12 CEST 582 0 0 SIGTRAP missing /tmp/test-dump - +Fri 2023-06-02 10:42:13 CEST 593 0 0 SIGABRT missing /tmp/test-dump - + +(cherry picked from commit 1326d2dd059132760b40acb7a715ecc9ff08bd35) + +Related: RHEL-29430 +--- + test/units/testsuite-74.coredump.sh | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/test/units/testsuite-74.coredump.sh b/test/units/testsuite-74.coredump.sh +index d5039b70f4..d30fd73717 100755 +--- a/test/units/testsuite-74.coredump.sh ++++ b/test/units/testsuite-74.coredump.sh +@@ -42,7 +42,17 @@ sig="${2:?}" + ulimit -c unlimited + "$bin" infinity & + pid=$! +-sleep 1 ++# Sync with the "fake" binary, so we kill it once it's fully forked off, ++# otherwise we might kill it during fork and kernel would then report ++# "wrong" binary name (i.e. $MAKE_DUMP_SCRIPT instead of $CORE_TEST_BIN). ++# In this case, wait until the "fake" binary (sleep in this case) enters ++# the "interruptible sleep" state, at which point it should be ready ++# to be sacrificed. ++for _ in {0..9}; do ++ read -ra self_stat <"/proc/$pid/stat" ++ [[ "${self_stat[2]}" == S ]] && break ++ sleep .5 ++done + kill -s "$sig" "$pid" + # This should always fail + ! wait "$pid" diff --git a/0731-test-check-coredump-handling-in-containers-namespace.patch b/0731-test-check-coredump-handling-in-containers-namespace.patch new file mode 100644 index 0000000..d42bd4e --- /dev/null +++ b/0731-test-check-coredump-handling-in-containers-namespace.patch @@ -0,0 +1,112 @@ +From 623e09d910fffd6824d77203b8d9b016c0dd6208 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 25 Apr 2024 19:50:10 +0200 +Subject: [PATCH] test: check coredump handling in containers & namespaces + +This is partially based on upstream's 097e28736a, which tests coredump +forwarding (that we don't have in RHEL 9). It also provides basic +coverage for RHEL-29430 (generating stack traces for processes in +containers without coredump fowarding). + +rhel-only +Related: RHEL-29430 +--- + test/test-functions | 2 +- + test/units/testsuite-74.coredump.sh | 64 ++++++++++++++++++++++++++++- + 2 files changed, 64 insertions(+), 2 deletions(-) + +diff --git a/test/test-functions b/test/test-functions +index 1608644cbb..947f8589c5 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -2619,7 +2619,7 @@ inst_binary() { + # ls, stat - pulls in nss_systemd with certain options (like ls -l) when + # nsswitch.conf uses [SUCCESS=merge] (like on Arch Linux) + # tar - called by machinectl in TEST-25 +- if get_bool "$IS_BUILT_WITH_ASAN" && [[ "$bin" =~ /(chown|getent|login|ls|stat|su|tar|useradd|userdel)$ ]]; then ++ if get_bool "$IS_BUILT_WITH_ASAN" && [[ "$bin" =~ /(chown|getent|login|id|ls|stat|su|tar|useradd|userdel)$ ]]; then + wrap_binary=1 + fi + +diff --git a/test/units/testsuite-74.coredump.sh b/test/units/testsuite-74.coredump.sh +index d30fd73717..1093cad8a9 100755 +--- a/test/units/testsuite-74.coredump.sh ++++ b/test/units/testsuite-74.coredump.sh +@@ -74,6 +74,68 @@ rm -fv /run/systemd/coredump.conf.d/99-external.conf + # Wait a bit for the coredumps to get processed + timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $CORE_TEST_BIN | wc -l) -lt 4 ]]; do sleep 1; done" + ++# RHEL9: following part is taken out of 097e28736aed9280dfac0f8e8096deca71bac813 but slightly tweaked, since ++# in RHEL9 we don't have the support for coredump forwarding ++CONTAINER="testsuite-74-container" ++TESTUSER_UID="$(id -u testuser)" ++TESTUSER_GID="$(id -g testuser)" ++ ++mkdir -p "/var/lib/machines/$CONTAINER" ++mkdir -p "/run/systemd/system/systemd-nspawn@$CONTAINER.service.d" ++# Bind-mounting /etc into the container kinda defeats the purpose of --volatile=, ++# but we need the ASan-related overrides scattered across /etc ++cat > "/run/systemd/system/systemd-nspawn@$CONTAINER.service.d/override.conf" << EOF ++[Service] ++ExecStart= ++ExecStart=systemd-nspawn --quiet --link-journal=try-guest --keep-unit --machine=%i --boot \ ++ --volatile=yes --directory=/ --bind-ro=/etc --inaccessible=/etc/machine-id ++EOF ++systemctl daemon-reload ++ ++machinectl start "$CONTAINER" ++timeout 60 bash -xec "until systemd-run -M '$CONTAINER' -q --wait --pipe true; do sleep .5; done" ++machinectl copy-to "$CONTAINER" "$MAKE_DUMP_SCRIPT" ++ ++run_namespaced_coredump_tests() { ++ local TS ++ ++ # Make a couple of coredumps in a full-fleged container ++ TS="$(date +"%s.%N")" ++ [[ "$(coredumpctl list --since="@$TS" -q --no-legend /usr/bin/sleep | wc -l)" -eq 0 ]] ++ [[ "$(coredumpctl list --since="@$TS" -q --no-legend /usr/bin/sleep _UID="$TESTUSER_UID" | wc -l)" -eq 0 ]] ++ systemd-run -M "testuser@$CONTAINER" --user -q --wait --pipe "$MAKE_DUMP_SCRIPT" "/usr/bin/sleep" "SIGABRT" ++ systemd-run -M "$CONTAINER" -q --wait --pipe "$MAKE_DUMP_SCRIPT" "/usr/bin/sleep" "SIGTRAP" ++ # Wait a bit for the coredumps to get processed ++ timeout 30 bash -c "while [[ \$(coredumpctl list --since=@$TS -q --no-legend /usr/bin/sleep | wc -l) -ne 2 ]]; do sleep 1; done" ++ coredumpctl list ++ [[ "$(coredumpctl list --since="@$TS" -q --no-legend /usr/bin/sleep _UID="$TESTUSER_UID" _GID="$TESTUSER_GID" | wc -l)" -eq 1 ]] ++ ++ # Simplified version of the above - not a full container, just a mount & pid namespace ++ TS="$(date +"%s.%N")" ++ unshare --mount --pid --fork --mount-proc /bin/bash -xec "$MAKE_DUMP_SCRIPT /usr/bin/sleep SIGABRT" ++ timeout 30 bash -c "while [[ \$(coredumpctl list --since=@$TS -q --no-legend /usr/bin/sleep | wc -l) -ne 1 ]]; do sleep 1; done" ++ TS="$(date +"%s.%N")" ++ unshare --setuid="$TESTUSER_UID" --setgid="$TESTUSER_GID" --mount --pid --fork --mount-proc /bin/bash -xec "$MAKE_DUMP_SCRIPT /usr/bin/sleep SIGABRT" ++ timeout 30 bash -c "while [[ \$(coredumpctl list --since=@$TS -q --no-legend /usr/bin/sleep _UID=$TESTUSER_UID _GID=$TESTUSER_GID | wc -l) -ne 1 ]]; do sleep 1; done" ++} ++ ++# First, run the tests with default systemd-coredumpd settings ++run_namespaced_coredump_tests ++ ++# And now with SYSTEMD_COREDUMP_ALLOW_NAMESPACE_CHANGE=1 (RHEL-only) ++cat >/tmp/coredump-handler.sh <cOGaB-vfdbAOwN4CB1vum3>r=dZtEiFI#7jHUi%!Yo*8N&k^pc* z1oEOciVYb@@-jV$d@-|4CVLvbV3CH#Ax^mR%M}_0cfDwfS^%rn^^-O_tD`!+VOP4! zOHj;Us1&+{Q^OHO1*0&gU{BTG1KdzqY@h59SSx)BD;=kj6bNlG=WDLKLvY+LzwQ?b zglWADjM%FVSZ2$D(+p};UNSNbrKuP=w*KQWpo15YCzvEd;#UEP71bPr!QvM5We}f> Nxgwk>NL6xoD1g$!feZiu literal 0 HcmV?d00001 diff --git a/systemd.spec b/systemd.spec index 2b25abb..92c676f 100644 --- a/systemd.spec +++ b/systemd.spec @@ -12,6 +12,10 @@ %global system_unit_dir %{pkgdir}/system %global user_unit_dir %{pkgdir}/user +# defining macros needed by SELinux +%global selinuxtype targeted +%global modulename systemd-container-coredump + # Bootstrap may be needed to break intercircular dependencies with # cryptsetup, e.g. when re-building cryptsetup on a json-c SONAME-bump. %bcond_with bootstrap @@ -21,7 +25,7 @@ Name: systemd Url: https://systemd.io Version: 252 -Release: 32%{?dist} +Release: 33%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -70,6 +74,8 @@ Source25: rc.local %global rhel_nns_version 0.5 Source26: https://gitlab.com/mschmidt2/rhel-net-naming-sysattrs/-/archive/v%{rhel_nns_version}/rhel-net-naming-sysattrs-v%{rhel_nns_version}.tar.gz +Source27: %{modulename}.pp.bz2 + %if 0 GIT_DIR=../../src/systemd/.git git format-patch-ab --no-signature -M -N v235..v235-stable i=1; for j in 00*patch; do printf "Patch%04d: %s\n" $i $j; i=$((i+1));done|xclip @@ -799,6 +805,21 @@ Patch0713: 0713-random-seed-don-t-refresh-EFI-random-seed-from-rando.patch Patch0714: 0714-bootctl-downgrade-graceful-messages-to-LOG_NOTICE.patch Patch0715: 0715-units-rename-rework-systemd-boot-system-token.servic.patch Patch0716: 0716-bootctl-split-out-setting-of-system-token-into-funct.patch +Patch0717: 0717-execute-Pass-AT_FDCWD-instead-of-1.patch +Patch0718: 0718-ci-src-git-update-list-of-supported-products.patch +Patch0719: 0719-coredump-by-default-process-and-store-core-files-up-.patch +Patch0720: 0720-coredump-keep-core-files-for-two-weeks.patch +Patch0721: 0721-ukify-make-the-test-happy-with-the-latest-OpenSSL.patch +Patch0722: 0722-test_ukify-use-raw-string-for-the-regex.patch +Patch0723: 0723-coredump-generate-stacktraces-also-for-processes-run.patch +Patch0724: 0724-test-add-a-couple-of-tests-for-systemd-coredump.patch +Patch0725: 0725-test-don-t-expand-the-subshell-expression-prematurel.patch +Patch0726: 0726-coredump-filter-fix-stack-overflow-with-all.patch +Patch0727: 0727-coredump-filter-add-mask-for-all-using-UINT32_MAX-no.patch +Patch0728: 0728-test-add-coverage-for-CoredumpFilter-all.patch +Patch0729: 0729-test-rotate-journal-before-storing-coredumps.patch +Patch0730: 0730-test-sync-with-the-fake-binary-before-killing-it.patch +Patch0731: 0731-test-check-coredump-handling-in-containers-namespace.patch # Downstream-only patches (9000–9999) @@ -867,11 +888,18 @@ BuildRequires: git-core %if 0%{?have_gnu_efi} BuildRequires: gnu-efi gnu-efi-devel %endif +BuildRequires: selinux-policy-devel Requires(post): coreutils Requires(post): sed Requires(post): acl Requires(post): grep + +# selinux +Requires(post): libselinux-utils +Requires(post): policycoreutils +Requires(post): policycoreutils-python-utils + # systemd-machine-id-setup requires libssl Requires(post): openssl-libs Requires(pre): coreutils @@ -1362,6 +1390,9 @@ install -m 0644 -D -t %{buildroot}%{_rpmconfigdir}/fileattrs/ %{SOURCE22} install -m 0755 -D -t %{buildroot}%{_rpmconfigdir}/ %{SOURCE23} install -m 0755 -D -t %{buildroot}%{_rpmconfigdir}/ %{SOURCE24} +# install policy modules +install -m 0644 -D -t %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype}/ %{SOURCE27} + %find_lang %{name} # Split files in build root into rpms. See split-files.py for the @@ -1464,6 +1495,9 @@ chmod g+s /{run,var}/log/journal/{,${machine_id}} &>/dev/null || : # Apply ACL to the journal directory setfacl -Rnm g:wheel:rx,d:g:wheel:rx,g:adm:rx,d:g:adm:rx /var/log/journal/ &>/dev/null || : +# Install our own selinux-policy module that allows systemd-coredump access to containers +%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2 + [ $1 -eq 1 ] || exit 0 # We reset the enablement of all services upon initial installation @@ -1608,6 +1642,7 @@ systemd-hwdb update &>/dev/null || : %global _docdir_fmt %{name} %files -f %{name}.lang -f .file-list-main +%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.* %doc %{_pkgdocdir} %exclude %{_pkgdocdir}/LICENSE.* %license LICENSE.GPL2 LICENSE.LGPL2.1 @@ -1627,6 +1662,7 @@ systemd-hwdb update &>/dev/null || : %ghost %dir %attr(0755,-,-) /etc/systemd/system/system-update.target.wants %ghost %dir %attr(0755,-,-) /etc/systemd/system/timers.target.wants %ghost %dir %attr(0755,-,-) /var/lib/rpm-state/systemd +%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename} %files libs -f .file-list-libs %license LICENSE.LGPL2.1 @@ -1664,6 +1700,23 @@ systemd-hwdb update &>/dev/null || : %{_prefix}/lib/dracut/modules.d/70rhel-net-naming-sysattrs/* %changelog +* Fri Apr 26 2024 systemd maintenance team - 252-33 +- execute: Pass AT_FDCWD instead of -1 (RHEL-31783) +- ci(src-git): update list of supported products (RHEL-30372) +- coredump: by default process and store core files up to 1GiB (RHEL-15501) +- coredump: keep core files for two weeks (RHEL-15501) +- ukify: make the test happy with the latest OpenSSL (RHEL-30372) +- test_ukify: use raw string for the regex (RHEL-30372) +- coredump: generate stacktraces also for processes running in containers w/o coredump forwarding (RHEL-29430) +- test: add a couple of tests for systemd-coredump (RHEL-29430) +- test: don't expand the subshell expression prematurely (RHEL-29430) +- coredump filter: fix stack overflow with =all (RHEL-29430) +- coredump filter: add mask for 'all' using UINT32_MAX, not UINT64_MAX (RHEL-29430) +- test: add coverage for CoredumpFilter=all (RHEL-29430) +- test: rotate journal before storing coredumps (RHEL-29430) +- test: sync with the fake binary before killing it (RHEL-29430) +- test: check coredump handling in containers & namespaces (RHEL-29430) + * Mon Mar 18 2024 Jan Macku - 252-32 - rebase rhel-net-naming-sysattrs to v0.5