diff --git a/backport-core-exec-do-not-crash-with-UtmpMode-user-without-Us.patch b/backport-core-exec-do-not-crash-with-UtmpMode-user-without-Us.patch new file mode 100644 index 0000000..d14ee6b --- /dev/null +++ b/backport-core-exec-do-not-crash-with-UtmpMode-user-without-Us.patch @@ -0,0 +1,75 @@ +From fa972e8681159a34ffc9c114e4fe3538a7f69046 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 19 Feb 2024 13:04:28 +0900 +Subject: [PATCH] core/exec: do not crash with UtmpMode=user without User= + setting + +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=2264404. + +Replaces #31356. + +(cherry picked from commit d42b81f93f81e45f7a4053c6522ec3a2145ff136) +(cherry picked from commit cba1060f8854fd9a11dac8e2b02126d2f3bb14ba) +(cherry picked from commit 74ffb11efc851ecc291766abce8a1052746e715e) + +Conflict:add saved_uid +Reference:https://github.com/systemd/systemd-stable/commit/fa972e8681159a34ffc9c114e4fe3538a7f69046 + +--- + src/core/execute.c | 13 ++++++++++++- + src/shared/utmp-wtmp.c | 1 + + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index f6e2142..f4b4642 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -2962,6 +2962,7 @@ static int exec_child( + #if HAVE_APPARMOR + bool use_apparmor = false; + #endif ++ uid_t saved_uid = getuid(); + uid_t uid = UID_INVALID; + gid_t gid = GID_INVALID; + size_t n_fds; +@@ -3252,6 +3253,16 @@ static int exec_child( + } + + if (context->utmp_id) { ++ _cleanup_free_ char *username_alloc = NULL; ++ ++ if (!username && context->utmp_mode == EXEC_UTMP_USER) { ++ username_alloc = uid_to_name(uid_is_valid(uid) ? uid : saved_uid); ++ if (!username_alloc) { ++ *exit_status = EXIT_USER; ++ return log_oom(); ++ } ++ } ++ + const char *line = context->tty_path ? + (path_startswith(context->tty_path, "/dev/") ?: context->tty_path) : + NULL; +@@ -3260,7 +3271,7 @@ static int exec_child( + context->utmp_mode == EXEC_UTMP_INIT ? INIT_PROCESS : + context->utmp_mode == EXEC_UTMP_LOGIN ? LOGIN_PROCESS : + USER_PROCESS, +- username); ++ username ?: username_alloc); + } + + if (uid_is_valid(uid)) { +diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c +index 646f449..4c1d479 100644 +--- a/src/shared/utmp-wtmp.c ++++ b/src/shared/utmp-wtmp.c +@@ -202,6 +202,7 @@ int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line + int r; + + assert(id); ++ assert(ut_type != USER_PROCESS || user); + + init_timestamp(&store, 0); + +-- +2.33.0 + diff --git a/backport-resolved-limit-the-number-of-signature-validations-i.patch b/backport-resolved-limit-the-number-of-signature-validations-i.patch new file mode 100644 index 0000000..f83c1d1 --- /dev/null +++ b/backport-resolved-limit-the-number-of-signature-validations-i.patch @@ -0,0 +1,191 @@ +From 7886eea2425fe7773cc012da0b2e266e33d4be12 Mon Sep 17 00:00:00 2001 +From: Ronan Pigott +Date: Sat, 24 Feb 2024 18:21:24 -0700 +Subject: [PATCH] resolved: limit the number of signature validations in a + transaction + +It has been demonstrated that tolerating an unbounded number of dnssec +signature validations is a bad idea. It is easy for a maliciously +crafted DNS reply to contain as many keytag collisions as desired, +causing us to iterate every dnskey and signature combination in vain. + +The solution is to impose a maximum number of validations we will +tolerate. While collisions are not hard to craft, I still expect they +are unlikely in the wild so it should be safe to pick fairly small +values. + +Here two limits are imposed: one on the maximum number of invalid +signatures encountered per rrset, and another on the total number of +validations performed per transaction. + +(cherry picked from commit 67d0ce8843d612a2245d0966197d4f528b911b66) +(cherry picked from commit 1ebdb19ff194120109b08bbf888bdcc502f83211) +(cherry picked from commit 2f5edffa8ffd5210165ebe7604f07d23f375fe9a) + +Conflict:adapt context +Reference:https://github.com/systemd/systemd-stable/commit/7886eea2425fe7773cc012da0b2e266e33d4be12 + +--- + src/resolve/resolved-dns-dnssec.c | 16 ++++++++++++++-- + src/resolve/resolved-dns-dnssec.h | 9 ++++++++- + src/resolve/resolved-dns-transaction.c | 19 ++++++++++++++++--- + 3 files changed, 38 insertions(+), 6 deletions(-) + +diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c +index fc375a8..7d8f0f2 100644 +--- a/src/resolve/resolved-dns-dnssec.c ++++ b/src/resolve/resolved-dns-dnssec.c +@@ -988,6 +988,7 @@ int dnssec_verify_rrset_search( + DnsResourceRecord **ret_rrsig) { + + bool found_rrsig = false, found_invalid = false, found_expired_rrsig = false, found_unsupported_algorithm = false; ++ unsigned nvalidations = 0; + DnsResourceRecord *rrsig; + int r; + +@@ -1033,6 +1034,14 @@ int dnssec_verify_rrset_search( + if (realtime == USEC_INFINITY) + realtime = now(CLOCK_REALTIME); + ++ /* Have we seen an unreasonable number of invalid signaures? */ ++ if (nvalidations > DNSSEC_INVALID_MAX) { ++ if (ret_rrsig) ++ *ret_rrsig = NULL; ++ *result = DNSSEC_TOO_MANY_VALIDATIONS; ++ return (int) nvalidations; ++ } ++ + /* Yay, we found a matching RRSIG with a matching + * DNSKEY, awesome. Now let's verify all entries of + * the RRSet against the RRSIG and DNSKEY +@@ -1042,6 +1051,8 @@ int dnssec_verify_rrset_search( + if (r < 0) + return r; + ++ nvalidations++; ++ + switch (one_result) { + + case DNSSEC_VALIDATED: +@@ -1052,7 +1063,7 @@ int dnssec_verify_rrset_search( + *ret_rrsig = rrsig; + + *result = one_result; +- return 0; ++ return (int) nvalidations; + + case DNSSEC_INVALID: + /* If the signature is invalid, let's try another +@@ -1099,7 +1110,7 @@ int dnssec_verify_rrset_search( + if (ret_rrsig) + *ret_rrsig = NULL; + +- return 0; ++ return (int) nvalidations; + } + + int dnssec_has_rrsig(DnsAnswer *a, const DnsResourceKey *key) { +@@ -2302,6 +2313,7 @@ static const char* const dnssec_result_table[_DNSSEC_RESULT_MAX] = { + [DNSSEC_FAILED_AUXILIARY] = "failed-auxiliary", + [DNSSEC_NSEC_MISMATCH] = "nsec-mismatch", + [DNSSEC_INCOMPATIBLE_SERVER] = "incompatible-server", ++ [DNSSEC_TOO_MANY_VALIDATIONS] = "too-many-validations", + }; + DEFINE_STRING_TABLE_LOOKUP(dnssec_result, DnssecResult); + +diff --git a/src/resolve/resolved-dns-dnssec.h b/src/resolve/resolved-dns-dnssec.h +index dfee723..4d6abee 100644 +--- a/src/resolve/resolved-dns-dnssec.h ++++ b/src/resolve/resolved-dns-dnssec.h +@@ -9,12 +9,13 @@ typedef enum DnssecVerdict DnssecVerdict; + #include "resolved-dns-rr.h" + + enum DnssecResult { +- /* These five are returned by dnssec_verify_rrset() */ ++ /* These six are returned by dnssec_verify_rrset() */ + DNSSEC_VALIDATED, + DNSSEC_VALIDATED_WILDCARD, /* Validated via a wildcard RRSIG, further NSEC/NSEC3 checks necessary */ + DNSSEC_INVALID, + DNSSEC_SIGNATURE_EXPIRED, + DNSSEC_UNSUPPORTED_ALGORITHM, ++ DNSSEC_TOO_MANY_VALIDATIONS, + + /* These two are added by dnssec_verify_rrset_search() */ + DNSSEC_NO_SIGNATURE, +@@ -45,6 +46,12 @@ enum DnssecVerdict { + /* The longest digest we'll ever generate, of all digest algorithms we support */ + #define DNSSEC_HASH_SIZE_MAX (MAX(20, 32)) + ++/* The most invalid signatures we will tolerate for a single rrset */ ++#define DNSSEC_INVALID_MAX 5 ++ ++/* The total number of signature validations we will tolerate for a single transaction */ ++#define DNSSEC_VALIDATION_MAX 64 ++ + int dnssec_rrsig_match_dnskey(DnsResourceRecord *rrsig, DnsResourceRecord *dnskey, bool revoked_ok); + int dnssec_key_match_rrsig(const DnsResourceKey *key, DnsResourceRecord *rrsig); + +diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c +index 3a3c078..3ebff39 100644 +--- a/src/resolve/resolved-dns-transaction.c ++++ b/src/resolve/resolved-dns-transaction.c +@@ -2809,11 +2809,14 @@ static int dnssec_validate_records( + DnsTransaction *t, + Phase phase, + bool *have_nsec, ++ unsigned *nvalidations, + DnsAnswer **validated) { + + DnsResourceRecord *rr; + int r; + ++ assert(nvalidations); ++ + /* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */ + + DNS_ANSWER_FOREACH(rr, t->answer) { +@@ -2848,6 +2851,7 @@ static int dnssec_validate_records( + r = dnssec_verify_rrset_search(t->answer, rr->key, t->validated_keys, USEC_INFINITY, &result, &rrsig); + if (r < 0) + return r; ++ *nvalidations += r; + + log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result)); + +@@ -3025,7 +3029,8 @@ static int dnssec_validate_records( + DNSSEC_SIGNATURE_EXPIRED, + DNSSEC_NO_SIGNATURE)) + manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, rr->key); +- else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */ ++ else /* DNSSEC_MISSING_KEY, DNSSEC_UNSUPPORTED_ALGORITHM, ++ or DNSSEC_TOO_MANY_VALIDATIONS */ + manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, rr->key); + + /* This is a primary response to our question, and it failed validation. +@@ -3119,13 +3124,21 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { + return r; + + phase = DNSSEC_PHASE_DNSKEY; +- for (;;) { ++ for (unsigned nvalidations = 0;;) { + bool have_nsec = false; + +- r = dnssec_validate_records(t, phase, &have_nsec, &validated); ++ r = dnssec_validate_records(t, phase, &have_nsec, &nvalidations, &validated); + if (r <= 0) + return r; + ++ if (nvalidations > DNSSEC_VALIDATION_MAX) { ++ /* This reply requires an onerous number of signature validations to verify. Let's ++ * not waste our time trying, as this shouldn't happen for well-behaved domains ++ * anyway. */ ++ t->answer_dnssec_result = DNSSEC_TOO_MANY_VALIDATIONS; ++ return 0; ++ } ++ + /* Try again as long as we managed to achieve something */ + if (r == 1) + continue; +-- +2.33.0 + diff --git a/backport-resolved-reduce-the-maximum-nsec3-iterations-to-100.patch b/backport-resolved-reduce-the-maximum-nsec3-iterations-to-100.patch new file mode 100644 index 0000000..287c504 --- /dev/null +++ b/backport-resolved-reduce-the-maximum-nsec3-iterations-to-100.patch @@ -0,0 +1,41 @@ +From 156e519d990a5662c719a1cbe80c6a02a2b9115f Mon Sep 17 00:00:00 2001 +From: Ronan Pigott +Date: Sun, 25 Feb 2024 00:23:32 -0700 +Subject: [PATCH] resolved: reduce the maximum nsec3 iterations to 100 + +According to RFC9267, the 2500 value is not helpful, and in fact it can +be harmful to permit a large number of iterations. Combined with limits +on the number of signature validations, I expect this will mitigate the +impact of maliciously crafted domains designed to cause excessive +cryptographic work. + +(cherry picked from commit eba291124bc11f03732d1fc468db3bfac069f9cb) +(cherry picked from commit 572692f0bdd6a3fabe3dd4a3e8e5565cc69b5e14) +(cherry picked from commit 9899281c59a91f19c8b39362d203e997d2faf233) + +Conflict:NA +Reference:https://github.com/systemd/systemd-stable/commit/156e519d990a5662c719a1cbe80c6a02a2b9115f + +--- + src/resolve/resolved-dns-dnssec.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c +index e9ff94847a..d48d8a9297 100644 +--- a/src/resolve/resolved-dns-dnssec.c ++++ b/src/resolve/resolved-dns-dnssec.c +@@ -27,8 +27,9 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_KEY*, EC_KEY_free, NULL); + /* Permit a maximum clock skew of 1h 10min. This should be enough to deal with DST confusion */ + #define SKEW_MAX (1*USEC_PER_HOUR + 10*USEC_PER_MINUTE) + +-/* Maximum number of NSEC3 iterations we'll do. RFC5155 says 2500 shall be the maximum useful value */ +-#define NSEC3_ITERATIONS_MAX 2500 ++/* Maximum number of NSEC3 iterations we'll do. RFC5155 says 2500 shall be the maximum useful value, but ++ * RFC9276 ยง 3.2 says that we should reduce the acceptable iteration count */ ++#define NSEC3_ITERATIONS_MAX 100 + + /* + * The DNSSEC Chain of trust: +-- +2.33.0 + diff --git a/backport-utmp-remove-dev-from-line.patch b/backport-utmp-remove-dev-from-line.patch new file mode 100644 index 0000000..5b6f2ef --- /dev/null +++ b/backport-utmp-remove-dev-from-line.patch @@ -0,0 +1,44 @@ +From 09534e85b5c51c664077637e7e8c7c68dec52972 Mon Sep 17 00:00:00 2001 +From: Vincent Bernat +Date: Mon, 18 Oct 2021 20:58:43 +0200 +Subject: [PATCH] utmp: remove /dev from line + +utmp(5) says `ut_line` is the device name minus the leading "/dev/". Therefore, +remove it. Without that, when using UtmpMode=user, we get `/dev/tty` in the +output of `last`/`w`. + +(cherry picked from commit 33331d116db2eaf1189ea56ee4b36540179ac3dd) + +Conflict:NA +Reference:https://github.com/systemd/systemd/commit/09534e85b5c51c664077637e7e8c7c68dec52972 +--- + src/core/execute.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index 2a337b55a2..6ff757ff04 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -4059,13 +4059,17 @@ static int exec_child( + } + } + +- if (context->utmp_id) ++ if (context->utmp_id) { ++ const char *line = context->tty_path ? ++ (path_startswith(context->tty_path, "/dev/") ?: context->tty_path) : ++ NULL; + utmp_put_init_process(context->utmp_id, getpid_cached(), getsid(0), +- context->tty_path, ++ line, + context->utmp_mode == EXEC_UTMP_INIT ? INIT_PROCESS : + context->utmp_mode == EXEC_UTMP_LOGIN ? LOGIN_PROCESS : + USER_PROCESS, + username); ++ } + + if (uid_is_valid(uid)) { + r = chown_terminal(STDIN_FILENO, uid); +-- +2.33.0 + diff --git a/systemd.spec b/systemd.spec index ac4f34c..3aed8dc 100644 --- a/systemd.spec +++ b/systemd.spec @@ -16,7 +16,7 @@ Name: systemd Url: https://www.freedesktop.org/wiki/Software/systemd Version: 243 -Release: 75 +Release: 76 License: MIT and LGPLv2+ and GPLv2+ Summary: System and Service Manager @@ -301,6 +301,10 @@ Patch0253: backport-basic-fix-overflow-detection-in-sigbus_pop.patch Patch0254: backport-bus-use-bus_log_parse_error-to-print-message.patch Patch0255: backport-busctl-avoid-asserting-on-NULL-message.patch Patch0256: backport-sd-journal-check-sd-event-state-before-setting-up-po.patch +Patch0257: backport-utmp-remove-dev-from-line.patch +Patch0258: backport-core-exec-do-not-crash-with-UtmpMode-user-without-Us.patch +Patch0259: backport-resolved-limit-the-number-of-signature-validations-i.patch +Patch0260: backport-resolved-reduce-the-maximum-nsec3-iterations-to-100.patch #openEuler Patch9002: 1509-fix-journal-file-descriptors-leak-problems.patch @@ -1708,6 +1712,12 @@ fi %exclude /usr/share/man/man3/* %changelog +* Wed Mar 27 2024 huyubiao - 243-76 +- DESC:add backport-utmp-remove-dev-from-line.patch + backport-core-exec-do-not-crash-with-UtmpMode-user-without-Us.patch + backport-resolved-limit-the-number-of-signature-validations-i.patch + backport-resolved-reduce-the-maximum-nsec3-iterations-to-100.patch + * Wed Feb 28 2024 huyubiao - 243-75 - Type:bugfix - CVE:NA