From 8483bf9043a4d82eda9b9dfedaa09ebceba3727d Mon Sep 17 00:00:00 2001 From: Anita Zhang Date: Oct 11 2021 22:13:28 +0000 Subject: 249.4-2.5: additional patches and fixes - Fix duplicate Address= properties in network configs (part of PR #20892) - Serialize bpf device programs across reloads/reexecs (PR #20978) - Don't rewrite sysctls that are already set (PR #20676) --- diff --git a/SOURCES/20676_cherrypicked.patch b/SOURCES/20676_cherrypicked.patch new file mode 100644 index 0000000..e97a589 --- /dev/null +++ b/SOURCES/20676_cherrypicked.patch @@ -0,0 +1,336 @@ +From 0b9f08931944c2e33c6ed012919157e429eb7be2 Mon Sep 17 00:00:00 2001 +From: Antony Deepak Thomas +Date: Wed, 29 Sep 2021 12:47:49 +0900 +Subject: [PATCH 1/4] fileio: introduce read_virtual_file_fd() + +--- + src/basic/fileio.c | 24 ++++++++++++++++-------- + src/basic/fileio.h | 1 + + 2 files changed, 17 insertions(+), 8 deletions(-) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index 466c6321c7..4a0d060105 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -373,9 +373,8 @@ int verify_file(const char *fn, const char *blob, bool accept_extra_nl) { + return 1; + } + +-int read_virtual_file(const char *filename, size_t max_size, char **ret_contents, size_t *ret_size) { ++int read_virtual_file_fd(int fd, size_t max_size, char **ret_contents, size_t *ret_size) { + _cleanup_free_ char *buf = NULL; +- _cleanup_close_ int fd = -1; + size_t n, size; + int n_retries; + bool truncated = false; +@@ -393,10 +392,7 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents + * contents* may be returned. (Though the read is still done using one syscall.) Returns 0 on + * partial success, 1 if untruncated contents were read. */ + +- fd = open(filename, O_RDONLY|O_CLOEXEC); +- if (fd < 0) +- return -errno; +- ++ assert(fd >= 0); + assert(max_size <= READ_VIRTUAL_BYTES_MAX || max_size == SIZE_MAX); + + /* Limit the number of attempts to read the number of bytes returned by fstat(). */ +@@ -432,8 +428,8 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents + + n_retries--; + } else if (n_retries > 1) { +- /* Files in /proc are generally smaller than the page size so let's start with a page size +- * buffer from malloc and only use the max buffer on the final try. */ ++ /* Files in /proc are generally smaller than the page size so let's start with ++ * a page size buffer from malloc and only use the max buffer on the final try. */ + size = MIN3(page_size() - 1, READ_VIRTUAL_BYTES_MAX, max_size); + n_retries = 1; + } else { +@@ -517,6 +513,18 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents + return !truncated; + } + ++int read_virtual_file(const char *filename, size_t max_size, char **ret_contents, size_t *ret_size) { ++ _cleanup_close_ int fd = -1; ++ ++ assert(filename); ++ ++ fd = open(filename, O_RDONLY | O_NOCTTY | O_CLOEXEC); ++ if (fd < 0) ++ return -errno; ++ ++ return read_virtual_file_fd(fd, max_size, ret_contents, ret_size); ++} ++ + int read_full_stream_full( + FILE *f, + const char *filename, +diff --git a/src/basic/fileio.h b/src/basic/fileio.h +index 9bd2037f5b..82330840bf 100644 +--- a/src/basic/fileio.h ++++ b/src/basic/fileio.h +@@ -66,6 +66,7 @@ static inline int read_full_file(const char *filename, char **ret_contents, size + return read_full_file_full(AT_FDCWD, filename, UINT64_MAX, SIZE_MAX, 0, NULL, ret_contents, ret_size); + } + ++int read_virtual_file_fd(int fd, size_t max_size, char **ret_contents, size_t *ret_size); + int read_virtual_file(const char *filename, size_t max_size, char **ret_contents, size_t *ret_size); + static inline int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size) { + return read_virtual_file(filename, SIZE_MAX, ret_contents, ret_size); +-- +2.31.1 + + +From bede594fa1ea4c32a886191b774134effcf71bef Mon Sep 17 00:00:00 2001 +From: Antony Deepak Thomas +Date: Wed, 29 Sep 2021 12:57:30 +0900 +Subject: [PATCH 2/4] string-util: introduce streq_skip_trailing_chars() + +--- + src/basic/string-util.c | 16 ++++++++++++++++ + src/basic/string-util.h | 2 ++ + src/test/test-string-util.c | 28 ++++++++++++++++++++++++++++ + 3 files changed, 46 insertions(+) + +diff --git a/src/basic/string-util.c b/src/basic/string-util.c +index a645958d38..6ceaeaf9df 100644 +--- a/src/basic/string-util.c ++++ b/src/basic/string-util.c +@@ -1146,3 +1146,19 @@ int string_contains_word_strv(const char *string, const char *separators, char * + *ret_word = found; + return !!found; + } ++ ++bool streq_skip_trailing_chars(const char *s1, const char *s2, const char *ok) { ++ if (!s1 && !s2) ++ return true; ++ if (!s1 || !s2) ++ return false; ++ ++ if (!ok) ++ ok = WHITESPACE; ++ ++ for (; *s1 && *s2; s1++, s2++) ++ if (*s1 != *s2) ++ break; ++ ++ return in_charset(s1, ok) && in_charset(s2, ok); ++} +diff --git a/src/basic/string-util.h b/src/basic/string-util.h +index 9155e50ba8..0bf215827e 100644 +--- a/src/basic/string-util.h ++++ b/src/basic/string-util.h +@@ -242,3 +242,5 @@ int string_contains_word_strv(const char *string, const char *separators, char * + static inline int string_contains_word(const char *string, const char *separators, const char *word) { + return string_contains_word_strv(string, separators, STRV_MAKE(word), NULL); + } ++ ++bool streq_skip_trailing_chars(const char *s1, const char *s2, const char *ok); +diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c +index 4d9d0260c9..9a9c974332 100644 +--- a/src/test/test-string-util.c ++++ b/src/test/test-string-util.c +@@ -1000,6 +1000,33 @@ static void test_strextendf(void) { + assert_se(streq(p, "<77>,<99>,< 88>,<00001234>")); + } + ++static void test_streq_skip_trailing_chars(void) { ++ log_info("/* %s */", __func__); ++ ++ /* NULL is WHITESPACE by default*/ ++ assert_se(streq_skip_trailing_chars("foo bar", "foo bar", NULL)); ++ assert_se(streq_skip_trailing_chars("foo", "foo", NULL)); ++ assert_se(streq_skip_trailing_chars("foo bar ", "foo bar", NULL)); ++ assert_se(streq_skip_trailing_chars("foo bar", "foo bar\t\t", NULL)); ++ assert_se(streq_skip_trailing_chars("foo bar ", "foo bar\t\t", NULL)); ++ assert_se(streq_skip_trailing_chars("foo\nbar", "foo\nbar", NULL)); ++ assert_se(streq_skip_trailing_chars("\t\tfoo bar", "\t\tfoo bar", NULL)); ++ assert_se(streq_skip_trailing_chars(" foo bar\t", " foo bar\n", NULL)); ++ ++ assert_se(!streq_skip_trailing_chars("foobar", "foo bar", NULL)); ++ assert_se(!streq_skip_trailing_chars("foo\nbar", "foo\tbar", NULL)); ++ assert_se(!streq_skip_trailing_chars("\t\nfoo bar", "\t foo bar", NULL)); ++ ++ assert_se(streq_skip_trailing_chars("foo bar ", "foo bar", WHITESPACE)); ++ assert_se(!streq_skip_trailing_chars("foo bar ", "foo bar", NEWLINE)); ++ ++ assert_se(streq_skip_trailing_chars(NULL, NULL, NULL)); ++ assert_se(streq_skip_trailing_chars("", "", NULL)); ++ assert_se(!streq_skip_trailing_chars(NULL, "foo bar", NULL)); ++ assert_se(!streq_skip_trailing_chars("foo", NULL, NULL)); ++ assert_se(!streq_skip_trailing_chars("", "f", NULL)); ++} ++ + int main(int argc, char *argv[]) { + test_setup_logging(LOG_DEBUG); + +@@ -1039,6 +1066,7 @@ int main(int argc, char *argv[]) { + test_string_contains_word(); + test_strverscmp_improved(); + test_strextendf(); ++ test_streq_skip_trailing_chars(); + + return 0; + } +-- +2.31.1 + + +From a2552e17829d0090db3ff5f2e6f2d772d0fca3e9 Mon Sep 17 00:00:00 2001 +From: Antony Deepak Thomas +Date: Wed, 29 Sep 2021 13:06:25 +0900 +Subject: [PATCH 3/4] fileio: introduce new mode to suppress writing the same + value + +--- + src/basic/fileio.c | 29 +++++++++++++++++++++++++++-- + src/basic/fileio.h | 23 ++++++++++++----------- + 2 files changed, 39 insertions(+), 13 deletions(-) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index 4a0d060105..729789ce47 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -146,6 +146,30 @@ int write_string_stream_ts( + return -EBADF; + } + ++ if (flags & WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) { ++ _cleanup_free_ char *t = NULL; ++ ++ /* If value to be written is same as that of the existing value, then suppress the write. */ ++ ++ if (fd < 0) { ++ fd = fileno(f); ++ if (fd < 0) ++ return -EBADF; ++ } ++ ++ /* Read an additional byte to detect cases where the prefix matches but the rest ++ * doesn't. Also, 0 returned by read_virtual_file_fd() means the read was truncated and ++ * it won't be equal to the new value. */ ++ if (read_virtual_file_fd(fd, strlen(line)+1, &t, NULL) > 0 && ++ streq_skip_trailing_chars(line, t, NEWLINE)) { ++ log_debug("No change in value '%s', supressing write", line); ++ return 0; ++ } ++ ++ if (lseek(fd, 0, SEEK_SET) < 0) ++ return -errno; ++ } ++ + needs_nl = !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n"); + + if (needs_nl && (flags & WRITE_STRING_FILE_DISABLE_BUFFER)) { +@@ -261,10 +285,11 @@ int write_string_file_ts( + assert(!ts); + + /* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */ +- fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY | ++ fd = open(fn, O_CLOEXEC|O_NOCTTY | + (FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) | + (FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) | +- (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0), ++ (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) | ++ (FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY), + (FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 : 0666)); + if (fd < 0) { + r = -errno; +diff --git a/src/basic/fileio.h b/src/basic/fileio.h +index 82330840bf..a72b2f3881 100644 +--- a/src/basic/fileio.h ++++ b/src/basic/fileio.h +@@ -15,17 +15,18 @@ + #define LONG_LINE_MAX (1U*1024U*1024U) + + typedef enum { +- WRITE_STRING_FILE_CREATE = 1 << 0, +- WRITE_STRING_FILE_TRUNCATE = 1 << 1, +- WRITE_STRING_FILE_ATOMIC = 1 << 2, +- WRITE_STRING_FILE_AVOID_NEWLINE = 1 << 3, +- WRITE_STRING_FILE_VERIFY_ON_FAILURE = 1 << 4, +- WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE = 1 << 5, +- WRITE_STRING_FILE_SYNC = 1 << 6, +- WRITE_STRING_FILE_DISABLE_BUFFER = 1 << 7, +- WRITE_STRING_FILE_NOFOLLOW = 1 << 8, +- WRITE_STRING_FILE_MKDIR_0755 = 1 << 9, +- WRITE_STRING_FILE_MODE_0600 = 1 << 10, ++ WRITE_STRING_FILE_CREATE = 1 << 0, ++ WRITE_STRING_FILE_TRUNCATE = 1 << 1, ++ WRITE_STRING_FILE_ATOMIC = 1 << 2, ++ WRITE_STRING_FILE_AVOID_NEWLINE = 1 << 3, ++ WRITE_STRING_FILE_VERIFY_ON_FAILURE = 1 << 4, ++ WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE = 1 << 5, ++ WRITE_STRING_FILE_SYNC = 1 << 6, ++ WRITE_STRING_FILE_DISABLE_BUFFER = 1 << 7, ++ WRITE_STRING_FILE_NOFOLLOW = 1 << 8, ++ WRITE_STRING_FILE_MKDIR_0755 = 1 << 9, ++ WRITE_STRING_FILE_MODE_0600 = 1 << 10, ++ WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL = 1 << 11, + + /* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one + more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file() +-- +2.31.1 + + +From 41d86b627331f432454280714dd5b17d255367ba Mon Sep 17 00:00:00 2001 +From: Antony Deepak Thomas +Date: Wed, 29 Sep 2021 13:07:42 +0900 +Subject: [PATCH 4/4] sysctl-util: minimize side-effects when running + `systemd-sysctl` + +Currently `systemd-sysctl` binary is used in `systemd-sysctl.service` +which is mostly configured as `oneshot`. There are situations where one +would like to use systemd to maintain Sysctl configurations on a host, +using a configuration managers such as Chef or Puppet, by apply +configurations every X duration. +The problem with using `systemd-sysctl` is that it writes all the Sysctl +settings, even if the values for those settings have not changed. From +experience, we have observed that some Sysctl settings cause actions in +the kernel upon writing(like dropping caches) which in turn cause +undesired side effects. +This patch tries to minimize such side effects by comparing values +before writing. +--- + src/basic/sysctl-util.c | 19 +++++-------------- + 1 file changed, 5 insertions(+), 14 deletions(-) + +diff --git a/src/basic/sysctl-util.c b/src/basic/sysctl-util.c +index 8913e6ff85..4da3eaf5f7 100644 +--- a/src/basic/sysctl-util.c ++++ b/src/basic/sysctl-util.c +@@ -44,25 +44,16 @@ char *sysctl_normalize(char *s) { + + int sysctl_write(const char *property, const char *value) { + char *p; +- _cleanup_close_ int fd = -1; +- + assert(property); + assert(value); +- +- log_debug("Setting '%s' to '%.*s'.", property, (int) strcspn(value, NEWLINE), value); +- + p = strjoina("/proc/sys/", property); +- fd = open(p, O_WRONLY|O_CLOEXEC); +- if (fd < 0) +- return -errno; ++ path_simplify(p); ++ if (!path_is_normalized(p)) ++ return -EINVAL; + +- if (!endswith(value, "\n")) +- value = strjoina(value, "\n"); +- +- if (write(fd, value, strlen(value)) < 0) +- return -errno; ++ log_debug("Setting '%s' to '%s'", p, value); + +- return 0; ++ return write_string_file(p, value, WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER | WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL); + } + + int sysctl_writef(const char *property, const char *format, ...) { +-- +2.31.1 + diff --git a/SOURCES/20978.patch b/SOURCES/20978.patch new file mode 100644 index 0000000..8330e00 --- /dev/null +++ b/SOURCES/20978.patch @@ -0,0 +1,126 @@ +From a58dea6130fdcccd8cdf50633c939b45e2b32189 Mon Sep 17 00:00:00 2001 +From: Anita Zhang +Date: Mon, 11 Oct 2021 00:25:20 -0700 +Subject: [PATCH] core: serialize device cgroup bpf progs across + daemon-reload/reexec + +Follows what was done in b57d75232615f98aefcf41cb145ec2ea3262857d and +adds a test that verifies the device BPF program is not detached during +reload/reexec. +--- + src/core/unit-serialize.c | 4 ++++ + test/TEST-66-DEVICE-ISOLATION/Makefile | 1 + + test/TEST-66-DEVICE-ISOLATION/test.sh | 10 ++++++++ + .../testsuite-66-deviceisolation.service | 9 ++++++++ + test/units/testsuite-66.service | 7 ++++++ + test/units/testsuite-66.sh | 23 +++++++++++++++++++ + 6 files changed, 54 insertions(+) + create mode 120000 test/TEST-66-DEVICE-ISOLATION/Makefile + create mode 100755 test/TEST-66-DEVICE-ISOLATION/test.sh + create mode 100644 test/units/testsuite-66-deviceisolation.service + create mode 100644 test/units/testsuite-66.service + create mode 100755 test/units/testsuite-66.sh + +diff --git a/src/core/unit-serialize.c b/src/core/unit-serialize.c +index 9e1664ff53af..3458d7017bd5 100644 +--- a/src/core/unit-serialize.c ++++ b/src/core/unit-serialize.c +@@ -171,6 +171,7 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool switching_root) { + + (void) bpf_program_serialize_attachment(f, fds, "ip-bpf-ingress-installed", u->ip_bpf_ingress_installed); + (void) bpf_program_serialize_attachment(f, fds, "ip-bpf-egress-installed", u->ip_bpf_egress_installed); ++ (void) bpf_program_serialize_attachment(f, fds, "bpf-device-control-installed", u->bpf_device_control_installed); + (void) bpf_program_serialize_attachment_set(f, fds, "ip-bpf-custom-ingress-installed", u->ip_bpf_custom_ingress_installed); + (void) bpf_program_serialize_attachment_set(f, fds, "ip-bpf-custom-egress-installed", u->ip_bpf_custom_egress_installed); + +@@ -408,6 +409,9 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { + } else if (streq(l, "ip-bpf-egress-installed")) { + (void) bpf_program_deserialize_attachment(v, fds, &u->ip_bpf_egress_installed); + continue; ++ } else if (streq(l, "bpf-device-control-installed")) { ++ (void) bpf_program_deserialize_attachment(v, fds, &u->bpf_device_control_installed); ++ continue; + + } else if (streq(l, "ip-bpf-custom-ingress-installed")) { + (void) bpf_program_deserialize_attachment_set(v, fds, &u->ip_bpf_custom_ingress_installed); +diff --git a/test/TEST-66-DEVICE-ISOLATION/Makefile b/test/TEST-66-DEVICE-ISOLATION/Makefile +new file mode 120000 +index 000000000000..e9f93b1104cd +--- /dev/null ++++ b/test/TEST-66-DEVICE-ISOLATION/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-66-DEVICE-ISOLATION/test.sh b/test/TEST-66-DEVICE-ISOLATION/test.sh +new file mode 100755 +index 000000000000..534e43e493e6 +--- /dev/null ++++ b/test/TEST-66-DEVICE-ISOLATION/test.sh +@@ -0,0 +1,10 @@ ++#!/usr/bin/env bash ++set -e ++ ++TEST_DESCRIPTION="test device isolation" ++TEST_NO_NSPAWN=1 ++ ++# shellcheck source=test/test-functions ++. "${TEST_BASE_DIR:?}/test-functions" ++ ++do_test "$@" +diff --git a/test/units/testsuite-66-deviceisolation.service b/test/units/testsuite-66-deviceisolation.service +new file mode 100644 +index 000000000000..0022a9a45724 +--- /dev/null ++++ b/test/units/testsuite-66-deviceisolation.service +@@ -0,0 +1,9 @@ ++[Unit] ++Description=Service that uses device isolation ++ ++[Service] ++DevicePolicy=strict ++DeviceAllow=/dev/null r ++StandardOutput=file:/testsuite66serviceresults ++ExecStartPre=rm -f /testsuite66serviceresults ++ExecStart=/bin/bash -c "while true; do sleep 0.01 && echo meow > /dev/null && echo thisshouldnotbehere; done" +diff --git a/test/units/testsuite-66.service b/test/units/testsuite-66.service +new file mode 100644 +index 000000000000..a97974a4262d +--- /dev/null ++++ b/test/units/testsuite-66.service +@@ -0,0 +1,7 @@ ++[Unit] ++Description=TESTSUITE-66-DEVICEISOLATION ++ ++[Service] ++ExecStartPre=rm -f /failed /testok ++ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh ++Type=oneshot +diff --git a/test/units/testsuite-66.sh b/test/units/testsuite-66.sh +new file mode 100755 +index 000000000000..870dca42e169 +--- /dev/null ++++ b/test/units/testsuite-66.sh +@@ -0,0 +1,23 @@ ++#!/usr/bin/env bash ++set -eux ++set -o pipefail ++ ++systemd-analyze log-level debug ++systemd-analyze log-target console ++ ++systemctl start testsuite-66-deviceisolation.service ++ ++grep -q "Operation not permitted" /testsuite66serviceresults ++ ++systemctl daemon-reload ++systemctl daemon-reexec ++ ++systemctl stop testsuite-66-deviceisolation.service ++ ++grep -q "thisshouldnotbehere" /testsuite66serviceresults && exit 42 ++ ++systemd-analyze log-level info ++ ++echo OK >/testok ++ ++exit 0 diff --git a/SOURCES/50783f91d44b1978c0e4ba62283131fac75d3745_cherrypicked.patch b/SOURCES/50783f91d44b1978c0e4ba62283131fac75d3745_cherrypicked.patch new file mode 100644 index 0000000..6b148ad --- /dev/null +++ b/SOURCES/50783f91d44b1978c0e4ba62283131fac75d3745_cherrypicked.patch @@ -0,0 +1,116 @@ +From 1035e36675e10522824476c9084ff1001039c054 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 1 Oct 2021 09:22:18 +0900 +Subject: [PATCH] network: drop and warn duplicated Address= settings + +Fixes #20891. +--- + src/network/networkd-address.c | 43 +++++++++++++++++++++++++++++++--- + src/network/networkd-address.h | 2 +- + src/network/networkd-network.c | 6 ++++- + 3 files changed, 46 insertions(+), 5 deletions(-) + +diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c +index 7b221516d7..e1bc6aa474 100644 +--- a/src/network/networkd-address.c ++++ b/src/network/networkd-address.c +@@ -304,6 +304,12 @@ bool address_equal(const Address *a1, const Address *a2) { + return address_compare_func(a1, a2) == 0; + } + ++DEFINE_PRIVATE_HASH_OPS( ++ address_hash_ops_new, ++ Address, ++ address_hash_func, ++ address_compare_func); ++ + int address_dup(const Address *src, Address **ret) { + _cleanup_(address_freep) Address *dest = NULL; + int r; +@@ -1988,12 +1994,43 @@ static int address_section_verify(Address *address) { + return 0; + } + +-void network_drop_invalid_addresses(Network *network) { ++int network_drop_invalid_addresses(Network *network) { ++ _cleanup_set_free_ Set *addresses = NULL; + Address *address; ++ int r; + + assert(network); + +- ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section) +- if (address_section_verify(address) < 0) ++ ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section) { ++ Address *dup; ++ ++ if (address_section_verify(address) < 0) { ++ /* Drop invalid [Address] sections or Address= settings in [Network]. ++ * Note that address_free() will drop the address from addresses_by_section. */ + address_free(address); ++ continue; ++ } ++ ++ /* Always use the setting specified later. So, remove the previously assigned setting. */ ++ dup = set_remove(addresses, address); ++ if (dup) { ++ _cleanup_free_ char *buf = NULL; ++ ++ (void) in_addr_prefix_to_string(address->family, &address->in_addr, address->prefixlen, &buf); ++ log_warning("%s: Duplicated address %s is specified at line %u and %u, " ++ "dropping the address setting specified at line %u.", ++ dup->section->filename, strna(buf), address->section->line, ++ dup->section->line, dup->section->line); ++ /* address_free() will drop the address from addresses_by_section. */ ++ address_free(dup); ++ } ++ ++ /* Do not use address_hash_ops_free here. Otherwise, all address settings will be freed. */ ++ r = set_ensure_put(&addresses, &address_hash_ops_new, address); ++ if (r < 0) ++ return log_oom(); ++ assert(r > 0); ++ } ++ ++ return 0; + } +diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h +index ff3d46abdd..55d22ad221 100644 +--- a/src/network/networkd-address.h ++++ b/src/network/networkd-address.h +@@ -85,7 +85,7 @@ int request_process_address(Request *req); + + int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, Manager *m); + +-void network_drop_invalid_addresses(Network *network); ++int network_drop_invalid_addresses(Network *network); + + void address_hash_func(const Address *a, struct siphash *state); + int address_compare_func(const Address *a1, const Address *a2); +diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c +index 2a864a38b1..920f7851ba 100644 +--- a/src/network/networkd-network.c ++++ b/src/network/networkd-network.c +@@ -119,6 +119,8 @@ static int network_resolve_stacked_netdevs(Network *network) { + } + + int network_verify(Network *network) { ++ int r; ++ + assert(network); + assert(network->filename); + +@@ -252,7 +254,9 @@ int network_verify(Network *network) { + network->ipv6_proxy_ndp_addresses = set_free_free(network->ipv6_proxy_ndp_addresses); + } + +- network_drop_invalid_addresses(network); ++ r = network_drop_invalid_addresses(network); ++ if (r < 0) ++ return r; + network_drop_invalid_routes(network); + network_drop_invalid_nexthops(network); + network_drop_invalid_bridge_fdb_entries(network); +-- +2.31.1 + diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index d514bc8..25924ab 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -40,7 +40,7 @@ Name: systemd Url: https://www.freedesktop.org/wiki/Software/systemd %if %{without inplace} Version: 249.4 -Release: 2.4%{?dist} +Release: 2.5%{?dist} %else # determine the build information from local checkout Version: %(tools/meson-vcs-tag.sh . error | sed -r 's/-([0-9])/.^\1/; s/-g/_g/') @@ -126,9 +126,17 @@ Patch0013: https://github.com/systemd/systemd/pull/20450.patch Patch0014: https://github.com/systemd/systemd/pull/20541.patch Patch0015: https://github.com/systemd/systemd/pull/20729.patch Patch0016: https://github.com/systemd/systemd/pull/20828.patch +# Part of PR #20892; it was difficult to backport the whole PR +Patch0017: 50783f91d44b1978c0e4ba62283131fac75d3745_cherrypicked.patch # PR 20875: allow verifying hidden (dot) files again -Patch0017: https://github.com/systemd/systemd/pull/20875.patch +Patch0018: https://github.com/systemd/systemd/pull/20875.patch + +# PR 20978: serialize bpf device programs across reloads/reexecs +Patch0019: https://github.com/systemd/systemd/pull/20978.patch + +# PR 20676: don't rewrite sysctls that are already set +Patch0020: 20676_cherrypicked.patch # Downstream-only patches (0500–9999) @@ -1073,6 +1081,11 @@ fi %endif %changelog +* Mon Oct 11 2021 Anita Zhang - 249.4-2.5 +- Remove duplicate Address= properties in network configs (part of PR #20892) +- Serialize bpf device programs across reloads/reexecs (PR #20978) +- Don't rewrite sysctls that are already set (PR #20676) + * Wed Oct 06 2021 Davide Cavalca - 249.4-2.4 - Drop qrencode-devel from BuildRequires as it's not actually used