diff --git a/SOURCES/0845-core-Detect-initial-timer-state-from-serialized-data.patch b/SOURCES/0845-core-Detect-initial-timer-state-from-serialized-data.patch index 2cfce58..bb837b0 100644 --- a/SOURCES/0845-core-Detect-initial-timer-state-from-serialized-data.patch +++ b/SOURCES/0845-core-Detect-initial-timer-state-from-serialized-data.patch @@ -1,4 +1,4 @@ -From b9914f359690e83303ee8a2ffa4d60cdf76f2a90 Mon Sep 17 00:00:00 2001 +From 9b2dad78f267ab3944d8b1145e3efe6c97bef4cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Koutn=C3=BD?= Date: Fri, 2 Nov 2018 20:56:08 +0100 Subject: [PATCH] core: Detect initial timer state from serialized data @@ -66,7 +66,7 @@ Resolves: #1764908 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/timer.c b/src/core/timer.c -index fb192d5..b36700c 100644 +index fb192d558a..b36700c186 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -267,10 +267,10 @@ static void timer_set_state(Timer *t, TimerState state) { @@ -135,6 +135,3 @@ index fb192d5..b36700c 100644 } static const char* const timer_state_table[_TIMER_STATE_MAX] = { --- -2.26.2 - diff --git a/SOURCES/0846-test-add-a-test-reproducer-for-BZ-1989245.patch b/SOURCES/0846-test-add-a-test-reproducer-for-BZ-1989245.patch new file mode 100644 index 0000000..d455bd8 --- /dev/null +++ b/SOURCES/0846-test-add-a-test-reproducer-for-BZ-1989245.patch @@ -0,0 +1,42 @@ +From c65ba4b00ee3a98b80fa1a76e08ab06659a94ad4 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 2 Aug 2021 20:31:42 +0200 +Subject: [PATCH] test: add a test/reproducer for BZ#1989245 + +Taken from https://github.com/systemd/systemd/issues/8056#issue-293156936. + +rhel-only +Related: #1989245 +--- + src/test/test-strv.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/test/test-strv.c b/src/test/test-strv.c +index 5ae929c3f8..c86e07f592 100644 +--- a/src/test/test-strv.c ++++ b/src/test/test-strv.c +@@ -542,6 +542,16 @@ static void test_strv_reverse(void) { + assert_se(streq_ptr(d[3], NULL)); + } + ++static void test_utf8(void) { ++ _cleanup_strv_free_ char **v = NULL; ++ _cleanup_free_ char *s = NULL; ++ ++ v = strv_new("/usr/bin/echo ", "привет", NULL); ++ assert_se(v); ++ s = strv_join_quoted(v); ++ assert_se(s); ++} ++ + int main(int argc, char *argv[]) { + test_specifier_printf(); + test_strv_foreach(); +@@ -598,6 +608,7 @@ int main(int argc, char *argv[]) { + test_strv_equal(); + test_strv_is_uniq(); + test_strv_reverse(); ++ test_utf8(); + + return 0; + } diff --git a/SOURCES/0847-strv-fix-buffer-size-calculation-in-strv_join_quoted.patch b/SOURCES/0847-strv-fix-buffer-size-calculation-in-strv_join_quoted.patch new file mode 100644 index 0000000..b29ece8 --- /dev/null +++ b/SOURCES/0847-strv-fix-buffer-size-calculation-in-strv_join_quoted.patch @@ -0,0 +1,48 @@ +From a7415ab87fa5cc7cae356aa296e5c3fec4add1bf Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 31 Jan 2018 23:43:28 +0900 +Subject: [PATCH] strv: fix buffer size calculation in strv_join_quoted() + +Fixes #8056. + +[fbui: the affected function was removed since v236+ (by commit + 2e59b24) so the patch is not needed by upstream which was at + v237+ when the issue was found.] + +rhel-only +Resolves: #1989245 +--- + src/shared/strv.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/src/shared/strv.c b/src/shared/strv.c +index e27ac68151..416373b183 100644 +--- a/src/shared/strv.c ++++ b/src/shared/strv.c +@@ -353,21 +353,18 @@ char *strv_join_quoted(char **l) { + size_t allocated = 0, len = 0; + + STRV_FOREACH(s, l) { +- /* assuming here that escaped string cannot be more +- * than twice as long, and reserving space for the +- * separator and quotes. +- */ + _cleanup_free_ char *esc = NULL; + size_t needed; + +- if (!GREEDY_REALLOC(buf, allocated, +- len + strlen(*s) * 2 + 3)) +- goto oom; +- + esc = cescape(*s); + if (!esc) + goto oom; + ++ /* reserving space for the escaped text, separator, quotes and NULL terminator. */ ++ if (!GREEDY_REALLOC(buf, allocated, ++ len + strlen(esc) + 4)) ++ goto oom; ++ + needed = snprintf(buf + len, allocated - len, "%s\"%s\"", + len > 0 ? " " : "", esc); + assert(needed < allocated - len); diff --git a/SOURCES/0848-install-refactor-find_symlinks-and-don-t-search-for-.patch b/SOURCES/0848-install-refactor-find_symlinks-and-don-t-search-for-.patch new file mode 100644 index 0000000..b5b7a69 --- /dev/null +++ b/SOURCES/0848-install-refactor-find_symlinks-and-don-t-search-for-.patch @@ -0,0 +1,280 @@ +From b864dc9ef4aa00191dfa81accbe93f9ed0382261 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 9 Mar 2021 17:22:32 +0100 +Subject: [PATCH] install: refactor find_symlinks() and don't search for + symlinks recursively + +After all we are only interested in symlinks either in top-level config +directory or in .wants and .requires sub-directories. + +As a bonus this should speed up ListUnitFiles() roughly 3-4x on systems +with a lot of units that use drop-ins (e.g. SSH jump hosts with a lot of +user session scopes). + +(cherry picked from commit 43b4e3058c106e663bbd5413e7bd106e55d6fd79) + +Resolves: #1828758 +--- + src/shared/install.c | 207 ++++++++++++++++++++----------------------- + 1 file changed, 96 insertions(+), 111 deletions(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index f2f968e329..761bf8074e 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -503,137 +503,88 @@ static int remove_marked_symlinks( + return r; + } + +-static int find_symlinks_fd( ++static int find_symlinks_in_directory( ++ DIR *dir, ++ const char *dir_path, + const char *root_dir, + const char *name, +- int fd, +- const char *path, + const char *config_path, + bool *same_name_link) { + ++ struct dirent *de; + int r = 0; +- _cleanup_closedir_ DIR *d = NULL; + +- assert(name); +- assert(fd >= 0); +- assert(path); +- assert(config_path); +- assert(same_name_link); +- +- d = fdopendir(fd); +- if (!d) { +- safe_close(fd); +- return -errno; +- } +- +- for (;;) { +- struct dirent *de; +- +- errno = 0; +- de = readdir(d); +- if (!de && errno != 0) +- return -errno; ++ FOREACH_DIRENT(de, dir, return -errno) { ++ _cleanup_free_ char *p = NULL, *dest = NULL; ++ bool found_path = false, found_dest, b = false; ++ int q; + +- if (!de) +- return r; ++ dirent_ensure_type(dir, de); + +- if (hidden_file(de->d_name)) ++ if (de->d_type != DT_LNK) + continue; + +- dirent_ensure_type(d, de); +- +- if (de->d_type == DT_DIR) { +- int nfd, q; +- _cleanup_free_ char *p = NULL; +- +- nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); +- if (nfd < 0) { +- if (errno == ENOENT) +- continue; +- +- if (r == 0) +- r = -errno; +- continue; +- } +- +- p = path_make_absolute(de->d_name, path); +- if (!p) { +- safe_close(nfd); +- return -ENOMEM; +- } ++ /* Acquire symlink name */ ++ p = path_make_absolute(de->d_name, dir_path); ++ if (!p) ++ return -ENOMEM; + +- /* This will close nfd, regardless whether it succeeds or not */ +- q = find_symlinks_fd(root_dir, name, nfd, p, config_path, same_name_link); +- if (q > 0) +- return 1; ++ /* Acquire symlink destination */ ++ q = readlinkat_malloc(dirfd(dir), de->d_name, &dest); ++ if (q == -ENOENT) ++ continue; ++ if (q < 0) { + if (r == 0) + r = q; ++ continue; ++ } + +- } else if (de->d_type == DT_LNK) { +- _cleanup_free_ char *p = NULL, *dest = NULL; +- bool found_path, found_dest, b = false; +- int q; ++ /* Make absolute */ ++ if (!path_is_absolute(dest)) { ++ char *x; + +- /* Acquire symlink name */ +- p = path_make_absolute(de->d_name, path); +- if (!p) ++ x = path_join(dir_path, dest, NULL); ++ if (!x) + return -ENOMEM; + +- /* Acquire symlink destination */ +- q = readlink_malloc(p, &dest); +- if (q < 0) { +- if (q == -ENOENT) +- continue; ++ free(dest); ++ dest = x; + +- if (r == 0) +- r = q; +- continue; +- } +- +- /* Make absolute */ +- if (!path_is_absolute(dest)) { +- char *x; +- +- x = prefix_root(root_dir, dest); +- if (!x) +- return -ENOMEM; +- +- free(dest); +- dest = x; +- } ++ } + +- /* Check if the symlink itself matches what we +- * are looking for */ +- if (path_is_absolute(name)) +- found_path = path_equal(p, name); +- else +- found_path = streq(de->d_name, name); ++ /* Check if the symlink itself matches what we ++ * are looking for */ ++ if (path_is_absolute(name)) ++ found_path = path_equal(p, name); ++ else ++ found_path = streq(de->d_name, name); + +- /* Check if what the symlink points to +- * matches what we are looking for */ +- if (path_is_absolute(name)) +- found_dest = path_equal(dest, name); +- else +- found_dest = streq(basename(dest), name); ++ /* Check if what the symlink points to ++ * matches what we are looking for */ ++ if (path_is_absolute(name)) ++ found_dest = path_equal(dest, name); ++ else ++ found_dest = streq(basename(dest), name); + +- if (found_path && found_dest) { +- _cleanup_free_ char *t = NULL; ++ if (found_path && found_dest) { ++ _cleanup_free_ char *t = NULL; + +- /* Filter out same name links in the main +- * config path */ +- t = path_make_absolute(name, config_path); +- if (!t) +- return -ENOMEM; +- +- b = path_equal(t, p); +- } ++ /* Filter out same name links in the main ++ * config path */ ++ t = path_make_absolute(name, config_path); ++ if (!t) ++ return -ENOMEM; + +- if (b) +- *same_name_link = true; +- else if (found_path || found_dest) +- return 1; ++ b = path_equal(p, t); + } ++ ++ if (b) ++ *same_name_link = true; ++ else if (found_path || found_dest) ++ return 1; + } ++ ++ return r; + } + + static int find_symlinks( +@@ -642,21 +593,55 @@ static int find_symlinks( + const char *config_path, + bool *same_name_link) { + +- int fd; ++ _cleanup_closedir_ DIR *config_dir = NULL; ++ struct dirent *de; ++ int r = 0; + + assert(name); + assert(config_path); + assert(same_name_link); + +- fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); +- if (fd < 0) { +- if (errno == ENOENT) ++ config_dir = opendir(config_path); ++ if (!config_dir) { ++ if (IN_SET(errno, ENOENT, ENOTDIR, EACCES)) + return 0; + return -errno; + } + +- /* This takes possession of fd and closes it */ +- return find_symlinks_fd(root_dir, name, fd, config_path, config_path, same_name_link); ++ FOREACH_DIRENT(de, config_dir, return -errno) { ++ const char *suffix; ++ _cleanup_free_ const char *path = NULL; ++ _cleanup_closedir_ DIR *d = NULL; ++ ++ dirent_ensure_type(config_dir, de); ++ ++ if (de->d_type != DT_DIR) ++ continue; ++ ++ suffix = strrchr(de->d_name, '.'); ++ if (!streq(suffix, ".wants") && !streq(suffix, ".requires")) ++ continue; ++ ++ path = path_join(config_path, de->d_name, NULL); ++ if (!path) ++ return -ENOMEM; ++ ++ d = opendir(path); ++ if (!d) { ++ log_error_errno(errno, "Failed to open directory '%s' while scanning for symlinks, ignoring: %m", path); ++ continue; ++ } ++ ++ r = find_symlinks_in_directory(d, path, root_dir, name, config_path, same_name_link); ++ if (r > 0) ++ return 1; ++ else if (r < 0) ++ log_debug_errno(r, "Failed to lookup for symlinks in '%s': %m", path); ++ } ++ ++ /* We didn't find any suitable symlinks in .wants or .requires directories, let's look for linked unit files in this directory. */ ++ rewinddir(config_dir); ++ return find_symlinks_in_directory(config_dir, config_path, root_dir, name, config_path, same_name_link); + } + + static int find_symlinks_in_scope( diff --git a/SOURCES/0849-install-fix-a-potential-crash.patch b/SOURCES/0849-install-fix-a-potential-crash.patch new file mode 100644 index 0000000..904224d --- /dev/null +++ b/SOURCES/0849-install-fix-a-potential-crash.patch @@ -0,0 +1,27 @@ +From bc861f7c3f1f7902ff94f43f45e0b960d6f2985c Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 30 Nov 2021 11:09:59 +0100 +Subject: [PATCH] install: fix a potential crash + +This is a follow-up for commit b864dc9ef4aa00191dfa81accbe93f9ed0382261 . + +Fixes #136. + +Related: #1828758 +--- + src/shared/install.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 761bf8074e..38cfc4a94c 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -619,7 +619,7 @@ static int find_symlinks( + continue; + + suffix = strrchr(de->d_name, '.'); +- if (!streq(suffix, ".wants") && !streq(suffix, ".requires")) ++ if (!streq_ptr(suffix, ".wants") && !streq_ptr(suffix, ".requires")) + continue; + + path = path_join(config_path, de->d_name, NULL); diff --git a/SOURCES/0850-acl-util-only-set-the-mask-if-not-present.patch b/SOURCES/0850-acl-util-only-set-the-mask-if-not-present.patch new file mode 100644 index 0000000..de9e2ef --- /dev/null +++ b/SOURCES/0850-acl-util-only-set-the-mask-if-not-present.patch @@ -0,0 +1,66 @@ +From cedab11bf07cdb5275ac12104d4dad6debbedce4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 28 Nov 2015 18:41:08 -0500 +Subject: [PATCH] acl-util: only set the mask if not present +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When we have non-owner user or group entries, we need the mask +for the acl to be valid. But acl_calc_mask() calculates the mask +to include all permissions, even those that were masked before. +Apparently this happens when we inherit *:r-x permissions from +a parent directory — the kernel sets *:r-x, mask:r--, effectively +masking the executable bit. acl_calc_mask() would set the mask:r-x, +effectively enabling the bit. To avoid this, be more conservative when +to add the mask entry: first iterate over all entries, and do nothing +if a mask. + +This returns the code closer to J.A.Steffens' original version +in v204-90-g23ad4dd884. + +Should fix https://github.com/systemd/systemd/issues/1977. + +(cherry picked from commit 6debb3982612b1fce9b2dd878bad07fe5ae9c0a9) + +Resolves: #2026361 +--- + src/shared/acl-util.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c +index d18a02f503..ec08661167 100644 +--- a/src/shared/acl-util.c ++++ b/src/shared/acl-util.c +@@ -69,6 +69,7 @@ int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) { + int calc_acl_mask_if_needed(acl_t *acl_p) { + acl_entry_t i; + int r; ++ bool need = false; + + assert(acl_p); + +@@ -83,17 +84,16 @@ int calc_acl_mask_if_needed(acl_t *acl_p) { + if (tag == ACL_MASK) + return 0; + +- if (IN_SET(tag, ACL_USER, ACL_GROUP)) { +- if (acl_calc_mask(acl_p) < 0) +- return -errno; +- +- return 1; +- } ++ if (IN_SET(tag, ACL_USER, ACL_GROUP)) ++ need = true; + } + if (r < 0) + return -errno; + +- return 0; ++ if (need && acl_calc_mask(acl_p) < 0) ++ return -errno; ++ ++ return need; + } + + int add_base_acls_if_needed(acl_t *acl_p, const char *path) { diff --git a/SOURCES/9999-Update-kernel-install-script-by-backporting-fedora-p.patch b/SOURCES/9999-Update-kernel-install-script-by-backporting-fedora-p.patch deleted file mode 100644 index c42f0b6..0000000 --- a/SOURCES/9999-Update-kernel-install-script-by-backporting-fedora-p.patch +++ /dev/null @@ -1,57 +0,0 @@ -From c49c37d5e26bf71a97d5194d390f80d3e71758e1 Mon Sep 17 00:00:00 2001 -From: systemd team -Date: Tue, 23 Apr 2019 10:46:19 -0300 -Subject: [PATCH] Update kernel-install script by backporting fedora patches - ---- - src/kernel-install/kernel-install | 30 +++++++++++++++++------------- - 1 file changed, 17 insertions(+), 13 deletions(-) - -diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install -index f1c74de..d860701 100755 ---- a/src/kernel-install/kernel-install -+++ b/src/kernel-install/kernel-install -@@ -73,23 +73,27 @@ KERNEL_IMAGE="$2" - - if [[ -x /sbin/new-kernel-pkg ]]; then - KERNEL_DIR="${KERNEL_IMAGE%/*}" -- if [[ "${KERNEL_DIR}" != "/boot" ]]; then -- for i in \ -- "$KERNEL_IMAGE" \ -- "$KERNEL_DIR/.${KERNEL_IMAGE##*/}.hmac" \ -- "$KERNEL_DIR"/System.map \ -- "$KERNEL_DIR"/config \ -- "$KERNEL_DIR"/zImage.stub \ -- "$KERNEL_DIR"/dtb \ -- ; do -- [[ -e "$i" ]] || continue -- cp -a "$i" "/boot/${i##*/}-${KERNEL_VERSION}" -- done -- fi - - [[ "$KERNEL_VERSION" == *\+* ]] && flavor=-"${KERNEL_VERSION##*+}" - case "$COMMAND" in - add) -+ if [[ "${KERNEL_DIR}" != "/boot" ]]; then -+ for i in \ -+ "$KERNEL_IMAGE" \ -+ "$KERNEL_DIR"/System.map \ -+ "$KERNEL_DIR"/config \ -+ "$KERNEL_DIR"/zImage.stub \ -+ "$KERNEL_DIR"/dtb \ -+ ; do -+ [[ -e "$i" ]] || continue -+ cp -aT "$i" "/boot/${i##*/}-${KERNEL_VERSION}" -+ done -+ # hmac is .vmlinuz-.hmac so needs a special treatment -+ i="$KERNEL_DIR/.${KERNEL_IMAGE##*/}.hmac" -+ if [[ -e "$i" ]]; then -+ cp -aT "$i" "/boot/.${KERNEL_IMAGE##*/}-${KERNEL_VERSION}.hmac" -+ fi -+ fi - /sbin/new-kernel-pkg --package "kernel${flavor}" --install "$KERNEL_VERSION" || exit $? - /sbin/new-kernel-pkg --package "kernel${flavor}" --mkinitrd --dracut --depmod --update "$KERNEL_VERSION" || exit $? - /sbin/new-kernel-pkg --package "kernel${flavor}" --rpmposttrans "$KERNEL_VERSION" || exit $? --- -1.8.3.1 - diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index bb50a27..f158f21 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -7,7 +7,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 219 -Release: 78%{?dist}.3 +Release: 78%{?dist}.5 # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: A System and Service Manager @@ -884,7 +884,11 @@ Patch0842: 0842-core-don-t-update-unit-description-if-it-is-already-.patch Patch0843: 0843-unit-don-t-emit-PropertiesChanged-signal-if-adding-a.patch Patch0844: 0844-core-fix-unnecessary-fallback-to-the-rescue-mode-cau.patch Patch0845: 0845-core-Detect-initial-timer-state-from-serialized-data.patch -Patch9999: 9999-Update-kernel-install-script-by-backporting-fedora-p.patch +Patch0846: 0846-test-add-a-test-reproducer-for-BZ-1989245.patch +Patch0847: 0847-strv-fix-buffer-size-calculation-in-strv_join_quoted.patch +Patch0848: 0848-install-refactor-find_symlinks-and-don-t-search-for-.patch +Patch0849: 0849-install-fix-a-potential-crash.patch +Patch0850: 0850-acl-util-only-set-the-mask-if-not-present.patch %global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);} @@ -1801,7 +1805,7 @@ fi %{_bindir}/systemd-sysv-convert %files python -%{python_sitearch}/systemd +%{python2_sitearch}/systemd %files -n libgudev1 %{_libdir}/libgudev-1.0.so.* @@ -1852,7 +1856,7 @@ fi %files resolved %{_prefix}/lib/systemd/systemd-resolved %{_prefix}/lib/systemd/systemd-resolve-host -%{_sysconfdir}/systemd/resolved.conf +%config(noreplace) %{_sysconfdir}/systemd/resolved.conf %config(noreplace) %{_sysconfdir}/dbus-1/system.d/org.freedesktop.resolve1.conf %{_datadir}/dbus-1/system-services/org.freedesktop.resolve1.service %{_libdir}/libnss_resolve.so.2 @@ -1862,6 +1866,15 @@ fi %{_mandir}/man8/systemd-resolved.* %changelog +* Mon Dec 06 2021 systemd maintenance team - 219-78.5 +- install: fix a potential crash (#1828758) +- acl-util: only set the mask if not present (#2026361) + +* Mon Nov 29 2021 systemd maintenance team - 219-78.4 +- test: add a test/reproducer for BZ#1989245 (#1989245) +- strv: fix buffer size calculation in strv_join_quoted() (#1989245) +- install: refactor find_symlinks() and don't search for symlinks recursively (#1828758) + * Fri Jan 15 2021 systemd maintenance team - 219-78.3 - core: Detect initial timer state from serialized data (#1764908)