diff --git a/SOURCES/0567-basic-unit-name-do-not-use-strdupa-on-a-path.patch b/SOURCES/0567-basic-unit-name-do-not-use-strdupa-on-a-path.patch new file mode 100644 index 0000000..992365a --- /dev/null +++ b/SOURCES/0567-basic-unit-name-do-not-use-strdupa-on-a-path.patch @@ -0,0 +1,63 @@ +From 25e2006bff1b82c4cee3d3899ed2874815e81e4a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 23 Jun 2021 11:46:41 +0200 +Subject: [PATCH] basic/unit-name: do not use strdupa() on a path + +The path may have unbounded length, for example through a fuse mount. + +CVE-2021-33910: attacked controlled alloca() leads to crash in systemd and +ultimately a kernel panic. Systemd parses the content of /proc/self/mountinfo +and each mountpoint is passed to mount_setup_unit(), which calls +unit_name_path_escape() underneath. A local attacker who is able to mount a +filesystem with a very long path can crash systemd and the whole system. + +https://bugzilla.redhat.com/show_bug.cgi?id=1970887 + +The resulting string length is bounded by UNIT_NAME_MAX, which is 256. But we +can't easily check the length after simplification before doing the +simplification, which in turns uses a copy of the string we can write to. +So we can't reject paths that are too long before doing the duplication. +Hence the most obvious solution is to switch back to strdup(), as before +7410616cd9dbbec97cf98d75324da5cda2b2f7a2. + +(cherry picked from commit 441e0115646d54f080e5c3bb0ba477c892861ab9) +--- + src/basic/unit-name.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c +index 1b81fe268f..614eb8649b 100644 +--- a/src/basic/unit-name.c ++++ b/src/basic/unit-name.c +@@ -369,12 +369,13 @@ int unit_name_unescape(const char *f, char **ret) { + } + + int unit_name_path_escape(const char *f, char **ret) { +- char *p, *s; ++ _cleanup_free_ char *p = NULL; ++ char *s; + + assert(f); + assert(ret); + +- p = strdupa(f); ++ p = strdup(f); + if (!p) + return -ENOMEM; + +@@ -386,13 +387,9 @@ int unit_name_path_escape(const char *f, char **ret) { + if (!path_is_normalized(p)) + return -EINVAL; + +- /* Truncate trailing slashes */ ++ /* Truncate trailing slashes and skip leading slashes */ + delete_trailing_chars(p, "/"); +- +- /* Truncate leading slashes */ +- p = skip_leading_chars(p, "/"); +- +- s = unit_name_escape(p); ++ s = unit_name_escape(skip_leading_chars(p, "/")); + } + if (!s) + return -ENOMEM; diff --git a/SOURCES/0568-sd-event-change-ordering-of-pending-ratelimited-even.patch b/SOURCES/0568-sd-event-change-ordering-of-pending-ratelimited-even.patch new file mode 100644 index 0000000..3a9fe9d --- /dev/null +++ b/SOURCES/0568-sd-event-change-ordering-of-pending-ratelimited-even.patch @@ -0,0 +1,96 @@ +From 93de7820843c175f4c9661dbfcb312e8ee09fbd3 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 8 Jun 2021 00:07:51 -0700 +Subject: [PATCH] sd-event: change ordering of pending/ratelimited events + +Instead of ordering non-pending before pending we should order +"non-pending OR ratelimited" before "pending AND not-ratelimited". +This fixes a bug where ratelimited events were ordered at the end of the +priority queue and could be stuck there for an indeterminate amount of +time. + +(cherry picked from commit 81107b8419c39f726fd2805517a5b9faab204e59) + +Related: #1984406 +--- + src/libsystemd/sd-event/sd-event.c | 48 +++++++++++++----------------- + 1 file changed, 20 insertions(+), 28 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index be912d94e3..3e77f4e810 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -427,25 +427,6 @@ static usec_t time_event_source_next(const sd_event_source *s) { + return USEC_INFINITY; + } + +-static int earliest_time_prioq_compare(const void *a, const void *b) { +- const sd_event_source *x = a, *y = b; +- +- /* Enabled ones first */ +- if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) +- return -1; +- if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) +- return 1; +- +- /* Move the pending ones to the end */ +- if (!x->pending && y->pending) +- return -1; +- if (x->pending && !y->pending) +- return 1; +- +- /* Order by time */ +- return CMP(time_event_source_next(x), time_event_source_next(y)); +-} +- + static usec_t time_event_source_latest(const sd_event_source *s) { + assert(s); + +@@ -464,7 +445,15 @@ static usec_t time_event_source_latest(const sd_event_source *s) { + return USEC_INFINITY; + } + +-static int latest_time_prioq_compare(const void *a, const void *b) { ++static bool event_source_timer_candidate(const sd_event_source *s) { ++ assert(s); ++ ++ /* Returns true for event sources that either are not pending yet (i.e. where it's worth to mark them pending) ++ * or which are currently ratelimited (i.e. where it's worth leaving the ratelimited state) */ ++ return !s->pending || s->ratelimited; ++} ++ ++static int time_prioq_compare(const void *a, const void *b, usec_t (*time_func)(const sd_event_source *s)) { + const sd_event_source *x = a, *y = b; + + /* Enabled ones first */ +@@ -473,19 +462,22 @@ static int latest_time_prioq_compare(const void *a, const void *b) { + if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) + return 1; + +- /* Move the pending ones to the end */ +- if (!x->pending && y->pending) ++ /* Order "non-pending OR ratelimited" before "pending AND not-ratelimited" */ ++ if (event_source_timer_candidate(x) && !event_source_timer_candidate(y)) + return -1; +- if (x->pending && !y->pending) ++ if (!event_source_timer_candidate(x) && event_source_timer_candidate(y)) + return 1; + + /* Order by time */ +- if (time_event_source_latest(x) < time_event_source_latest(y)) +- return -1; +- if (time_event_source_latest(x) > time_event_source_latest(y)) +- return 1; ++ return CMP(time_func(x), time_func(y)); ++} + +- return 0; ++static int earliest_time_prioq_compare(const void *a, const void *b) { ++ return time_prioq_compare(a, b, time_event_source_next); ++} ++ ++static int latest_time_prioq_compare(const void *a, const void *b) { ++ return time_prioq_compare(a, b, time_event_source_latest); + } + + static int exit_prioq_compare(const void *a, const void *b) { diff --git a/SOURCES/0569-sd-event-drop-unnecessary-else.patch b/SOURCES/0569-sd-event-drop-unnecessary-else.patch new file mode 100644 index 0000000..42e392b --- /dev/null +++ b/SOURCES/0569-sd-event-drop-unnecessary-else.patch @@ -0,0 +1,27 @@ +From 3e7e54c63236c65aa01bb332fd5135a13e51b992 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Jun 2021 00:44:04 +0900 +Subject: [PATCH] sd-event: drop unnecessary "else" + +(cherry picked from commit 7e2bf71ca3638e36ee33215ceee386ba8013da6d) + +Related: #1984406 +--- + src/libsystemd/sd-event/sd-event.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 3e77f4e810..2b0b76aa1c 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -2883,8 +2883,8 @@ static int event_arm_timer( + + if (!d->needs_rearm) + return 0; +- else +- d->needs_rearm = false; ++ ++ d->needs_rearm = false; + + a = prioq_peek(d->earliest); + if (!a || a->enabled == SD_EVENT_OFF || time_event_source_next(a) == USEC_INFINITY) { diff --git a/SOURCES/0570-sd-event-use-CMP-macro.patch b/SOURCES/0570-sd-event-use-CMP-macro.patch new file mode 100644 index 0000000..dcbf5eb --- /dev/null +++ b/SOURCES/0570-sd-event-use-CMP-macro.patch @@ -0,0 +1,90 @@ +From eaab8d57d9db0d98d7e618ba634983c34cdb9c06 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Jun 2021 00:51:33 +0900 +Subject: [PATCH] sd-event: use CMP() macro + +(cherry picked from commit 06e131477d82b83c5d516e66d6e413affd7c774a) + +Related: #1984406 +--- + src/libsystemd/sd-event/sd-event.c | 37 ++++++++++++++---------------- + 1 file changed, 17 insertions(+), 20 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 2b0b76aa1c..6a20b658e4 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -358,10 +358,9 @@ static int pending_prioq_compare(const void *a, const void *b) { + assert(y->pending); + + /* Enabled ones first */ +- if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) +- return -1; +- if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) +- return 1; ++ r = CMP(x->enabled == SD_EVENT_OFF, y->enabled == SD_EVENT_OFF); ++ if (r != 0) ++ return r; + + /* Non rate-limited ones first. */ + r = CMP(!!x->ratelimited, !!y->ratelimited); +@@ -385,10 +384,9 @@ static int prepare_prioq_compare(const void *a, const void *b) { + assert(y->prepare); + + /* Enabled ones first */ +- if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) +- return -1; +- if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) +- return 1; ++ r = CMP(x->enabled == SD_EVENT_OFF, y->enabled == SD_EVENT_OFF); ++ if (r != 0) ++ return r; + + /* Non rate-limited ones first. */ + r = CMP(!!x->ratelimited, !!y->ratelimited); +@@ -455,18 +453,17 @@ static bool event_source_timer_candidate(const sd_event_source *s) { + + static int time_prioq_compare(const void *a, const void *b, usec_t (*time_func)(const sd_event_source *s)) { + const sd_event_source *x = a, *y = b; ++ int r; + + /* Enabled ones first */ +- if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) +- return -1; +- if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) +- return 1; ++ r = CMP(x->enabled == SD_EVENT_OFF, y->enabled == SD_EVENT_OFF); ++ if (r != 0) ++ return r; + + /* Order "non-pending OR ratelimited" before "pending AND not-ratelimited" */ +- if (event_source_timer_candidate(x) && !event_source_timer_candidate(y)) +- return -1; +- if (!event_source_timer_candidate(x) && event_source_timer_candidate(y)) +- return 1; ++ r = CMP(!event_source_timer_candidate(x), !event_source_timer_candidate(y)); ++ if (r != 0) ++ return r; + + /* Order by time */ + return CMP(time_func(x), time_func(y)); +@@ -482,15 +479,15 @@ static int latest_time_prioq_compare(const void *a, const void *b) { + + static int exit_prioq_compare(const void *a, const void *b) { + const sd_event_source *x = a, *y = b; ++ int r; + + assert(x->type == SOURCE_EXIT); + assert(y->type == SOURCE_EXIT); + + /* Enabled ones first */ +- if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) +- return -1; +- if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) +- return 1; ++ r = CMP(x->enabled == SD_EVENT_OFF, y->enabled == SD_EVENT_OFF); ++ if (r != 0) ++ return r; + + /* Lower priority values first */ + if (x->priority < y->priority) diff --git a/SOURCES/0571-sd-event-use-usec_add.patch b/SOURCES/0571-sd-event-use-usec_add.patch new file mode 100644 index 0000000..b4ac736 --- /dev/null +++ b/SOURCES/0571-sd-event-use-usec_add.patch @@ -0,0 +1,27 @@ +From b8732d647162b50ce9b34de2ad7ae11a53f6e7ba Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Jun 2021 01:01:48 +0900 +Subject: [PATCH] sd-event: use usec_add() + +(cherry picked from commit a595fb5ca9c69c589e758e9ebe3b70ac90450ba3) + +Related: #1984406 +--- + src/libsystemd/sd-event/sd-event.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 6a20b658e4..f675c09d84 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -3514,8 +3514,8 @@ static int arm_watchdog(sd_event *e) { + assert(e->watchdog_fd >= 0); + + t = sleep_between(e, +- e->watchdog_last + (e->watchdog_period / 2), +- e->watchdog_last + (e->watchdog_period * 3 / 4)); ++ usec_add(e->watchdog_last, (e->watchdog_period / 2)), ++ usec_add(e->watchdog_last, (e->watchdog_period * 3 / 4))); + + timespec_store(&its.it_value, t); + diff --git a/SOURCES/0572-sd-event-make-event_source_time_prioq_reshuffle-acce.patch b/SOURCES/0572-sd-event-make-event_source_time_prioq_reshuffle-acce.patch new file mode 100644 index 0000000..91c03a4 --- /dev/null +++ b/SOURCES/0572-sd-event-make-event_source_time_prioq_reshuffle-acce.patch @@ -0,0 +1,40 @@ +From 9f044118dbc6a0f04b3820ffaa9d4c7807ae48a7 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Jun 2021 02:03:02 +0900 +Subject: [PATCH] sd-event: make event_source_time_prioq_reshuffle() accept all + event source type + +But it does nothing for an event source which is neither a timer nor +ratelimited. + +(cherry picked from commit 5c08c7ab23dbf02aaf4e4bbae8e08a195da230a4) + +Related: #1984406 +--- + src/libsystemd/sd-event/sd-event.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index f675c09d84..ae46392901 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -954,14 +954,15 @@ static void event_source_time_prioq_reshuffle(sd_event_source *s) { + assert(s); + + /* Called whenever the event source's timer ordering properties changed, i.e. time, accuracy, +- * pending, enable state. Makes sure the two prioq's are ordered properly again. */ ++ * pending, enable state, and ratelimiting state. Makes sure the two prioq's are ordered ++ * properly again. */ + + if (s->ratelimited) + d = &s->event->monotonic; +- else { +- assert(EVENT_SOURCE_IS_TIME(s->type)); ++ else if (EVENT_SOURCE_IS_TIME(s->type)) + assert_se(d = event_get_clock_data(s->event, s->type)); +- } ++ else ++ return; /* no-op for an event source which is neither a timer nor ratelimited. */ + + prioq_reshuffle(d->earliest, s, &s->earliest_index); + prioq_reshuffle(d->latest, s, &s->latest_index); diff --git a/SOURCES/0573-sd-event-always-reshuffle-time-prioq-on-changing-onl.patch b/SOURCES/0573-sd-event-always-reshuffle-time-prioq-on-changing-onl.patch new file mode 100644 index 0000000..04c1c14 --- /dev/null +++ b/SOURCES/0573-sd-event-always-reshuffle-time-prioq-on-changing-onl.patch @@ -0,0 +1,90 @@ +From f5611a22d4a65ef440352792085774ce898adb0f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Jun 2021 02:13:59 +0900 +Subject: [PATCH] sd-event: always reshuffle time prioq on changing + online/offline state + +Before 81107b8419c39f726fd2805517a5b9faab204e59, the compare functions +for the latest or earliest prioq did not handle ratelimited flag. +So, it was ok to not reshuffle the time prioq when changing the flag. + +But now, those two compare functions also compare the source is +ratelimited or not. So, it is necessary to reshuffle the time prioq +after changing the ratelimited flag. + +Hopefully fixes #19903. + +(cherry picked from commit 2115b9b6629eeba7bc9f42f757f38205febb1cb7) + +Related: #1984406 +--- + src/libsystemd/sd-event/sd-event.c | 33 ++++++++++-------------------- + 1 file changed, 11 insertions(+), 22 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index ae46392901..f78da00c3a 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -2390,14 +2390,6 @@ static int event_source_offline( + source_io_unregister(s); + break; + +- case SOURCE_TIME_REALTIME: +- case SOURCE_TIME_BOOTTIME: +- case SOURCE_TIME_MONOTONIC: +- case SOURCE_TIME_REALTIME_ALARM: +- case SOURCE_TIME_BOOTTIME_ALARM: +- event_source_time_prioq_reshuffle(s); +- break; +- + case SOURCE_SIGNAL: + event_gc_signal_data(s->event, &s->priority, s->signal.sig); + break; +@@ -2415,6 +2407,11 @@ static int event_source_offline( + prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); + break; + ++ case SOURCE_TIME_REALTIME: ++ case SOURCE_TIME_BOOTTIME: ++ case SOURCE_TIME_MONOTONIC: ++ case SOURCE_TIME_REALTIME_ALARM: ++ case SOURCE_TIME_BOOTTIME_ALARM: + case SOURCE_DEFER: + case SOURCE_POST: + case SOURCE_INOTIFY: +@@ -2424,6 +2421,9 @@ static int event_source_offline( + assert_not_reached("Wut? I shouldn't exist."); + } + ++ /* Always reshuffle time prioq, as the ratelimited flag may be changed. */ ++ event_source_time_prioq_reshuffle(s); ++ + return 1; + } + +@@ -2505,22 +2505,11 @@ static int event_source_online( + s->ratelimited = ratelimited; + + /* Non-failing operations below */ +- switch (s->type) { +- case SOURCE_TIME_REALTIME: +- case SOURCE_TIME_BOOTTIME: +- case SOURCE_TIME_MONOTONIC: +- case SOURCE_TIME_REALTIME_ALARM: +- case SOURCE_TIME_BOOTTIME_ALARM: +- event_source_time_prioq_reshuffle(s); +- break; +- +- case SOURCE_EXIT: ++ if (s->type == SOURCE_EXIT) + prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); +- break; + +- default: +- break; +- } ++ /* Always reshuffle time prioq, as the ratelimited flag may be changed. */ ++ event_source_time_prioq_reshuffle(s); + + return 1; + } diff --git a/SOURCES/0574-meson-remove-strange-dep-that-causes-meson-to-enter-.patch b/SOURCES/0574-meson-remove-strange-dep-that-causes-meson-to-enter-.patch new file mode 100644 index 0000000..b53c326 --- /dev/null +++ b/SOURCES/0574-meson-remove-strange-dep-that-causes-meson-to-enter-.patch @@ -0,0 +1,38 @@ +From 2991ba196d034aef170acbf0d73533f79c66b94e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 6 Nov 2019 12:44:39 +0100 +Subject: [PATCH] meson: remove strange dep that causes meson to enter infinite + loop + +The value is obviously bogus, but didn't seem to cause problems so far. +With meson-0.52.0, it causes a hang. The number of aliases is always rather +small (usually just one or two, possibly up to a dozen in a few cases), so +even if this causes some looping, it is strange that it has such a huge impact. +But let's just remove it. + +Fixes #13742. + +Tested with meson-0.52.0-1.module_f31+6771+f5d842eb.noarch, +meson-0.51.1-1.fc29.noarch. + +Based on: af336643a01d0b210b18312c253a50594ba54b0a + +Related: #1984406 + +(cherry picked from commit 7fb2d86b58201341a582b739a5445821bec66eea) +--- + man/meson.build | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/man/meson.build b/man/meson.build +index ec05d73bc6..a953d34098 100644 +--- a/man/meson.build ++++ b/man/meson.build +@@ -68,7 +68,6 @@ foreach tuple : xsltproc.found() ? manpages : [] + foreach htmlalias : htmlaliases + link = custom_target( + htmlalias, +- input : p2, + output : htmlalias, + command : ['ln', '-fs', html, '@OUTPUT@']) + if want_html diff --git a/SOURCES/0575-copy-handle-copy_file_range-weirdness-on-procfs-sysf.patch b/SOURCES/0575-copy-handle-copy_file_range-weirdness-on-procfs-sysf.patch new file mode 100644 index 0000000..b3c99e2 --- /dev/null +++ b/SOURCES/0575-copy-handle-copy_file_range-weirdness-on-procfs-sysf.patch @@ -0,0 +1,185 @@ +From f13a7eab34e675a88634c053682ecb2af43a432c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 26 Feb 2021 10:25:24 +0100 +Subject: [PATCH] copy: handle copy_file_range() weirdness on procfs/sysfs + +This addresses the issue described in https://lwn.net/Articles/846403/ +and makes sure we will be able to stream bytes from procfs/sysfs via +copy_bytes() if people ask us to. + +Based on: ee1aa61c4710ae567a2b844e0f0bb8cb0456ab8c + +Related: ##1984406 + +(cherry picked from commit 8df650c7c5adc2bb24a0077d8332f5ee342e7fd8) +--- + src/basic/copy.c | 75 +++++++++++++++++++++++++++++--------------- + src/test/test-copy.c | 17 ++++++++++ + 2 files changed, 66 insertions(+), 26 deletions(-) + +diff --git a/src/basic/copy.c b/src/basic/copy.c +index e06a503a29..a48c42c5c6 100644 +--- a/src/basic/copy.c ++++ b/src/basic/copy.c +@@ -92,7 +92,7 @@ int copy_bytes_full( + void **ret_remains, + size_t *ret_remains_size) { + +- bool try_cfr = true, try_sendfile = true, try_splice = true; ++ bool try_cfr = true, try_sendfile = true, try_splice = true, copied_something = false; + int r, nonblock_pipe = -1; + size_t m = SSIZE_MAX; /* that is the maximum that sendfile and c_f_r accept */ + +@@ -185,9 +185,20 @@ int copy_bytes_full( + + try_cfr = false; + /* use fallback below */ +- } else if (n == 0) /* EOF */ +- break; +- else ++ } else if (n == 0) { /* likely EOF */ ++ ++ if (copied_something) ++ break; ++ ++ /* So, we hit EOF immediately, without having copied a single byte. This ++ * could indicate two things: the file is actually empty, or we are on some ++ * virtual file system such as procfs/sysfs where the syscall actually ++ * doesn't work but doesn't return an error. Try to handle that, by falling ++ * back to simple read()s in case we encounter empty files. ++ * ++ * See: https://lwn.net/Articles/846403/ */ ++ try_cfr = try_sendfile = try_splice = false; ++ } else + /* Success! */ + goto next; + } +@@ -201,9 +212,14 @@ int copy_bytes_full( + + try_sendfile = false; + /* use fallback below */ +- } else if (n == 0) /* EOF */ ++ } else if (n == 0) { /* likely EOF */ ++ ++ if (copied_something) ++ break; ++ ++ try_sendfile = try_splice = false; /* same logic as above for copy_file_range() */ + break; +- else ++ } else + /* Success! */ + goto next; + } +@@ -213,14 +229,14 @@ int copy_bytes_full( + + /* splice()'s asynchronous I/O support is a bit weird. When it encounters a pipe file + * descriptor, then it will ignore its O_NONBLOCK flag and instead only honour the +- * SPLICE_F_NONBLOCK flag specified in its flag parameter. Let's hide this behaviour here, and +- * check if either of the specified fds are a pipe, and if so, let's pass the flag +- * automatically, depending on O_NONBLOCK being set. ++ * SPLICE_F_NONBLOCK flag specified in its flag parameter. Let's hide this behaviour ++ * here, and check if either of the specified fds are a pipe, and if so, let's pass ++ * the flag automatically, depending on O_NONBLOCK being set. + * +- * Here's a twist though: when we use it to move data between two pipes of which one has +- * O_NONBLOCK set and the other has not, then we have no individual control over O_NONBLOCK +- * behaviour. Hence in that case we can't use splice() and still guarantee systematic +- * O_NONBLOCK behaviour, hence don't. */ ++ * Here's a twist though: when we use it to move data between two pipes of which one ++ * has O_NONBLOCK set and the other has not, then we have no individual control over ++ * O_NONBLOCK behaviour. Hence in that case we can't use splice() and still guarantee ++ * systematic O_NONBLOCK behaviour, hence don't. */ + + if (nonblock_pipe < 0) { + int a, b; +@@ -238,12 +254,13 @@ int copy_bytes_full( + (a == FD_IS_BLOCKING_PIPE && b == FD_IS_NONBLOCKING_PIPE) || + (a == FD_IS_NONBLOCKING_PIPE && b == FD_IS_BLOCKING_PIPE)) + +- /* splice() only works if one of the fds is a pipe. If neither is, let's skip +- * this step right-away. As mentioned above, if one of the two fds refers to a +- * blocking pipe and the other to a non-blocking pipe, we can't use splice() +- * either, hence don't try either. This hence means we can only use splice() if +- * either only one of the two fds is a pipe, or if both are pipes with the same +- * nonblocking flag setting. */ ++ /* splice() only works if one of the fds is a pipe. If neither is, ++ * let's skip this step right-away. As mentioned above, if one of the ++ * two fds refers to a blocking pipe and the other to a non-blocking ++ * pipe, we can't use splice() either, hence don't try either. This ++ * hence means we can only use splice() if either only one of the two ++ * fds is a pipe, or if both are pipes with the same nonblocking flag ++ * setting. */ + + try_splice = false; + else +@@ -259,9 +276,13 @@ int copy_bytes_full( + + try_splice = false; + /* use fallback below */ +- } else if (n == 0) /* EOF */ +- break; +- else ++ } else if (n == 0) { /* likely EOF */ ++ ++ if (copied_something) ++ break; ++ ++ try_splice = false; /* same logic as above for copy_file_range() + sendfile() */ ++ } else + /* Success! */ + goto next; + } +@@ -312,11 +333,13 @@ int copy_bytes_full( + assert(max_bytes >= (uint64_t) n); + max_bytes -= n; + } +- /* sendfile accepts at most SSIZE_MAX-offset bytes to copy, +- * so reduce our maximum by the amount we already copied, +- * but don't go below our copy buffer size, unless we are +- * close the limit of bytes we are allowed to copy. */ ++ ++ /* sendfile accepts at most SSIZE_MAX-offset bytes to copy, so reduce our maximum by the ++ * amount we already copied, but don't go below our copy buffer size, unless we are close the ++ * limit of bytes we are allowed to copy. */ + m = MAX(MIN(COPY_BUFFER_SIZE, max_bytes), m - n); ++ ++ copied_something = true; + } + + return 0; /* return 0 if we hit EOF earlier than the size limit */ +diff --git a/src/test/test-copy.c b/src/test/test-copy.c +index 2e8d251ac1..29ac33e47a 100644 +--- a/src/test/test-copy.c ++++ b/src/test/test-copy.c +@@ -253,6 +253,22 @@ static void test_copy_atomic(void) { + assert_se(copy_file_atomic("/etc/fstab", q, 0644, 0, COPY_REPLACE) >= 0); + } + ++static void test_copy_proc(void) { ++ _cleanup_(rm_rf_physical_and_freep) char *p = NULL; ++ _cleanup_free_ char *f = NULL, *a = NULL, *b = NULL; ++ ++ /* Check if copying data from /proc/ works correctly, i.e. let's see if https://lwn.net/Articles/846403/ is a problem for us */ ++ ++ assert_se(mkdtemp_malloc(NULL, &p) >= 0); ++ assert_se(f = path_join(NULL, p, "version")); ++ assert_se(copy_file("/proc/version", f, 0, (mode_t) -1, 0, 0) >= 0); ++ ++ assert_se(read_one_line_file("/proc/version", &a) >= 0); ++ assert_se(read_one_line_file(f, &b) >= 0); ++ assert_se(streq(a, b)); ++ assert_se(strlen(a) > 0); ++} ++ + int main(int argc, char *argv[]) { + log_set_max_level(LOG_DEBUG); + +@@ -267,6 +283,7 @@ int main(int argc, char *argv[]) { + test_copy_bytes_regular_file(argv[0], false, 32000); /* larger than copy buffer size */ + test_copy_bytes_regular_file(argv[0], true, 32000); + test_copy_atomic(); ++ test_copy_proc(); + + return 0; + } diff --git a/SOURCES/0576-ci-run-unit-tests-on-z-stream-branches-as-well.patch b/SOURCES/0576-ci-run-unit-tests-on-z-stream-branches-as-well.patch new file mode 100644 index 0000000..1e0ffad --- /dev/null +++ b/SOURCES/0576-ci-run-unit-tests-on-z-stream-branches-as-well.patch @@ -0,0 +1,30 @@ +From b36d6b397ad43e081574663a65b0db72cdcaaf28 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 15 Jul 2021 12:27:33 +0200 +Subject: [PATCH] ci: run unit tests on z-stream branches as well + +rhel-only + +Related: #1984406 + +(cherry picked from commit 68cedfd41f1ea3eda34b0023e951649b92953709) +--- + .github/workflows/unit_tests.yml | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml +index 15f5127a75..428bde4ed8 100644 +--- a/.github/workflows/unit_tests.yml ++++ b/.github/workflows/unit_tests.yml +@@ -2,10 +2,7 @@ + # vi: ts=2 sw=2 et: + # + name: Unit tests +-on: +- pull_request: +- branches: +- - master ++on: [pull_request] + + jobs: + build: diff --git a/SOURCES/0577-remove-a-left-over-break.patch b/SOURCES/0577-remove-a-left-over-break.patch new file mode 100644 index 0000000..5083299 --- /dev/null +++ b/SOURCES/0577-remove-a-left-over-break.patch @@ -0,0 +1,31 @@ +From 1745f135c7b26fef0223848efc06e62cf86c1b34 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 25 Jun 2021 10:42:53 +0200 +Subject: [PATCH] remove a left-over break + +By the "same logic as above...", we want to continue to fallback here, +but the break prohibits that. + +This is a follow-up for ee1aa61c4710ae567a2b844e0f0bb8cb0456ab8c . + +Based on: 99df1cb6f50875db513a5b45f18191460a150f3d) + +Related: #1984406 + +(cherry picked from commit 5944138a54017fc8f1f4c878a1eea96ea18736c4) +--- + src/basic/copy.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/basic/copy.c b/src/basic/copy.c +index a48c42c5c6..1a0db29ac9 100644 +--- a/src/basic/copy.c ++++ b/src/basic/copy.c +@@ -218,7 +218,6 @@ int copy_bytes_full( + break; + + try_sendfile = try_splice = false; /* same logic as above for copy_file_range() */ +- break; + } else + /* Success! */ + goto next; diff --git a/SOURCES/9000-basic-unit-name-do-not-use-strdupa-on-a-path.patch b/SOURCES/9000-basic-unit-name-do-not-use-strdupa-on-a-path.patch deleted file mode 100644 index 398a4bd..0000000 --- a/SOURCES/9000-basic-unit-name-do-not-use-strdupa-on-a-path.patch +++ /dev/null @@ -1,64 +0,0 @@ -From df7a2c629e700a510ce59b8745d240d2a43a12aa Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= -Date: Wed, 23 Jun 2021 11:46:41 +0200 -Subject: [PATCH] basic/unit-name: do not use strdupa() on a path - -The path may have unbounded length, for example through a fuse mount. - -CVE-2021-33910: attacked controlled alloca() leads to crash in systemd and -ultimately a kernel panic. Systemd parses the content of /proc/self/mountinfo -and each mountpoint is passed to mount_setup_unit(), which calls -unit_name_path_escape() underneath. A local attacker who is able to mount a -filesystem with a very long path can crash systemd and the whole system. - -https://bugzilla.redhat.com/show_bug.cgi?id=1970887 - -The resulting string length is bounded by UNIT_NAME_MAX, which is 256. But we -can't easily check the length after simplification before doing the -simplification, which in turns uses a copy of the string we can write to. -So we can't reject paths that are too long before doing the duplication. -Hence the most obvious solution is to switch back to strdup(), as before -7410616cd9dbbec97cf98d75324da5cda2b2f7a2. ---- - src/basic/unit-name.c | 13 +++++-------- - 1 file changed, 5 insertions(+), 8 deletions(-) - -diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c -index 1b81fe2..614eb86 100644 ---- a/src/basic/unit-name.c -+++ b/src/basic/unit-name.c -@@ -369,12 +369,13 @@ int unit_name_unescape(const char *f, char **ret) { - } - - int unit_name_path_escape(const char *f, char **ret) { -- char *p, *s; -+ _cleanup_free_ char *p = NULL; -+ char *s; - - assert(f); - assert(ret); - -- p = strdupa(f); -+ p = strdup(f); - if (!p) - return -ENOMEM; - -@@ -386,13 +387,9 @@ int unit_name_path_escape(const char *f, char **ret) { - if (!path_is_normalized(p)) - return -EINVAL; - -- /* Truncate trailing slashes */ -+ /* Truncate trailing slashes and skip leading slashes */ - delete_trailing_chars(p, "/"); -- -- /* Truncate leading slashes */ -- p = skip_leading_chars(p, "/"); -- -- s = unit_name_escape(p); -+ s = unit_name_escape(skip_leading_chars(p, "/")); - } - if (!s) - return -ENOMEM; --- -2.31.1 - diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index ccc28be..129c3f7 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -13,7 +13,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 45%{?dist}.2 +Release: 45%{?dist}.3 # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -616,10 +616,20 @@ Patch0563: 0563-pam-systemd-use-secure_getenv-rather-than-getenv.patch Patch0564: 0564-Revert-udev-run-link_update-with-increased-retry-cou.patch Patch0565: 0565-Revert-udev-make-algorithm-that-selects-highest-prio.patch Patch0566: 0566-test-udev-test.pl-drop-test-cases-that-add-mutliple-.patch +Patch0567: 0567-basic-unit-name-do-not-use-strdupa-on-a-path.patch +Patch0568: 0568-sd-event-change-ordering-of-pending-ratelimited-even.patch +Patch0569: 0569-sd-event-drop-unnecessary-else.patch +Patch0570: 0570-sd-event-use-CMP-macro.patch +Patch0571: 0571-sd-event-use-usec_add.patch +Patch0572: 0572-sd-event-make-event_source_time_prioq_reshuffle-acce.patch +Patch0573: 0573-sd-event-always-reshuffle-time-prioq-on-changing-onl.patch +Patch0574: 0574-meson-remove-strange-dep-that-causes-meson-to-enter-.patch +Patch0575: 0575-copy-handle-copy_file_range-weirdness-on-procfs-sysf.patch +Patch0576: 0576-ci-run-unit-tests-on-z-stream-branches-as-well.patch +Patch0577: 0577-remove-a-left-over-break.patch # Security patches -Patch9000: 9000-basic-unit-name-do-not-use-strdupa-on-a-path.patch %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 @@ -1247,6 +1257,18 @@ fi %files tests -f .file-list-tests %changelog +* Wed Jul 28 2021 systemd maintenance team - 239-45.3 +- sd-event: change ordering of pending/ratelimited events (#1984406) +- sd-event: drop unnecessary "else" (#1984406) +- sd-event: use CMP() macro (#1984406) +- sd-event: use usec_add() (#1984406) +- sd-event: make event_source_time_prioq_reshuffle() accept all event source type (#1984406) +- sd-event: always reshuffle time prioq on changing online/offline state (#1984406) +- meson: remove strange dep that causes meson to enter infinite loop (#1984406) +- copy: handle copy_file_range() weirdness on procfs/sysfs (#1984406) +- ci: run unit tests on z-stream branches as well (#1984406) +- remove a left-over break (#1984406) + * Mon Jun 28 2021 Jan Macku - 239-45.2 - basic/unit-name: do not use strdupa() on a path (CVE-2021-33910, #1974699)