sync patches from systemd community

This commit is contained in:
h30032433 2024-03-27 15:39:50 +08:00
parent efeac5ed66
commit 16eb9e1027
5 changed files with 362 additions and 1 deletions

View File

@ -0,0 +1,75 @@
From fa972e8681159a34ffc9c114e4fe3538a7f69046 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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

View File

@ -0,0 +1,191 @@
From 7886eea2425fe7773cc012da0b2e266e33d4be12 Mon Sep 17 00:00:00 2001
From: Ronan Pigott <ronan@rjp.ie>
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

View File

@ -0,0 +1,41 @@
From 156e519d990a5662c719a1cbe80c6a02a2b9115f Mon Sep 17 00:00:00 2001
From: Ronan Pigott <ronan@rjp.ie>
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

View File

@ -0,0 +1,44 @@
From 09534e85b5c51c664077637e7e8c7c68dec52972 Mon Sep 17 00:00:00 2001
From: Vincent Bernat <vincent@bernat.ch>
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

View File

@ -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 <huyubiao@huawei.com> - 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 <huyubiao@huawei.com> - 243-75
- Type:bugfix
- CVE:NA