summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/systemd
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/systemd')
-rw-r--r--meta/recipes-core/systemd/systemd-boot_244.5.bb (renamed from meta/recipes-core/systemd/systemd-boot_244.3.bb)0
-rw-r--r--meta/recipes-core/systemd/systemd-conf/wired.network1
-rw-r--r--meta/recipes-core/systemd/systemd-conf_244.3.bb3
-rw-r--r--meta/recipes-core/systemd/systemd-serialgetty.bb4
-rwxr-xr-xmeta/recipes-core/systemd/systemd-systemctl/systemctl22
-rw-r--r--meta/recipes-core/systemd/systemd.inc4
-rw-r--r--meta/recipes-core/systemd/systemd/00-create-volatile.conf1
-rw-r--r--meta/recipes-core/systemd/systemd/CVE-2018-21029.patch120
-rw-r--r--meta/recipes-core/systemd/systemd/CVE-2020-13529.patch42
-rw-r--r--meta/recipes-core/systemd/systemd/CVE-2020-13776.patch96
-rw-r--r--meta/recipes-core/systemd/systemd/CVE-2021-33910.patch67
-rw-r--r--meta/recipes-core/systemd/systemd/CVE-2021-3997-1.patch65
-rw-r--r--meta/recipes-core/systemd/systemd/CVE-2021-3997-2.patch101
-rw-r--r--meta/recipes-core/systemd/systemd/CVE-2021-3997-3.patch266
-rw-r--r--meta/recipes-core/systemd/systemd/CVE-2022-3821.patch47
-rw-r--r--meta/recipes-core/systemd/systemd/CVE-2023-26604-1.patch115
-rw-r--r--meta/recipes-core/systemd/systemd/CVE-2023-26604-2.patch264
-rw-r--r--meta/recipes-core/systemd/systemd/CVE-2023-26604-3.patch182
-rw-r--r--meta/recipes-core/systemd/systemd/CVE-2023-26604-4.patch32
-rw-r--r--meta/recipes-core/systemd/systemd/basic-pass-allocation-info-for-ordered-set-new-and-introd.patch78
-rw-r--r--meta/recipes-core/systemd/systemd/introduce-ordered_set_clear-free-with-destructor.patch35
-rw-r--r--meta/recipes-core/systemd/systemd/network-add-skeleton-of-request-queue.patch285
-rw-r--r--meta/recipes-core/systemd/systemd/network-also-drop-requests-when-link-enters-linger-state.patch50
-rw-r--r--meta/recipes-core/systemd/systemd/network-fix-Link-reference-counter-issue.patch278
-rw-r--r--meta/recipes-core/systemd/systemd/network-merge-link_drop-and-link_detach_from_manager.patch67
-rw-r--r--meta/recipes-core/systemd/systemd/rm-rf-optionally-fsync-after-removing-directory-tree.patch35
-rw-r--r--meta/recipes-core/systemd/systemd/rm-rf-refactor-rm-rf-children-split-out-body-of-directory.patch318
-rw-r--r--meta/recipes-core/systemd/systemd/systemd-pager.sh7
-rw-r--r--meta/recipes-core/systemd/systemd_244.5.bb (renamed from meta/recipes-core/systemd/systemd_244.3.bb)39
29 files changed, 2511 insertions, 113 deletions
diff --git a/meta/recipes-core/systemd/systemd-boot_244.3.bb b/meta/recipes-core/systemd/systemd-boot_244.5.bb
index f92c639810..f92c639810 100644
--- a/meta/recipes-core/systemd/systemd-boot_244.3.bb
+++ b/meta/recipes-core/systemd/systemd-boot_244.5.bb
diff --git a/meta/recipes-core/systemd/systemd-conf/wired.network b/meta/recipes-core/systemd/systemd-conf/wired.network
index ff807ba31f..34c20fcb24 100644
--- a/meta/recipes-core/systemd/systemd-conf/wired.network
+++ b/meta/recipes-core/systemd/systemd-conf/wired.network
@@ -1,6 +1,7 @@
[Match]
Name=en* eth*
KernelCommandLine=!nfsroot
+KernelCommandLine=!ip
[Network]
DHCP=yes
diff --git a/meta/recipes-core/systemd/systemd-conf_244.3.bb b/meta/recipes-core/systemd/systemd-conf_244.3.bb
index d9ec023bfd..9b797a91f4 100644
--- a/meta/recipes-core/systemd/systemd-conf_244.3.bb
+++ b/meta/recipes-core/systemd/systemd-conf_244.3.bb
@@ -23,9 +23,6 @@ do_install() {
# Based on change from YP bug 8141, OE commit 5196d7bacaef1076c361adaa2867be31759c1b52
do_install_append_qemuall() {
install -D -m0644 ${WORKDIR}/system.conf-qemuall ${D}${systemd_unitdir}/system.conf.d/01-${PN}.conf
-
- # Do not install wired.network for qemu bsps
- rm -rf ${D}${systemd_unitdir}/network
}
PACKAGE_ARCH = "${MACHINE_ARCH}"
diff --git a/meta/recipes-core/systemd/systemd-serialgetty.bb b/meta/recipes-core/systemd/systemd-serialgetty.bb
index 044c6c5b67..0cc0dc8c79 100644
--- a/meta/recipes-core/systemd/systemd-serialgetty.bb
+++ b/meta/recipes-core/systemd/systemd-serialgetty.bb
@@ -21,7 +21,7 @@ do_install() {
install -d ${D}${systemd_unitdir}/system/
install -d ${D}${sysconfdir}/systemd/system/getty.target.wants/
install -m 0644 ${WORKDIR}/serial-getty@.service ${D}${systemd_unitdir}/system/
- sed -i -e s/\@BAUDRATE\@/$default_baudrate/g ${D}${systemd_unitdir}/system/serial-getty@.service
+ sed -i -e "s/\@BAUDRATE\@/$default_baudrate/g" ${D}${systemd_unitdir}/system/serial-getty@.service
tmp="${SERIAL_CONSOLES}"
for entry in $tmp ; do
@@ -34,7 +34,7 @@ do_install() {
else
# install custom service file for the non-default baudrate
install -m 0644 ${WORKDIR}/serial-getty@.service ${D}${systemd_unitdir}/system/serial-getty$baudrate@.service
- sed -i -e s/\@BAUDRATE\@/$baudrate/g ${D}${systemd_unitdir}/system/serial-getty$baudrate@.service
+ sed -i -e "s/\@BAUDRATE\@/$baudrate/g" ${D}${systemd_unitdir}/system/serial-getty$baudrate@.service
# enable the service
ln -sf ${systemd_unitdir}/system/serial-getty$baudrate@.service \
${D}${sysconfdir}/systemd/system/getty.target.wants/serial-getty$baudrate@$ttydev.service
diff --git a/meta/recipes-core/systemd/systemd-systemctl/systemctl b/meta/recipes-core/systemd/systemd-systemctl/systemctl
index 990de1ab39..e003c860e3 100755
--- a/meta/recipes-core/systemd/systemd-systemctl/systemctl
+++ b/meta/recipes-core/systemd/systemd-systemctl/systemctl
@@ -11,6 +11,7 @@ import re
import sys
from collections import namedtuple
+from itertools import chain
from pathlib import Path
version = 1.0
@@ -25,12 +26,16 @@ locations = list()
class SystemdFile():
"""Class representing a single systemd configuration file"""
- def __init__(self, root, path):
+ def __init__(self, root, path, instance_unit_name):
self.sections = dict()
self._parse(root, path)
dirname = os.path.basename(path.name) + ".d"
for location in locations:
- for path2 in sorted((root / location / "system" / dirname).glob("*.conf")):
+ files = (root / location / "system" / dirname).glob("*.conf")
+ if instance_unit_name:
+ inst_dirname = instance_unit_name + ".d"
+ files = chain(files, (root / location / "system" / inst_dirname).glob("*.conf"))
+ for path2 in sorted(files):
self._parse(root, path2)
def _parse(self, root, path):
@@ -177,12 +182,14 @@ class SystemdUnit():
raise SystemdUnitNotFoundError(self.root, unit)
- def _process_deps(self, config, service, location, prop, dirstem):
+ def _process_deps(self, config, service, location, prop, dirstem, instance):
systemdir = self.root / SYSCONFDIR / "systemd" / "system"
target = ROOT / location.relative_to(self.root)
try:
for dependent in config.get('Install', prop):
+ # expand any %i to instance (ignoring escape sequence %%)
+ dependent = re.sub("([^%](%%)*)%i", "\\g<1>{}".format(instance), dependent)
wants = systemdir / "{}.{}".format(dependent, dirstem) / service
add_link(wants, target)
@@ -193,8 +200,11 @@ class SystemdUnit():
# if we're enabling an instance, first extract the actual instance
# then figure out what the template unit is
template = re.match(r"[^@]+@(?P<instance>[^\.]*)\.", self.unit)
+ instance_unit_name = None
if template:
instance = template.group('instance')
+ if instance != "":
+ instance_unit_name = self.unit
unit = re.sub(r"@[^\.]*\.", "@.", self.unit, 1)
else:
instance = None
@@ -206,7 +216,7 @@ class SystemdUnit():
# ignore aliases
return
- config = SystemdFile(self.root, path)
+ config = SystemdFile(self.root, path, instance_unit_name)
if instance == "":
try:
default_instance = config.get('Install', 'DefaultInstance')[0]
@@ -219,8 +229,8 @@ class SystemdUnit():
else:
service = self.unit
- self._process_deps(config, service, path, 'WantedBy', 'wants')
- self._process_deps(config, service, path, 'RequiredBy', 'requires')
+ self._process_deps(config, service, path, 'WantedBy', 'wants', instance)
+ self._process_deps(config, service, path, 'RequiredBy', 'requires', instance)
try:
for also in config.get('Install', 'Also'):
diff --git a/meta/recipes-core/systemd/systemd.inc b/meta/recipes-core/systemd/systemd.inc
index e73b397b5d..8b5260bb0d 100644
--- a/meta/recipes-core/systemd/systemd.inc
+++ b/meta/recipes-core/systemd/systemd.inc
@@ -14,8 +14,8 @@ LICENSE = "GPLv2 & LGPLv2.1"
LIC_FILES_CHKSUM = "file://LICENSE.GPL2;md5=751419260aa954499f7abaabaa882bbe \
file://LICENSE.LGPL2.1;md5=4fbd65380cdd255951079008b364516c"
-SRCREV = "b7ed902b2394f94e7f1fbe6c3194b5cd9a9429e6"
+SRCREV = "3ceaa81c61b654ebf562464d142675bd4d57d7b6"
SRCBRANCH = "v244-stable"
-SRC_URI = "git://github.com/systemd/systemd-stable.git;protocol=git;branch=${SRCBRANCH}"
+SRC_URI = "git://github.com/systemd/systemd-stable.git;protocol=https;branch=${SRCBRANCH}"
S = "${WORKDIR}/git"
diff --git a/meta/recipes-core/systemd/systemd/00-create-volatile.conf b/meta/recipes-core/systemd/systemd/00-create-volatile.conf
index 87cbe1e7d3..c4277221a2 100644
--- a/meta/recipes-core/systemd/systemd/00-create-volatile.conf
+++ b/meta/recipes-core/systemd/systemd/00-create-volatile.conf
@@ -3,5 +3,6 @@
# inside /var/log.
+d /run/lock 1777 - - -
d /var/volatile/log - - - -
d /var/volatile/tmp 1777 - -
diff --git a/meta/recipes-core/systemd/systemd/CVE-2018-21029.patch b/meta/recipes-core/systemd/systemd/CVE-2018-21029.patch
new file mode 100644
index 0000000000..8d3801a248
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/CVE-2018-21029.patch
@@ -0,0 +1,120 @@
+From 3f9d9289ee8730a81a0464539f4e1ba2d23d0ce9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= <joerg@thalheim.io>
+Date: Tue, 3 Mar 2020 23:31:25 +0000
+Subject: [PATCH] systemd-resolved: use hostname for certificate validation in
+ DoT
+
+Widely accepted certificates for IP addresses are expensive and only
+affordable for larger organizations. Therefore if the user provides
+the hostname in the DNS= option, we should use it instead of the IP
+address.
+
+(cherry picked from commit eec394f10bbfcc3d2fc8504ad8ff5be44231abd5)
+
+CVE: CVE-2018-21029
+Upstream-Status: Backport [ff26d281aec0877b43269f18c6282cd79a7f5529]
+Signed-off-by: Marek Vasut <marex@denx.de>
+---
+ man/resolved.conf.xml | 16 +++++++++++-----
+ src/resolve/resolved-dnstls-gnutls.c | 20 ++++++++++++--------
+ src/resolve/resolved-dnstls-openssl.c | 15 +++++++++++----
+ 3 files changed, 34 insertions(+), 17 deletions(-)
+
+diff --git a/man/resolved.conf.xml b/man/resolved.conf.xml
+index 818000145b..37161ebcbc 100644
+--- a/man/resolved.conf.xml
++++ b/man/resolved.conf.xml
+@@ -193,11 +193,17 @@
+ <varlistentry>
+ <term><varname>DNSOverTLS=</varname></term>
+ <listitem>
+- <para>Takes a boolean argument or <literal>opportunistic</literal>.
+- If true all connections to the server will be encrypted. Note that
+- this mode requires a DNS server that supports DNS-over-TLS and has
+- a valid certificate for it's IP. If the DNS server does not support
+- DNS-over-TLS all DNS requests will fail. When set to <literal>opportunistic</literal>
++ <para>Takes a boolean argument or <literal>opportunistic</literal>. If
++ true all connections to the server will be encrypted. Note that this
++ mode requires a DNS server that supports DNS-over-TLS and has a valid
++ certificate. If the hostname was specified in <varname>DNS=</varname>
++ by using the format format <literal>address#server_name</literal> it
++ is used to validate its certificate and also to enable Server Name
++ Indication (SNI) when opening a TLS connection. Otherwise
++ the certificate is checked against the server's IP.
++ If the DNS server does not support DNS-over-TLS all DNS requests will fail.</para>
++
++ <para>When set to <literal>opportunistic</literal>
+ DNS request are attempted to send encrypted with DNS-over-TLS.
+ If the DNS server does not support TLS, DNS-over-TLS is disabled.
+ Note that this mode makes DNS-over-TLS vulnerable to "downgrade"
+diff --git a/src/resolve/resolved-dnstls-gnutls.c b/src/resolve/resolved-dnstls-gnutls.c
+index ed0a31e8bf..c7215723a7 100644
+--- a/src/resolve/resolved-dnstls-gnutls.c
++++ b/src/resolve/resolved-dnstls-gnutls.c
+@@ -56,15 +56,19 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
+ }
+
+ if (server->manager->dns_over_tls_mode == DNS_OVER_TLS_YES) {
+- stream->dnstls_data.validation.type = GNUTLS_DT_IP_ADDRESS;
+- if (server->family == AF_INET) {
+- stream->dnstls_data.validation.data = (unsigned char*) &server->address.in.s_addr;
+- stream->dnstls_data.validation.size = 4;
+- } else {
+- stream->dnstls_data.validation.data = server->address.in6.s6_addr;
+- stream->dnstls_data.validation.size = 16;
++ if (server->server_name)
++ gnutls_session_set_verify_cert(gs, server->server_name, 0);
++ else {
++ stream->dnstls_data.validation.type = GNUTLS_DT_IP_ADDRESS;
++ if (server->family == AF_INET) {
++ stream->dnstls_data.validation.data = (unsigned char*) &server->address.in.s_addr;
++ stream->dnstls_data.validation.size = 4;
++ } else {
++ stream->dnstls_data.validation.data = server->address.in6.s6_addr;
++ stream->dnstls_data.validation.size = 16;
++ }
++ gnutls_session_set_verify_cert2(gs, &stream->dnstls_data.validation, 1, 0);
+ }
+- gnutls_session_set_verify_cert2(gs, &stream->dnstls_data.validation, 1, 0);
+ }
+
+ gnutls_handshake_set_timeout(gs, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
+diff --git a/src/resolve/resolved-dnstls-openssl.c b/src/resolve/resolved-dnstls-openssl.c
+index 85e202ff74..007aedaa5b 100644
+--- a/src/resolve/resolved-dnstls-openssl.c
++++ b/src/resolve/resolved-dnstls-openssl.c
+@@ -6,6 +6,7 @@
+
+ #include <openssl/bio.h>
+ #include <openssl/err.h>
++#include <openssl/x509v3.h>
+
+ #include "io-util.h"
+ #include "resolved-dns-stream.h"
+@@ -78,13 +79,19 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
+
+ if (server->manager->dns_over_tls_mode == DNS_OVER_TLS_YES) {
+ X509_VERIFY_PARAM *v;
+- const unsigned char *ip;
+
+ SSL_set_verify(s, SSL_VERIFY_PEER, NULL);
+ v = SSL_get0_param(s);
+- ip = server->family == AF_INET ? (const unsigned char*) &server->address.in.s_addr : server->address.in6.s6_addr;
+- if (!X509_VERIFY_PARAM_set1_ip(v, ip, FAMILY_ADDRESS_SIZE(server->family)))
+- return -ECONNREFUSED;
++ if (server->server_name) {
++ X509_VERIFY_PARAM_set_hostflags(v, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
++ if (X509_VERIFY_PARAM_set1_host(v, server->server_name, 0) == 0)
++ return -ECONNREFUSED;
++ } else {
++ const unsigned char *ip;
++ ip = server->family == AF_INET ? (const unsigned char*) &server->address.in.s_addr : server->address.in6.s6_addr;
++ if (X509_VERIFY_PARAM_set1_ip(v, ip, FAMILY_ADDRESS_SIZE(server->family)) == 0)
++ return -ECONNREFUSED;
++ }
+ }
+
+ ERR_clear_error();
+--
+2.40.1
+
diff --git a/meta/recipes-core/systemd/systemd/CVE-2020-13529.patch b/meta/recipes-core/systemd/systemd/CVE-2020-13529.patch
new file mode 100644
index 0000000000..6b499efbd8
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/CVE-2020-13529.patch
@@ -0,0 +1,42 @@
+From 38e980a6a5a3442c2f48b1f827284388096d8ca5 Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Thu, 24 Jun 2021 01:22:07 +0900
+Subject: [PATCH] sd-dhcp-client: tentatively ignore FORCERENEW command
+
+This makes DHCP client ignore FORCERENEW requests, as unauthenticated
+FORCERENEW requests causes a security issue (TALOS-2020-1142, CVE-2020-13529).
+
+Let's re-enable this after RFC3118 (Authentication for DHCP Messages)
+and/or RFC6704 (Forcerenew Nonce Authentication) are implemented.
+
+Fixes #16774.
+
+Upstream-Status: Backport [https://github.com/systemd/systemd/commit/38e980a6a5a3442c2f48b1f827284388096d8ca5]
+CVE: CVE-2020-13529
+
+Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
+
+---
+ src/libsystemd-network/sd-dhcp-client.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/src/libsystemd-network/sd-dhcp-client.c
++++ b/src/libsystemd-network/sd-dhcp-client.c
+@@ -1392,9 +1392,17 @@ static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
+ if (r != DHCP_FORCERENEW)
+ return -ENOMSG;
+
++#if 0
+ log_dhcp_client(client, "FORCERENEW");
+
+ return 0;
++#else
++ /* FIXME: Ignore FORCERENEW requests until we implement RFC3118 (Authentication for DHCP
++ * Messages) and/or RFC6704 (Forcerenew Nonce Authentication), as unauthenticated FORCERENEW
++ * requests causes a security issue (TALOS-2020-1142, CVE-2020-13529). */
++ log_dhcp_client(client, "Received FORCERENEW, ignoring.");
++ return -ENOMSG;
++#endif
+ }
+
+ static bool lease_equal(const sd_dhcp_lease *a, const sd_dhcp_lease *b) {
diff --git a/meta/recipes-core/systemd/systemd/CVE-2020-13776.patch b/meta/recipes-core/systemd/systemd/CVE-2020-13776.patch
deleted file mode 100644
index 7b5e3e7f7a..0000000000
--- a/meta/recipes-core/systemd/systemd/CVE-2020-13776.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 156a5fd297b61bce31630d7a52c15614bf784843 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Sun, 31 May 2020 18:21:09 +0200
-Subject: [PATCH 1/1] basic/user-util: always use base 10 for user/group
- numbers
-
-We would parse numbers with base prefixes as user identifiers. For example,
-"0x2b3bfa0" would be interpreted as UID==45334432 and "01750" would be
-interpreted as UID==1000. This parsing was used also in cases where either a
-user/group name or number may be specified. This means that names like
-0x2b3bfa0 would be ambiguous: they are a valid user name according to our
-documented relaxed rules, but they would also be parsed as numeric uids.
-
-This behaviour is definitely not expected by users, since tools generally only
-accept decimal numbers (e.g. id, getent passwd), while other tools only accept
-user names and thus will interpret such strings as user names without even
-attempting to convert them to numbers (su, ssh). So let's follow suit and only
-accept numbers in decimal notation. Effectively this means that we will reject
-such strings as a username/uid/groupname/gid where strict mode is used, and try
-to look up a user/group with such a name in relaxed mode.
-
-Since the function changed is fairly low-level and fairly widely used, this
-affects multiple tools: loginctl show-user/enable-linger/disable-linger foo',
-the third argument in sysusers.d, fourth and fifth arguments in tmpfiles.d,
-etc.
-
-Fixes #15985.
----
- src/basic/user-util.c | 2 +-
- src/test/test-user-util.c | 10 ++++++++++
- 2 files changed, 11 insertions(+), 1 deletion(-)
-
---- end of commit 156a5fd297b61bce31630d7a52c15614bf784843 ---
-
-
-Add definition of safe_atou32_full() from commit b934ac3d6e7dcad114776ef30ee9098693e7ab7e
-
-CVE: CVE-2020-13776
-
-Upstream-Status: Backport [https://github.com/systemd/systemd.git]
-
-Signed-off-by: Joe Slater <joe.slater@windriver.com>
-
-
-
---- git.orig/src/basic/user-util.c
-+++ git/src/basic/user-util.c
-@@ -49,7 +49,7 @@ int parse_uid(const char *s, uid_t *ret)
- assert(s);
-
- assert_cc(sizeof(uid_t) == sizeof(uint32_t));
-- r = safe_atou32(s, &uid);
-+ r = safe_atou32_full(s, 10, &uid);
- if (r < 0)
- return r;
-
---- git.orig/src/test/test-user-util.c
-+++ git/src/test/test-user-util.c
-@@ -48,9 +48,19 @@ static void test_parse_uid(void) {
-
- r = parse_uid("65535", &uid);
- assert_se(r == -ENXIO);
-+ assert_se(uid == 100);
-+
-+ r = parse_uid("0x1234", &uid);
-+ assert_se(r == -EINVAL);
-+ assert_se(uid == 100);
-+
-+ r = parse_uid("01234", &uid);
-+ assert_se(r == 0);
-+ assert_se(uid == 1234);
-
- r = parse_uid("asdsdas", &uid);
- assert_se(r == -EINVAL);
-+ assert_se(uid == 1234);
- }
-
- static void test_uid_ptr(void) {
---- git.orig/src/basic/parse-util.h
-+++ git/src/basic/parse-util.h
-@@ -45,9 +45,13 @@ static inline int safe_atoux16(const cha
-
- int safe_atoi16(const char *s, int16_t *ret);
-
--static inline int safe_atou32(const char *s, uint32_t *ret_u) {
-+static inline int safe_atou32_full(const char *s, unsigned base, uint32_t *ret_u) {
- assert_cc(sizeof(uint32_t) == sizeof(unsigned));
-- return safe_atou(s, (unsigned*) ret_u);
-+ return safe_atou_full(s, base, (unsigned*) ret_u);
-+}
-+
-+static inline int safe_atou32(const char *s, uint32_t *ret_u) {
-+ return safe_atou32_full(s, 0, (unsigned*) ret_u);
- }
-
- static inline int safe_atoi32(const char *s, int32_t *ret_i) {
diff --git a/meta/recipes-core/systemd/systemd/CVE-2021-33910.patch b/meta/recipes-core/systemd/systemd/CVE-2021-33910.patch
new file mode 100644
index 0000000000..e92d721d3d
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/CVE-2021-33910.patch
@@ -0,0 +1,67 @@
+Backport of:
+
+From 441e0115646d54f080e5c3bb0ba477c892861ab9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Wed, 23 Jun 2021 11:46:41 +0200
+Subject: [PATCH 1/2] 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.
+
+Upstream-Status: Backport [https://github.com/systemd/systemd/pull/20256/commits/441e0115646d54f080e5c3bb0ba477c892861ab9]
+CVE: CVE-2021-33910
+
+Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
+
+---
+ src/basic/unit-name.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+--- 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/meta/recipes-core/systemd/systemd/CVE-2021-3997-1.patch b/meta/recipes-core/systemd/systemd/CVE-2021-3997-1.patch
new file mode 100644
index 0000000000..341976822b
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/CVE-2021-3997-1.patch
@@ -0,0 +1,65 @@
+Backport of the following upstream commit:
+From fbb77e1e55866633c9f064e2b3bcf2b6402d962d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 23 Nov 2021 15:55:45 +0100
+Subject: [PATCH 1/3] shared/rm_rf: refactor rm_rf_children_inner() to shorten
+ code a bit
+
+CVE: CVE-2021-3997
+Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/s/systemd/systemd_245.4-4ubuntu3.15.debian.tar.xz]
+Signed-off-by: Purushottam Choudhary <Purushottam.Choudhary@kpit.com>
+---
+ src/basic/rm-rf.c | 27 +++++++++------------------
+ 1 file changed, 9 insertions(+), 18 deletions(-)
+
+--- a/src/basic/rm-rf.c
++++ b/src/basic/rm-rf.c
+@@ -34,7 +34,7 @@
+ const struct stat *root_dev) {
+
+ struct stat st;
+- int r;
++ int r, q = 0;
+
+ assert(fd >= 0);
+ assert(fname);
+@@ -50,7 +50,6 @@
+
+ if (is_dir) {
+ _cleanup_close_ int subdir_fd = -1;
+- int q;
+
+ /* if root_dev is set, remove subdirectories only if device is same */
+ if (root_dev && st.st_dev != root_dev->st_dev)
+@@ -86,23 +85,15 @@
+ * again for each directory */
+ q = rm_rf_children(TAKE_FD(subdir_fd), flags | REMOVE_PHYSICAL, root_dev);
+
+- r = unlinkat(fd, fname, AT_REMOVEDIR);
+- if (r < 0)
+- return r;
+- if (q < 0)
+- return q;
+-
+- return 1;
+-
+- } else if (!(flags & REMOVE_ONLY_DIRECTORIES)) {
+- r = unlinkat(fd, fname, 0);
+- if (r < 0)
+- return r;
+-
+- return 1;
+- }
++ } else if (flags & REMOVE_ONLY_DIRECTORIES)
++ return 0;
+
+- return 0;
++ r = unlinkat(fd, fname, is_dir ? AT_REMOVEDIR : 0);
++ if (r < 0)
++ return r;
++ if (q < 0)
++ return q;
++ return 1;
+ }
+
+ int rm_rf_children(
diff --git a/meta/recipes-core/systemd/systemd/CVE-2021-3997-2.patch b/meta/recipes-core/systemd/systemd/CVE-2021-3997-2.patch
new file mode 100644
index 0000000000..066e10fbbc
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/CVE-2021-3997-2.patch
@@ -0,0 +1,101 @@
+Backport of the following upstream commit:
+From bd0127daaaae009ade053718f7d2f297aee4acaf Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 23 Nov 2021 16:56:42 +0100
+Subject: [PATCH 2/3] shared/rm_rf: refactor rm_rf() to shorten code a bit
+
+CVE: CVE-2021-3997
+Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/s/systemd/systemd_245.4-4ubuntu3.15.debian.tar.xz]
+Signed-off-by: Purushottam Choudhary <Purushottam.Choudhary@kpit.com>
+---
+ src/basic/rm-rf.c | 53 ++++++++++++++++++++--------------------------
+ 1 file changed, 23 insertions(+), 30 deletions(-)
+
+--- a/src/basic/rm-rf.c
++++ b/src/basic/rm-rf.c
+@@ -159,7 +159,7 @@
+ }
+
+ int rm_rf(const char *path, RemoveFlags flags) {
+- int fd, r;
++ int fd, r, q = 0;
+
+ assert(path);
+
+@@ -191,49 +191,47 @@
+ }
+
+ fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
+- if (fd < 0) {
++ if (fd >= 0) {
++ /* We have a dir */
++ r = rm_rf_children(fd, flags, NULL);
++
++ if (FLAGS_SET(flags, REMOVE_ROOT)) {
++ q = rmdir(path);
++ if (q < 0)
++ q = -errno;
++ }
++ } else {
+ if (FLAGS_SET(flags, REMOVE_MISSING_OK) && errno == ENOENT)
+ return 0;
+
+ if (!IN_SET(errno, ENOTDIR, ELOOP))
+ return -errno;
+
+- if (FLAGS_SET(flags, REMOVE_ONLY_DIRECTORIES))
++ if (FLAGS_SET(flags, REMOVE_ONLY_DIRECTORIES) || !FLAGS_SET(flags, REMOVE_ROOT))
+ return 0;
+
+- if (FLAGS_SET(flags, REMOVE_ROOT)) {
+-
+- if (!FLAGS_SET(flags, REMOVE_PHYSICAL)) {
+- struct statfs s;
+-
+- if (statfs(path, &s) < 0)
+- return -errno;
+- if (is_physical_fs(&s))
+- return log_error_errno(SYNTHETIC_ERRNO(EPERM),
+- "Attempted to remove files from a disk file system under \"%s\", refusing.",
+- path);
+- }
+-
+- if (unlink(path) < 0) {
+- if (FLAGS_SET(flags, REMOVE_MISSING_OK) && errno == ENOENT)
+- return 0;
++ if (!FLAGS_SET(flags, REMOVE_PHYSICAL)) {
++ struct statfs s;
+
++ if (statfs(path, &s) < 0)
+ return -errno;
+- }
++ if (is_physical_fs(&s))
++ return log_error_errno(SYNTHETIC_ERRNO(EPERM),
++ "Attempted to remove files from a disk file system under \"%s\", refusing.",
++ path);
+ }
+
+- return 0;
++ r = 0;
++ q = unlink(path);
++ if (q < 0)
++ q = -errno;
+ }
+
+- r = rm_rf_children(fd, flags, NULL);
+-
+- if (FLAGS_SET(flags, REMOVE_ROOT) &&
+- rmdir(path) < 0 &&
+- r >= 0 &&
+- (!FLAGS_SET(flags, REMOVE_MISSING_OK) || errno != ENOENT))
+- r = -errno;
+-
+- return r;
++ if (r < 0)
++ return r;
++ if (q < 0 && (q != -ENOENT || !FLAGS_SET(flags, REMOVE_MISSING_OK)))
++ return q;
++ return 0;
+ }
+
+ int rm_rf_child(int fd, const char *name, RemoveFlags flags) {
diff --git a/meta/recipes-core/systemd/systemd/CVE-2021-3997-3.patch b/meta/recipes-core/systemd/systemd/CVE-2021-3997-3.patch
new file mode 100644
index 0000000000..c96b8d9a6e
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/CVE-2021-3997-3.patch
@@ -0,0 +1,266 @@
+Backport of the following upstream commit:
+From bef8e8e577368697b2e6f85183b1dbc99e0e520f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 30 Nov 2021 22:29:05 +0100
+Subject: [PATCH 3/3] shared/rm-rf: loop over nested directories instead of
+ instead of recursing
+
+To remove directory structures, we need to remove the innermost items first,
+and then recursively remove higher-level directories. We would recursively
+descend into directories and invoke rm_rf_children and rm_rm_children_inner.
+This is problematic when too many directories are nested.
+
+Instead, let's create a "TODO" queue. In the the queue, for each level we
+hold the DIR* object we were working on, and the name of the directory. This
+allows us to leave a partially-processed directory, and restart the removal
+loop one level down. When done with the inner directory, we use the name to
+unlinkat() it from the parent, and proceed with the removal of other items.
+
+Because the nesting is increased by one level, it is best to view this patch
+with -b/--ignore-space-change.
+
+This fixes CVE-2021-3997, https://bugzilla.redhat.com/show_bug.cgi?id=2024639.
+The issue was reported and patches reviewed by Qualys Team.
+Mauro Matteo Cascella and Riccardo Schirone from Red Hat handled the disclosure.
+
+CVE: CVE-2021-3997
+Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/s/systemd/systemd_245.4-4ubuntu3.15.debian.tar.xz]
+Signed-off-by: Purushottam Choudhary <Purushottam.Choudhary@kpit.com>
+---
+ src/basic/rm-rf.c | 161 +++++++++++++++++++++++++++++++--------------
+ 1 file changed, 113 insertions(+), 48 deletions(-)
+
+--- a/src/basic/rm-rf.c
++++ b/src/basic/rm-rf.c
+@@ -26,12 +26,13 @@
+ return !is_temporary_fs(sfs) && !is_cgroup_fs(sfs);
+ }
+
+-static int rm_rf_children_inner(
++static int rm_rf_inner_child(
+ int fd,
+ const char *fname,
+ int is_dir,
+ RemoveFlags flags,
+- const struct stat *root_dev) {
++ const struct stat *root_dev,
++ bool allow_recursion) {
+
+ struct stat st;
+ int r, q = 0;
+@@ -49,9 +50,7 @@
+ }
+
+ if (is_dir) {
+- _cleanup_close_ int subdir_fd = -1;
+-
+- /* if root_dev is set, remove subdirectories only if device is same */
++ /* If root_dev is set, remove subdirectories only if device is same */
+ if (root_dev && st.st_dev != root_dev->st_dev)
+ return 0;
+
+@@ -63,7 +62,6 @@
+ return 0;
+
+ if ((flags & REMOVE_SUBVOLUME) && st.st_ino == 256) {
+-
+ /* This could be a subvolume, try to remove it */
+
+ r = btrfs_subvol_remove_fd(fd, fname, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
+@@ -77,13 +75,16 @@
+ return 1;
+ }
+
+- subdir_fd = openat(fd, fname, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
++ if (!allow_recursion)
++ return -EISDIR;
++
++ int subdir_fd = openat(fd, fname, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
+ if (subdir_fd < 0)
+ return -errno;
+
+ /* We pass REMOVE_PHYSICAL here, to avoid doing the fstatfs() to check the file system type
+ * again for each directory */
+- q = rm_rf_children(TAKE_FD(subdir_fd), flags | REMOVE_PHYSICAL, root_dev);
++ q = rm_rf_children(subdir_fd, flags | REMOVE_PHYSICAL, root_dev);
+
+ } else if (flags & REMOVE_ONLY_DIRECTORIES)
+ return 0;
+@@ -96,64 +97,128 @@
+ return 1;
+ }
+
++typedef struct TodoEntry {
++ DIR *dir; /* A directory that we were operating on. */
++ char *dirname; /* The filename of that directory itself. */
++} TodoEntry;
++
++static void free_todo_entries(TodoEntry **todos) {
++ for (TodoEntry *x = *todos; x && x->dir; x++) {
++ closedir(x->dir);
++ free(x->dirname);
++ }
++
++ freep(todos);
++}
++
+ int rm_rf_children(
+ int fd,
+ RemoveFlags flags,
+ const struct stat *root_dev) {
+
+- _cleanup_closedir_ DIR *d = NULL;
+- struct dirent *de;
++ _cleanup_(free_todo_entries) TodoEntry *todos = NULL;
++ size_t n_todo = 0, allocated = 0;
++ _cleanup_free_ char *dirname = NULL; /* Set when we are recursing and want to delete ourselves */
+ int ret = 0, r;
+
+- assert(fd >= 0);
++ /* Return the first error we run into, but nevertheless try to go on.
++ * The passed fd is closed in all cases, including on failure. */
+
+- /* This returns the first error we run into, but nevertheless tries to go on. This closes the passed
+- * fd, in all cases, including on failure. */
++ for (;;) { /* This loop corresponds to the directory nesting level. */
++ _cleanup_closedir_ DIR *d = NULL;
++ struct dirent *de;
++
++ if (n_todo > 0) {
++ /* We know that we are in recursion here, because n_todo is set.
++ * We need to remove the inner directory we were operating on. */
++ assert(dirname);
++ r = unlinkat(dirfd(todos[n_todo-1].dir), dirname, AT_REMOVEDIR);
++ if (r < 0 && r != -ENOENT && ret == 0)
++ ret = r;
++ dirname = mfree(dirname);
++
++ /* And now let's back out one level up */
++ n_todo --;
++ d = TAKE_PTR(todos[n_todo].dir);
++ dirname = TAKE_PTR(todos[n_todo].dirname);
++
++ assert(d);
++ fd = dirfd(d); /* Retrieve the file descriptor from the DIR object */
++ assert(fd >= 0);
++ } else {
++ next_fd:
++ assert(fd >= 0);
++ d = fdopendir(fd);
++ if (!d) {
++ safe_close(fd);
++ return -errno;
++ }
++ fd = dirfd(d); /* We donated the fd to fdopendir(). Let's make sure we sure we have
++ * the right descriptor even if it were to internally invalidate the
++ * one we passed. */
++
++ if (!(flags & REMOVE_PHYSICAL)) {
++ struct statfs sfs;
++
++ if (fstatfs(fd, &sfs) < 0)
++ return -errno;
++
++ if (is_physical_fs(&sfs)) {
++ /* We refuse to clean physical file systems with this call, unless
++ * explicitly requested. This is extra paranoia just to be sure we
++ * never ever remove non-state data. */
++
++ _cleanup_free_ char *path = NULL;
++
++ (void) fd_get_path(fd, &path);
++ return log_error_errno(SYNTHETIC_ERRNO(EPERM),
++ "Attempted to remove disk file system under \"%s\", and we can't allow that.",
++ strna(path));
++ }
++ }
++ }
+
+- d = fdopendir(fd);
+- if (!d) {
+- safe_close(fd);
+- return -errno;
+- }
++ FOREACH_DIRENT_ALL(de, d, return -errno) {
++ int is_dir;
+
+- if (!(flags & REMOVE_PHYSICAL)) {
+- struct statfs sfs;
++ if (dot_or_dot_dot(de->d_name))
++ continue;
+
+- if (fstatfs(dirfd(d), &sfs) < 0)
+- return -errno;
+- }
++ is_dir = de->d_type == DT_UNKNOWN ? -1 : de->d_type == DT_DIR;
+
+- if (is_physical_fs(&sfs)) {
+- /* We refuse to clean physical file systems with this call, unless explicitly
+- * requested. This is extra paranoia just to be sure we never ever remove non-state
+- * data. */
+-
+- _cleanup_free_ char *path = NULL;
+-
+- (void) fd_get_path(fd, &path);
+- return log_error_errno(SYNTHETIC_ERRNO(EPERM),
+- "Attempted to remove disk file system under \"%s\", and we can't allow that.",
+- strna(path));
+- }
+- }
++ r = rm_rf_inner_child(fd, de->d_name, is_dir, flags, root_dev, false);
++ if (r == -EISDIR) {
++ /* Push the current working state onto the todo list */
+
+- FOREACH_DIRENT_ALL(de, d, return -errno) {
+- int is_dir;
++ if (!GREEDY_REALLOC0(todos, allocated, n_todo + 2))
++ return log_oom();
+
+- if (dot_or_dot_dot(de->d_name))
+- continue;
++ _cleanup_free_ char *newdirname = strdup(de->d_name);
++ if (!newdirname)
++ return log_oom();
+
+- is_dir =
+- de->d_type == DT_UNKNOWN ? -1 :
+- de->d_type == DT_DIR;
+-
+- r = rm_rf_children_inner(dirfd(d), de->d_name, is_dir, flags, root_dev);
+- if (r < 0 && r != -ENOENT && ret == 0)
+- ret = r;
+- }
++ int newfd = openat(fd, de->d_name,
++ O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
++ if (newfd >= 0) {
++ todos[n_todo++] = (TodoEntry) { TAKE_PTR(d), TAKE_PTR(dirname) };
++ fd = newfd;
++ dirname = TAKE_PTR(newdirname);
++
++ goto next_fd;
+
+- if (FLAGS_SET(flags, REMOVE_SYNCFS) && syncfs(dirfd(d)) < 0 && ret >= 0)
+- ret = -errno;
++ } else if (errno != -ENOENT && ret == 0)
++ ret = -errno;
++
++ } else if (r < 0 && r != -ENOENT && ret == 0)
++ ret = r;
++ }
++
++ if (FLAGS_SET(flags, REMOVE_SYNCFS) && syncfs(fd) < 0 && ret >= 0)
++ ret = -errno;
++
++ if (n_todo == 0)
++ break;
++ }
+
+ return ret;
+ }
+@@ -250,5 +315,5 @@
+ if (FLAGS_SET(flags, REMOVE_ONLY_DIRECTORIES|REMOVE_SUBVOLUME))
+ return -EINVAL;
+
+- return rm_rf_children_inner(fd, name, -1, flags, NULL);
++ return rm_rf_inner_child(fd, name, -1, flags, NULL, true);
+ }
diff --git a/meta/recipes-core/systemd/systemd/CVE-2022-3821.patch b/meta/recipes-core/systemd/systemd/CVE-2022-3821.patch
new file mode 100644
index 0000000000..f9c6704cfc
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/CVE-2022-3821.patch
@@ -0,0 +1,47 @@
+From 9102c625a673a3246d7e73d8737f3494446bad4e Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Thu, 7 Jul 2022 18:27:02 +0900
+Subject: [PATCH] time-util: fix buffer-over-run
+
+Fixes #23928.
+
+CVE: CVE-2022-3821
+Upstream-Status: Backport [https://github.com/systemd/systemd/commit/9102c625a673a3246d7e73d8737f3494446bad4e.patch]
+Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
+Comment: Both the hunks refreshed to backport
+
+---
+ src/basic/time-util.c | 2 +-
+ src/test/test-time-util.c | 5 +++++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/src/basic/time-util.c b/src/basic/time-util.c
+index abbc4ad5cd70..26d59de12348 100644
+--- a/src/basic/time-util.c
++++ b/src/basic/time-util.c
+@@ -514,7 +514,7 @@ char *format_timespan(char *buf, size_t
+ t = b;
+ }
+
+- n = MIN((size_t) k, l);
++ n = MIN((size_t) k, l-1);
+
+ l -= n;
+ p += n;
+diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
+index e8e4e2a67bb1..58c5fa9be40c 100644
+--- a/src/test/test-time-util.c
++++ b/src/test/test-time-util.c
+@@ -501,6 +501,12 @@ int main(int argc, char *argv[]) {
+ test_format_timespan(1);
+ test_format_timespan(USEC_PER_MSEC);
+ test_format_timespan(USEC_PER_SEC);
++
++ /* See issue #23928. */
++ _cleanup_free_ char *buf;
++ assert_se(buf = new(char, 5));
++ assert_se(buf == format_timespan(buf, 5, 100005, 1000));
++
+ test_timezone_is_valid();
+ test_get_timezones();
+ test_usec_add();
diff --git a/meta/recipes-core/systemd/systemd/CVE-2023-26604-1.patch b/meta/recipes-core/systemd/systemd/CVE-2023-26604-1.patch
new file mode 100644
index 0000000000..39f9480cf8
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/CVE-2023-26604-1.patch
@@ -0,0 +1,115 @@
+From 612ebf6c913dd0e4197c44909cb3157f5c51a2f0 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Mon, 31 Aug 2020 19:37:13 +0200
+Subject: [PATCH] pager: set $LESSSECURE whenver we invoke a pager
+
+Some extra safety when invoked via "sudo". With this we address a
+genuine design flaw of sudo, and we shouldn't need to deal with this.
+But it's still a good idea to disable this surface given how exotic it
+is.
+
+Prompted by #5666
+
+CVE: CVE-2023-26604
+Upstream-Status: Backport [https://github.com/systemd/systemd/pull/17270/commits/612ebf6c913dd0e4197c44909cb3157f5c51a2f0]
+Comments: Hunk not refreshed
+Signed-off-by: rajmohan r <rajmohan.r@kpit.com>
+---
+ man/less-variables.xml | 9 +++++++++
+ man/systemctl.xml | 1 +
+ man/systemd.xml | 1 +
+ src/shared/pager.c | 23 +++++++++++++++++++++--
+ 4 files changed, 32 insertions(+), 2 deletions(-)
+
+diff --git a/man/less-variables.xml b/man/less-variables.xml
+index 08e513c99f8e..c52511ca8e18 100644
+--- a/man/less-variables.xml
++++ b/man/less-variables.xml
+@@ -64,6 +64,15 @@
+ the invoking terminal is determined to be UTF-8 compatible).</para></listitem>
+ </varlistentry>
+
++ <varlistentry id='lesssecure'>
++ <term><varname>$SYSTEMD_LESSSECURE</varname></term>
++
++ <listitem><para>Takes a boolean argument. Overrides the <varname>$LESSSECURE</varname> environment
++ variable when invoking the pager, which controls the "secure" mode of less (which disables commands
++ such as <literal>|</literal> which allow to easily shell out to external command lines). By default
++ less secure mode is enabled, with this setting it may be disabled.</para></listitem>
++ </varlistentry>
++
+ <varlistentry id='colors'>
+ <term><varname>$SYSTEMD_COLORS</varname></term>
+
+diff --git a/man/systemctl.xml b/man/systemctl.xml
+index 1c5502883700..a3f0c3041a57 100644
+--- a/man/systemctl.xml
++++ b/man/systemctl.xml
+@@ -2240,6 +2240,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
+ <xi:include href="less-variables.xml" xpointer="pager"/>
+ <xi:include href="less-variables.xml" xpointer="less"/>
+ <xi:include href="less-variables.xml" xpointer="lesscharset"/>
++ <xi:include href="less-variables.xml" xpointer="lesssecure"/>
+ <xi:include href="less-variables.xml" xpointer="colors"/>
+ <xi:include href="less-variables.xml" xpointer="urlify"/>
+ </refsect1>
+diff --git a/man/systemd.xml b/man/systemd.xml
+index a9040545c2ab..c92cfef77689 100644
+--- a/man/systemd.xml
++++ b/man/systemd.xml
+@@ -692,6 +692,7 @@
+ <xi:include href="less-variables.xml" xpointer="pager"/>
+ <xi:include href="less-variables.xml" xpointer="less"/>
+ <xi:include href="less-variables.xml" xpointer="lesscharset"/>
++ <xi:include href="less-variables.xml" xpointer="lesssecure"/>
+ <xi:include href="less-variables.xml" xpointer="colors"/>
+ <xi:include href="less-variables.xml" xpointer="urlify"/>
+
+diff --git a/src/shared/pager.c b/src/shared/pager.c
+index e03be6d23b2d..9c21881241f5 100644
+--- a/src/shared/pager.c
++++ b/src/shared/pager.c
+@@ -9,6 +9,7 @@
+ #include <unistd.h>
+
+ #include "copy.h"
++#include "env-util.h"
+ #include "fd-util.h"
+ #include "fileio.h"
+ #include "io-util.h"
+@@ -152,8 +153,7 @@ int pager_open(PagerFlags flags) {
+ _exit(EXIT_FAILURE);
+ }
+
+- /* Initialize a good charset for less. This is
+- * particularly important if we output UTF-8
++ /* Initialize a good charset for less. This is particularly important if we output UTF-8
+ * characters. */
+ less_charset = getenv("SYSTEMD_LESSCHARSET");
+ if (!less_charset && is_locale_utf8())
+@@ -164,6 +164,25 @@ int pager_open(PagerFlags flags) {
+ _exit(EXIT_FAILURE);
+ }
+
++ /* People might invoke us from sudo, don't needlessly allow less to be a way to shell out
++ * privileged stuff. */
++ r = getenv_bool("SYSTEMD_LESSSECURE");
++ if (r == 0) { /* Remove env var if off */
++ if (unsetenv("LESSSECURE") < 0) {
++ log_error_errno(errno, "Failed to uset environment variable LESSSECURE: %m");
++ _exit(EXIT_FAILURE);
++ }
++ } else {
++ /* Set env var otherwise */
++ if (r < 0)
++ log_warning_errno(r, "Unable to parse $SYSTEMD_LESSSECURE, ignoring: %m");
++
++ if (setenv("LESSSECURE", "1", 1) < 0) {
++ log_error_errno(errno, "Failed to set environment variable LESSSECURE: %m");
++ _exit(EXIT_FAILURE);
++ }
++ }
++
+ if (pager_args) {
+ r = loop_write(exe_name_pipe[1], pager_args[0], strlen(pager_args[0]) + 1, false);
+ if (r < 0) {
diff --git a/meta/recipes-core/systemd/systemd/CVE-2023-26604-2.patch b/meta/recipes-core/systemd/systemd/CVE-2023-26604-2.patch
new file mode 100644
index 0000000000..95da7cfad6
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/CVE-2023-26604-2.patch
@@ -0,0 +1,264 @@
+From 1b5b507cd2d1d7a2b053151abb548475ad9c5c3b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Mon, 12 Oct 2020 18:57:32 +0200
+Subject: [PATCH] test-login: always test sd_pid_get_owner_uid(), modernize
+
+A long time some function only worked when in a session, and the test
+didn't execute them when sd_pid_get_session() failed. Let's always call
+them to increase coverage.
+
+While at it, let's test for ==0 not >=0 where we don't expect the function
+to return anything except 0 or error.
+
+CVE: CVE-2023-26604
+Upstream-Status: Backport [https://github.com/systemd/systemd/pull/17270/commits/1b5b507cd2d1d7a2b053151abb548475ad9c5c3b.patch]
+Comments: Hunk not refreshed
+Signed-off-by: rajmohan r <rajmohan.r@kpit.com>
+---
+ src/libsystemd/sd-login/test-login.c | 131 ++++++++++++++-------------
+ 1 file changed, 70 insertions(+), 61 deletions(-)
+
+diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c
+index c0c77e04714b..0494fc77ba18 100644
+--- a/src/libsystemd/sd-login/test-login.c
++++ b/src/libsystemd/sd-login/test-login.c
+@@ -5,21 +5,22 @@
+ #include "sd-login.h"
+
+ #include "alloc-util.h"
++#include "errno-list.h"
+ #include "fd-util.h"
+ #include "format-util.h"
+ #include "log.h"
+ #include "string-util.h"
+ #include "strv.h"
+ #include "time-util.h"
+-#include "util.h"
++#include "user-util.h"
+
+ static char* format_uids(char **buf, uid_t* uids, int count) {
+- int pos = 0, k, inc;
++ int pos = 0, inc;
+ size_t size = (DECIMAL_STR_MAX(uid_t) + 1) * count + 1;
+
+ assert_se(*buf = malloc(size));
+
+- for (k = 0; k < count; k++) {
++ for (int k = 0; k < count; k++) {
+ sprintf(*buf + pos, "%s"UID_FMT"%n", k > 0 ? " " : "", uids[k], &inc);
+ pos += inc;
+ }
+@@ -30,6 +31,10 @@ static char* format_uids(char **buf, uid_t* uids, int count) {
+ return *buf;
+ }
+
++static const char *e(int r) {
++ return r == 0 ? "OK" : errno_to_name(r);
++}
++
+ static void test_login(void) {
+ _cleanup_close_pair_ int pair[2] = { -1, -1 };
+ _cleanup_free_ char *pp = NULL, *qq = NULL,
+@@ -39,65 +44,71 @@ static void test_login(void) {
+ *seat = NULL, *session = NULL,
+ *unit = NULL, *user_unit = NULL, *slice = NULL;
+ int r;
+- uid_t u, u2;
+- char *t, **seats, **sessions;
++ uid_t u, u2 = UID_INVALID;
++ char *t, **seats = NULL, **sessions = NULL;
+
+ r = sd_pid_get_unit(0, &unit);
+- assert_se(r >= 0 || r == -ENODATA);
+- log_info("sd_pid_get_unit(0, …) → \"%s\"", strna(unit));
++ log_info("sd_pid_get_unit(0, …) → %s / \"%s\"", e(r), strnull(unit));
++ assert_se(IN_SET(r, 0, -ENODATA));
+
+ r = sd_pid_get_user_unit(0, &user_unit);
+- assert_se(r >= 0 || r == -ENODATA);
+- log_info("sd_pid_get_user_unit(0, …) → \"%s\"", strna(user_unit));
++ log_info("sd_pid_get_user_unit(0, …) → %s / \"%s\"", e(r), strnull(user_unit));
++ assert_se(IN_SET(r, 0, -ENODATA));
+
+ r = sd_pid_get_slice(0, &slice);
+- assert_se(r >= 0 || r == -ENODATA);
+- log_info("sd_pid_get_slice(0, …) → \"%s\"", strna(slice));
++ log_info("sd_pid_get_slice(0, …) → %s / \"%s\"", e(r), strnull(slice));
++ assert_se(IN_SET(r, 0, -ENODATA));
++
++ r = sd_pid_get_owner_uid(0, &u2);
++ log_info("sd_pid_get_owner_uid(0, …) → %s / "UID_FMT, e(r), u2);
++ assert_se(IN_SET(r, 0, -ENODATA));
+
+ r = sd_pid_get_session(0, &session);
+- if (r < 0) {
+- log_warning_errno(r, "sd_pid_get_session(0, …): %m");
+- if (r == -ENODATA)
+- log_info("Seems we are not running in a session, skipping some tests.");
+- } else {
+- log_info("sd_pid_get_session(0, …) → \"%s\"", session);
+-
+- assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
+- log_info("sd_pid_get_owner_uid(0, …) → "UID_FMT, u2);
+-
+- assert_se(sd_pid_get_cgroup(0, &cgroup) == 0);
+- log_info("sd_pid_get_cgroup(0, …) → \"%s\"", cgroup);
+-
+- r = sd_uid_get_display(u2, &display_session);
+- assert_se(r >= 0 || r == -ENODATA);
+- log_info("sd_uid_get_display("UID_FMT", …) → \"%s\"",
+- u2, strnull(display_session));
+-
+- assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
+- sd_peer_get_session(pair[0], &pp);
+- sd_peer_get_session(pair[1], &qq);
+- assert_se(streq_ptr(pp, qq));
+-
+- r = sd_uid_get_sessions(u2, false, &sessions);
++ log_info("sd_pid_get_session(0, …) → %s / \"%s\"", e(r), strnull(session));
++
++ r = sd_pid_get_cgroup(0, &cgroup);
++ log_info("sd_pid_get_cgroup(0, …) → %s / \"%s\"", e(r), strnull(cgroup));
++ assert_se(r == 0);
++
++ r = sd_uid_get_display(u2, &display_session);
++ log_info("sd_uid_get_display("UID_FMT", …) → %s / \"%s\"", u2, e(r), strnull(display_session));
++ if (u2 == UID_INVALID)
++ assert_se(r == -EINVAL);
++ else
++ assert_se(IN_SET(r, 0, -ENODATA));
++
++ assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
++ sd_peer_get_session(pair[0], &pp);
++ sd_peer_get_session(pair[1], &qq);
++ assert_se(streq_ptr(pp, qq));
++
++ r = sd_uid_get_sessions(u2, false, &sessions);
++ assert_se(t = strv_join(sessions, " "));
++ log_info("sd_uid_get_sessions("UID_FMT", …) → %s \"%s\"", u2, e(r), t);
++ if (u2 == UID_INVALID)
++ assert_se(r == -EINVAL);
++ else {
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(sessions));
+- assert_se(t = strv_join(sessions, " "));
+- strv_free(sessions);
+- log_info("sd_uid_get_sessions("UID_FMT", …) → [%i] \"%s\"", u2, r, t);
+- free(t);
++ }
++ sessions = strv_free(sessions);
++ free(t);
+
+- assert_se(r == sd_uid_get_sessions(u2, false, NULL));
++ assert_se(r == sd_uid_get_sessions(u2, false, NULL));
+
+- r = sd_uid_get_seats(u2, false, &seats);
++ r = sd_uid_get_seats(u2, false, &seats);
++ assert_se(t = strv_join(seats, " "));
++ log_info("sd_uid_get_seats("UID_FMT", …) → %s \"%s\"", u2, e(r), t);
++ if (u2 == UID_INVALID)
++ assert_se(r == -EINVAL);
++ else {
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(seats));
+- assert_se(t = strv_join(seats, " "));
+- strv_free(seats);
+- log_info("sd_uid_get_seats("UID_FMT", …) → [%i] \"%s\"", u2, r, t);
+- free(t);
+-
+- assert_se(r == sd_uid_get_seats(u2, false, NULL));
+ }
++ seats = strv_free(seats);
++ free(t);
++
++ assert_se(r == sd_uid_get_seats(u2, false, NULL));
+
+ if (session) {
+ r = sd_session_is_active(session);
+@@ -109,7 +120,7 @@ static void test_login(void) {
+ log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
+
+ r = sd_session_get_state(session, &state);
+- assert_se(r >= 0);
++ assert_se(r == 0);
+ log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
+
+ assert_se(sd_session_get_uid(session, &u) >= 0);
+@@ -123,16 +134,16 @@ static void test_login(void) {
+ log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
+
+ r = sd_session_get_display(session, &display);
+- assert_se(r >= 0 || r == -ENODATA);
++ assert_se(IN_SET(r, 0, -ENODATA));
+ log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
+
+ r = sd_session_get_remote_user(session, &remote_user);
+- assert_se(r >= 0 || r == -ENODATA);
++ assert_se(IN_SET(r, 0, -ENODATA));
+ log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
+ session, strna(remote_user));
+
+ r = sd_session_get_remote_host(session, &remote_host);
+- assert_se(r >= 0 || r == -ENODATA);
++ assert_se(IN_SET(r, 0, -ENODATA));
+ log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
+ session, strna(remote_host));
+
+@@ -161,7 +172,7 @@ static void test_login(void) {
+ assert_se(r == -ENODATA);
+ }
+
+- assert_se(sd_uid_get_state(u, &state2) >= 0);
++ assert_se(sd_uid_get_state(u, &state2) == 0);
+ log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2);
+ }
+
+@@ -173,11 +184,11 @@ static void test_login(void) {
+ assert_se(sd_uid_is_on_seat(u, 0, seat) > 0);
+
+ r = sd_seat_get_active(seat, &session2, &u2);
+- assert_se(r >= 0);
++ assert_se(r == 0);
+ log_info("sd_seat_get_active(\"%s\", …) → \"%s\", "UID_FMT, seat, session2, u2);
+
+ r = sd_uid_is_on_seat(u, 1, seat);
+- assert_se(r >= 0);
++ assert_se(IN_SET(r, 0, 1));
+ assert_se(!!r == streq(session, session2));
+
+ r = sd_seat_get_sessions(seat, &sessions, &uids, &n);
+@@ -185,8 +196,8 @@ static void test_login(void) {
+ assert_se(r == (int) strv_length(sessions));
+ assert_se(t = strv_join(sessions, " "));
+ strv_free(sessions);
+- log_info("sd_seat_get_sessions(\"%s\", …) → %i, \"%s\", [%i] {%s}",
+- seat, r, t, n, format_uids(&buf, uids, n));
++ log_info("sd_seat_get_sessions(\"%s\", …) → %s, \"%s\", [%u] {%s}",
++ seat, e(r), t, n, format_uids(&buf, uids, n));
+ free(t);
+
+ assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r);
+@@ -204,7 +215,7 @@ static void test_login(void) {
+
+ r = sd_seat_get_active(NULL, &t, NULL);
+ assert_se(IN_SET(r, 0, -ENODATA));
+- log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s", strnull(t));
++ log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s / \"%s\"", e(r), strnull(t));
+ free(t);
+
+ r = sd_get_sessions(&sessions);
+@@ -244,13 +255,11 @@ static void test_login(void) {
+
+ static void test_monitor(void) {
+ sd_login_monitor *m = NULL;
+- unsigned n;
+ int r;
+
+- r = sd_login_monitor_new("session", &m);
+- assert_se(r >= 0);
++ assert_se(sd_login_monitor_new("session", &m) == 0);
+
+- for (n = 0; n < 5; n++) {
++ for (unsigned n = 0; n < 5; n++) {
+ struct pollfd pollfd = {};
+ usec_t timeout, nw;
diff --git a/meta/recipes-core/systemd/systemd/CVE-2023-26604-3.patch b/meta/recipes-core/systemd/systemd/CVE-2023-26604-3.patch
new file mode 100644
index 0000000000..f02f62b772
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/CVE-2023-26604-3.patch
@@ -0,0 +1,182 @@
+From 0a42426d797406b4b01a0d9c13bb759c2629d108 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Wed, 7 Oct 2020 11:15:05 +0200
+Subject: [PATCH] pager: make pager secure when under euid is changed or
+ explicitly requested
+
+The variable is renamed to SYSTEMD_PAGERSECURE (because it's not just about
+less now), and we automatically enable secure mode in certain cases, but not
+otherwise.
+
+This approach is more nuanced, but should provide a better experience for
+users:
+
+- Previusly we would set LESSSECURE=1 and trust the pager to make use of
+ it. But this has an effect only on less. We need to not start pagers which
+ are insecure when in secure mode. In particular more is like that and is a
+ very popular pager.
+
+- We don't enable secure mode always, which means that those other pagers can
+ reasonably used.
+
+- We do the right thing by default, but the user has ultimate control by
+ setting SYSTEMD_PAGERSECURE.
+
+Fixes #5666.
+
+v2:
+- also check $PKEXEC_UID
+
+v3:
+- use 'sd_pid_get_owner_uid() != geteuid()' as the condition
+
+CVE: CVE-2023-26604
+Upstream-Status: Backport [https://github.com/systemd/systemd/pull/17270/commits/0a42426d797406b4b01a0d9c13bb759c2629d108]
+Comments: Hunk refreshed
+Signed-off-by: rajmohan r <rajmohan.r@kpit.com>
+---
+ man/less-variables.xml | 30 +++++++++++++++----
+ src/shared/pager.c | 63 ++++++++++++++++++++++++++-------------
+ 2 files changed, 66 insertions(+), 27 deletions(-)
+
+diff --git a/man/less-variables.xml b/man/less-variables.xml
+index c52511c..049e9f7 100644
+--- a/man/less-variables.xml
++++ b/man/less-variables.xml
+@@ -65,12 +65,30 @@
+ </varlistentry>
+
+ <varlistentry id='lesssecure'>
+- <term><varname>$SYSTEMD_LESSSECURE</varname></term>
+-
+- <listitem><para>Takes a boolean argument. Overrides the <varname>$LESSSECURE</varname> environment
+- variable when invoking the pager, which controls the "secure" mode of less (which disables commands
+- such as <literal>|</literal> which allow to easily shell out to external command lines). By default
+- less secure mode is enabled, with this setting it may be disabled.</para></listitem>
++ <term><varname>$SYSTEMD_PAGERSECURE</varname></term>
++
++ <listitem><para>Takes a boolean argument. When true, the "secure" mode of the pager is enabled; if
++ false, disabled. If <varname>$SYSTEMD_PAGERSECURE</varname> is not set at all, secure mode is enabled
++ if the effective UID is not the same as the owner of the login session, see <citerefentry
++ project='man-pages'><refentrytitle>geteuid</refentrytitle><manvolnum>2</manvolnum></citerefentry> and
++ <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
++ In secure mode, <option>LESSSECURE=1</option> will be set when invoking the pager, and the pager shall
++ disable commands that open or create new files or start new subprocesses. When
++ <varname>$SYSTEMD_PAGERSECURE</varname> is not set at all, pagers which are not known to implement
++ secure mode will not be used. (Currently only
++ <citerefentry><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry> implements
++ secure mode.)</para>
++
++ <para>Note: when commands are invoked with elevated privileges, for example under <citerefentry
++ project='man-pages'><refentrytitle>sudo</refentrytitle><manvolnum>8</manvolnum></citerefentry> or
++ <citerefentry
++ project='die-net'><refentrytitle>pkexec</refentrytitle><manvolnum>1</manvolnum></citerefentry>, care
++ must be taken to ensure that unintended interactive features are not enabled. "Secure" mode for the
++ pager may be enabled automatically as describe above. Setting <varname>SYSTEMD_PAGERSECURE=0</varname>
++ or not removing it from the inherited environment allows the user to invoke arbitrary commands. Note
++ that if the <varname>$SYSTEMD_PAGER</varname> or <varname>$PAGER</varname> variables are to be
++ honoured, <varname>$SYSTEMD_PAGERSECURE</varname> must be set too. It might be reasonable to completly
++ disable the pager using <option>--no-pager</option> instead.</para></listitem>
+ </varlistentry>
+
+ <varlistentry id='colors'>
+diff --git a/src/shared/pager.c b/src/shared/pager.c
+index a3b6576..a72d9ea 100644
+--- a/src/shared/pager.c
++++ b/src/shared/pager.c
+@@ -8,6 +8,8 @@
+ #include <sys/prctl.h>
+ #include <unistd.h>
+
++#include "sd-login.h"
++
+ #include "copy.h"
+ #include "env-util.h"
+ #include "fd-util.h"
+@@ -164,25 +166,42 @@ int pager_open(PagerFlags flags) {
+ }
+
+ /* People might invoke us from sudo, don't needlessly allow less to be a way to shell out
+- * privileged stuff. */
+- r = getenv_bool("SYSTEMD_LESSSECURE");
+- if (r == 0) { /* Remove env var if off */
+- if (unsetenv("LESSSECURE") < 0) {
+- log_error_errno(errno, "Failed to uset environment variable LESSSECURE: %m");
+- _exit(EXIT_FAILURE);
+- }
+- } else {
+- /* Set env var otherwise */
++ * privileged stuff. If the user set $SYSTEMD_PAGERSECURE, trust their configuration of the
++ * pager. If they didn't, use secure mode when under euid is changed. If $SYSTEMD_PAGERSECURE
++ * wasn't explicitly set, and we autodetect the need for secure mode, only use the pager we
++ * know to be good. */
++ int use_secure_mode = getenv_bool("SYSTEMD_PAGERSECURE");
++ bool trust_pager = use_secure_mode >= 0;
++ if (use_secure_mode == -ENXIO) {
++ uid_t uid;
++
++ r = sd_pid_get_owner_uid(0, &uid);
+ if (r < 0)
+- log_warning_errno(r, "Unable to parse $SYSTEMD_LESSSECURE, ignoring: %m");
++ log_debug_errno(r, "sd_pid_get_owner_uid() failed, enabling pager secure mode: %m");
+
+- if (setenv("LESSSECURE", "1", 1) < 0) {
+- log_error_errno(errno, "Failed to set environment variable LESSSECURE: %m");
+- _exit(EXIT_FAILURE);
+- }
++ use_secure_mode = r < 0 || uid != geteuid();
++
++ } else if (use_secure_mode < 0) {
++ log_warning_errno(use_secure_mode, "Unable to parse $SYSTEMD_PAGERSECURE, assuming true: %m");
++ use_secure_mode = true;
+ }
+
+- if (pager_args) {
++ /* We generally always set variables used by less, even if we end up using a different pager.
++ * They shouldn't hurt in any case, and ideally other pagers would look at them too. */
++ if (use_secure_mode)
++ r = setenv("LESSSECURE", "1", 1);
++ else
++ r = unsetenv("LESSSECURE");
++ if (r < 0) {
++ log_error_errno(errno, "Failed to adjust environment variable LESSSECURE: %m");
++ _exit(EXIT_FAILURE);
++ }
++
++ if (trust_pager && pager_args) { /* The pager config might be set globally, and we cannot
++ * know if the user adjusted it to be appropriate for the
++ * secure mode. Thus, start the pager specified through
++ * envvars only when $SYSTEMD_PAGERSECURE was explicitly set
++ * as well. */
+ r = loop_write(exe_name_pipe[1], pager_args[0], strlen(pager_args[0]) + 1, false);
+ if (r < 0) {
+ log_error_errno(r, "Failed to write pager name to socket: %m");
+@@ -194,13 +213,14 @@ int pager_open(PagerFlags flags) {
+ "Failed to execute '%s', using fallback pagers: %m", pager_args[0]);
+ }
+
+- /* Debian's alternatives command for pagers is
+- * called 'pager'. Note that we do not call
+- * sensible-pagers here, since that is just a
+- * shell script that implements a logic that
+- * is similar to this one anyway, but is
+- * Debian-specific. */
++ /* Debian's alternatives command for pagers is called 'pager'. Note that we do not call
++ * sensible-pagers here, since that is just a shell script that implements a logic that is
++ * similar to this one anyway, but is Debian-specific. */
+ FOREACH_STRING(exe, "pager", "less", "more") {
++ /* Only less implements secure mode right now. */
++ if (use_secure_mode && !streq(exe, "less"))
++ continue;
++
+ r = loop_write(exe_name_pipe[1], exe, strlen(exe) + 1, false);
+ if (r < 0) {
+ log_error_errno(r, "Failed to write pager name to socket: %m");
+@@ -211,6 +231,7 @@ int pager_open(PagerFlags flags) {
+ "Failed to execute '%s', using next fallback pager: %m", exe);
+ }
+
++ /* Our builtin is also very secure. */
+ r = loop_write(exe_name_pipe[1], "(built-in)", strlen("(built-in)") + 1, false);
+ if (r < 0) {
+ log_error_errno(r, "Failed to write pager name to socket: %m");
diff --git a/meta/recipes-core/systemd/systemd/CVE-2023-26604-4.patch b/meta/recipes-core/systemd/systemd/CVE-2023-26604-4.patch
new file mode 100644
index 0000000000..bc6b0a91c2
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/CVE-2023-26604-4.patch
@@ -0,0 +1,32 @@
+From b8f736b30e20a2b44e7c34bb4e43b0d97ae77e3c Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 15 Oct 2020 10:54:48 +0200
+Subject: [PATCH] pager: lets check SYSTEMD_PAGERSECURE with secure_getenv()
+
+I can't think of any real vulnerability about this, but it still feels
+better to check a variable with "secure" in its name with
+secure_getenv() rather than plain getenv().
+
+Paranoia FTW!
+
+CVE: CVE-2023-26604
+Upstream-Status: Backport [https://github.com/systemd/systemd/pull/17359/commits/b8f736b30e20a2b44e7c34bb4e43b0d97ae77e3c]
+Comments: Hunk refreshed
+Signed-off-by: rajmohan r <rajmohan.r@kpit.com>
+---
+ src/shared/pager.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/shared/pager.c b/src/shared/pager.c
+index a72d9ea..250519c 100644
+--- a/src/shared/pager.c
++++ b/src/shared/pager.c
+@@ -170,7 +170,7 @@ int pager_open(PagerFlags flags) {
+ * pager. If they didn't, use secure mode when under euid is changed. If $SYSTEMD_PAGERSECURE
+ * wasn't explicitly set, and we autodetect the need for secure mode, only use the pager we
+ * know to be good. */
+- int use_secure_mode = getenv_bool("SYSTEMD_PAGERSECURE");
++ int use_secure_mode = getenv_bool_secure("SYSTEMD_PAGERSECURE");
+ bool trust_pager = use_secure_mode >= 0;
+ if (use_secure_mode == -ENXIO) {
+ uid_t uid;
diff --git a/meta/recipes-core/systemd/systemd/basic-pass-allocation-info-for-ordered-set-new-and-introd.patch b/meta/recipes-core/systemd/systemd/basic-pass-allocation-info-for-ordered-set-new-and-introd.patch
new file mode 100644
index 0000000000..86d9b0499a
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/basic-pass-allocation-info-for-ordered-set-new-and-introd.patch
@@ -0,0 +1,78 @@
+From 1f25c71d9d0b5fe6cf383c347dcebc2443a99fe1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 1 Sep 2020 12:42:35 +0200
+Subject: [PATCH] basic: pass allocation info for ordered_set_new() and
+ introduce ordered_set_ensure_put()
+
+Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/1f25c71d9d0b5fe6cf383c347dcebc2443a99fe1]
+Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
+
+---
+ src/basic/ordered-set.c | 21 +++++++++++++++++++++
+ src/basic/ordered-set.h | 18 +++++++-----------
+ 2 files changed, 28 insertions(+), 11 deletions(-)
+
+diff --git a/src/basic/ordered-set.c b/src/basic/ordered-set.c
+index 7fdb47e064..fb82c17b5a 100644
+--- a/src/basic/ordered-set.c
++++ b/src/basic/ordered-set.c
+@@ -4,6 +4,27 @@
+ #include "ordered-set.h"
+ #include "strv.h"
+
++int _ordered_set_ensure_allocated(OrderedSet **s, const struct hash_ops *ops HASHMAP_DEBUG_PARAMS) {
++ if (*s)
++ return 0;
++
++ *s = _ordered_set_new(ops HASHMAP_DEBUG_PASS_ARGS);
++ if (!*s)
++ return -ENOMEM;
++
++ return 0;
++}
++
++int _ordered_set_ensure_put(OrderedSet **s, const struct hash_ops *ops, void *p HASHMAP_DEBUG_PARAMS) {
++ int r;
++
++ r = _ordered_set_ensure_allocated(s, ops HASHMAP_DEBUG_PASS_ARGS);
++ if (r < 0)
++ return r;
++
++ return ordered_set_put(*s, p);
++}
++
+ int ordered_set_consume(OrderedSet *s, void *p) {
+ int r;
+
+diff --git a/src/basic/ordered-set.h b/src/basic/ordered-set.h
+index a42a57eb49..2c241a808b 100644
+--- a/src/basic/ordered-set.h
++++ b/src/basic/ordered-set.h
+@@ -7,20 +7,16 @@
+
+ typedef struct OrderedSet OrderedSet;
+
+-static inline OrderedSet* ordered_set_new(const struct hash_ops *ops) {
+- return (OrderedSet*) ordered_hashmap_new(ops);
++static inline OrderedSet* _ordered_set_new(const struct hash_ops *ops HASHMAP_DEBUG_PARAMS) {
++ return (OrderedSet*) internal_ordered_hashmap_new(ops HASHMAP_DEBUG_PASS_ARGS);
+ }
++#define ordered_set_new(ops) _ordered_set_new(ops HASHMAP_DEBUG_SRC_ARGS)
+
+-static inline int ordered_set_ensure_allocated(OrderedSet **s, const struct hash_ops *ops) {
+- if (*s)
+- return 0;
++int _ordered_set_ensure_allocated(OrderedSet **s, const struct hash_ops *ops HASHMAP_DEBUG_PARAMS);
++#define ordered_set_ensure_allocated(s, ops) _ordered_set_ensure_allocated(s, ops HASHMAP_DEBUG_SRC_ARGS)
+
+- *s = ordered_set_new(ops);
+- if (!*s)
+- return -ENOMEM;
+-
+- return 0;
+-}
++int _ordered_set_ensure_put(OrderedSet **s, const struct hash_ops *ops, void *p HASHMAP_DEBUG_PARAMS);
++#define ordered_set_ensure_put(s, hash_ops, key) _ordered_set_ensure_put(s, hash_ops, key HASHMAP_DEBUG_SRC_ARGS)
+
+ static inline OrderedSet* ordered_set_free(OrderedSet *s) {
+ return (OrderedSet*) ordered_hashmap_free((OrderedHashmap*) s);
diff --git a/meta/recipes-core/systemd/systemd/introduce-ordered_set_clear-free-with-destructor.patch b/meta/recipes-core/systemd/systemd/introduce-ordered_set_clear-free-with-destructor.patch
new file mode 100644
index 0000000000..42b6e05b55
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/introduce-ordered_set_clear-free-with-destructor.patch
@@ -0,0 +1,35 @@
+From d38a6476aad3f2cc80a2a4bc11f3898cc06a70f5 Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Mon, 26 Apr 2021 23:52:40 +0900
+Subject: [PATCH] ordered-set: introduce
+ ordered_set_clear/free_with_destructor()
+
+Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/d38a6476aad3f2cc80a2a4bc11f3898cc06a70f5]
+Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
+
+---
+ src/basic/ordered-set.h | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/src/basic/ordered-set.h b/src/basic/ordered-set.h
+index a377f20b1f..64df41766f 100644
+--- a/src/basic/ordered-set.h
++++ b/src/basic/ordered-set.h
+@@ -63,6 +63,17 @@ void ordered_set_print(FILE *f, const char *field, OrderedSet *s);
+ #define ORDERED_SET_FOREACH(e, s, i) \
+ for ((i) = ITERATOR_FIRST; ordered_set_iterate((s), &(i), (void**)&(e)); )
+
++#define ordered_set_clear_with_destructor(s, f) \
++ ({ \
++ OrderedSet *_s = (s); \
++ void *_item; \
++ while ((_item = ordered_set_steal_first(_s))) \
++ f(_item); \
++ _s; \
++ })
++#define ordered_set_free_with_destructor(s, f) \
++ ordered_set_free(ordered_set_clear_with_destructor(s, f))
++
+ DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedSet*, ordered_set_free);
+ DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedSet*, ordered_set_free_free);
+
diff --git a/meta/recipes-core/systemd/systemd/network-add-skeleton-of-request-queue.patch b/meta/recipes-core/systemd/systemd/network-add-skeleton-of-request-queue.patch
new file mode 100644
index 0000000000..06c523834d
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/network-add-skeleton-of-request-queue.patch
@@ -0,0 +1,285 @@
+From 19d9a5adf0c1a6b5a243eea0390f6f6526d569de Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Fri, 7 May 2021 15:39:16 +0900
+Subject: [PATCH] network: add skeleton of request queue
+
+This will be used in later commits.
+
+Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/19d9a5adf0c1a6b5a243eea0390f6f6526d569de]
+Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
+
+---
+ src/network/meson.build | 2 +
+ src/network/networkd-link.c | 20 +++++-
+ src/network/networkd-manager.c | 7 ++
+ src/network/networkd-manager.h | 2 +
+ src/network/networkd-queue.c | 121 +++++++++++++++++++++++++++++++++
+ src/network/networkd-queue.h | 42 ++++++++++++
+ 6 files changed, 192 insertions(+), 2 deletions(-)
+ create mode 100644 src/network/networkd-queue.c
+ create mode 100644 src/network/networkd-queue.h
+
+diff --git a/src/network/meson.build b/src/network/meson.build
+index 4fca3106dc..a8b9232e64 100644
+--- a/src/network/meson.build
++++ b/src/network/meson.build
+@@ -105,6 +105,8 @@ sources = files('''
+ networkd-network.h
+ networkd-nexthop.c
+ networkd-nexthop.h
++ networkd-queue.c
++ networkd-queue.h
+ networkd-route.c
+ networkd-route.h
+ networkd-routing-policy-rule.c
+diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
+index 34359b2541..2f33305a27 100644
+--- a/src/network/networkd-link.c
++++ b/src/network/networkd-link.c
+@@ -30,6 +30,7 @@
+ #include "networkd-manager.h"
+ #include "networkd-ndisc.h"
+ #include "networkd-neighbor.h"
++#include "networkd-queue.h"
+ #include "networkd-radv.h"
+ #include "networkd-routing-policy-rule.h"
+ #include "networkd-wifi.h"
+
+@@ -2232,6 +2244,8 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for
+ if (r < 0)
+ return r;
+
++ link_drop_requests(link);
++
+ r = link_drop_config(link);
+ if (r < 0)
+ return r;
+@@ -2664,6 +2678,8 @@ static int link_carrier_lost(Link *link) {
+ return r;
+ }
+
++ link_drop_requests(link);
++
+ r = link_drop_config(link);
+ if (r < 0)
+ return r;
+diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
+index 562ce5ca54..fd576169a9 100644
+--- a/src/network/networkd-manager.c
++++ b/src/network/networkd-manager.c
+@@ -34,6 +34,7 @@
+ #include "networkd-manager-bus.h"
+ #include "networkd-manager.h"
+ #include "networkd-network-bus.h"
++#include "networkd-queue.h"
+ #include "networkd-speed-meter.h"
+ #include "ordered-set.h"
+ #include "path-util.h"
+@@ -406,6 +407,10 @@ int manager_new(Manager **ret) {
+ if (r < 0)
+ return r;
+
++ r = sd_event_add_post(m->event, NULL, manager_process_requests, m);
++ if (r < 0)
++ return r;
++
+ r = manager_connect_rtnl(m);
+ if (r < 0)
+ return r;
+@@ -446,6 +451,8 @@ Manager* manager_free(Manager *m) {
+
+ free(m->state_file);
+
++ m->request_queue = ordered_set_free_with_destructor(m->request_queue, request_free);
++
+ while ((a = hashmap_first_key(m->dhcp6_prefixes)))
+ (void) dhcp6_prefix_remove(m, a);
+ m->dhcp6_prefixes = hashmap_free(m->dhcp6_prefixes);
+diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h
+index 301b97c1a1..26e8802871 100644
+--- a/src/network/networkd-manager.h
++++ b/src/network/networkd-manager.h
+@@ -91,6 +91,8 @@ struct Manager {
+ usec_t speed_meter_usec_old;
+
+ bool dhcp4_prefix_root_cannot_set_table;
++
++ OrderedSet *request_queue;
+ };
+
+ int manager_new(Manager **ret);
+diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c
+new file mode 100644
+index 0000000000..24bb2c845d
+--- /dev/null
++++ b/src/network/networkd-queue.c
+@@ -0,0 +1,121 @@
++/* SPDX-License-Identifier: LGPL-2.1-or-later */
++
++#include "networkd-address.h"
++#include "networkd-manager.h"
++#include "networkd-neighbor.h"
++#include "networkd-nexthop.h"
++#include "networkd-route.h"
++#include "networkd-routing-policy-rule.h"
++#include "networkd-queue.h"
++
++static void request_free_object(RequestType type, void *object) {
++ switch(type) {
++ default:
++ assert_not_reached("invalid request type.");
++ }
++}
++
++Request *request_free(Request *req) {
++ if (!req)
++ return NULL;
++
++ if (req->on_free)
++ req->on_free(req);
++ if (req->consume_object)
++ request_free_object(req->type, req->object);
++ if (req->link && req->link->manager)
++ ordered_set_remove(req->link->manager->request_queue, req);
++ link_unref(req->link);
++
++ return mfree(req);
++}
++
++DEFINE_TRIVIAL_CLEANUP_FUNC(Request*, request_free);
++
++void request_drop(Request *req) {
++ if (req->message_counter)
++ (*req->message_counter)--;
++
++ request_free(req);
++}
++
++int link_queue_request(
++ Link *link,
++ RequestType type,
++ void *object,
++ bool consume_object,
++ unsigned *message_counter,
++ link_netlink_message_handler_t netlink_handler,
++ Request **ret) {
++
++ _cleanup_(request_freep) Request *req = NULL;
++ int r;
++
++ assert(link);
++ assert(link->manager);
++ assert(type >= 0 && type < _REQUEST_TYPE_MAX);
++ assert(object);
++ assert(netlink_handler);
++
++ req = new(Request, 1);
++ if (!req) {
++ if (consume_object)
++ request_free_object(type, object);
++ return -ENOMEM;
++ }
++
++ *req = (Request) {
++ .link = link,
++ .type = type,
++ .object = object,
++ .consume_object = consume_object,
++ .message_counter = message_counter,
++ .netlink_handler = netlink_handler,
++ };
++
++ link_ref(link);
++
++ r = ordered_set_ensure_put(&link->manager->request_queue, NULL, req);
++ if (r < 0)
++ return r;
++
++ if (req->message_counter)
++ (*req->message_counter)++;
++
++ if (ret)
++ *ret = req;
++
++ TAKE_PTR(req);
++ return 0;
++}
++
++int manager_process_requests(sd_event_source *s, void *userdata) {
++ Manager *manager = userdata;
++ int r;
++
++ assert(manager);
++
++ for (;;) {
++ bool processed = false;
++ Request *req;
++ Iterator i;
++ ORDERED_SET_FOREACH(req, manager->request_queue, i) {
++ switch(req->type) {
++ default:
++ return -EINVAL;
++ }
++ if (r < 0)
++ link_enter_failed(req->link);
++ if (r > 0) {
++ ordered_set_remove(manager->request_queue, req);
++ request_free(req);
++ processed = true;
++ }
++ }
++
++ if (!processed)
++ break;
++ }
++
++ return 0;
++}
+diff --git a/src/network/networkd-queue.h b/src/network/networkd-queue.h
+new file mode 100644
+index 0000000000..4558ae548f
+--- /dev/null
++++ b/src/network/networkd-queue.h
+@@ -0,0 +1,42 @@
++/* SPDX-License-Identifier: LGPL-2.1-or-later */
++#pragma once
++
++#include "sd-event.h"
++
++#include "networkd-link.h"
++
++typedef struct Request Request;
++
++typedef int (*request_after_configure_handler_t)(Request*, void*);
++typedef void (*request_on_free_handler_t)(Request*);
++
++typedef enum RequestType {
++ _REQUEST_TYPE_MAX,
++ _REQUEST_TYPE_INVALID = -EINVAL,
++} RequestType;
++
++typedef struct Request {
++ Link *link;
++ RequestType type;
++ bool consume_object;
++ void *object;
++ void *userdata;
++ unsigned *message_counter;
++ link_netlink_message_handler_t netlink_handler;
++ request_after_configure_handler_t after_configure;
++ request_on_free_handler_t on_free;
++} Request;
++
++Request *request_free(Request *req);
++void request_drop(Request *req);
++
++int link_queue_request(
++ Link *link,
++ RequestType type,
++ void *object,
++ bool consume_object,
++ unsigned *message_counter,
++ link_netlink_message_handler_t netlink_handler,
++ Request **ret);
++
++int manager_process_requests(sd_event_source *s, void *userdata);
diff --git a/meta/recipes-core/systemd/systemd/network-also-drop-requests-when-link-enters-linger-state.patch b/meta/recipes-core/systemd/systemd/network-also-drop-requests-when-link-enters-linger-state.patch
new file mode 100644
index 0000000000..4c402e7e55
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/network-also-drop-requests-when-link-enters-linger-state.patch
@@ -0,0 +1,50 @@
+From 56001f023305ea99329e27141d6e6067596491a9 Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Mon, 17 May 2021 15:32:57 +0900
+Subject: [PATCH] network: also drop requests when link enters linger state
+
+Otherwise, if link is removed, several references to the link in remain
+exist in requests.
+
+Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/56001f023305ea99329e27141d6e6067596491a9]
+Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
+
+---
+ src/network/networkd-link.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
+index 67d01ac44d..b56c232eca 100644
+--- a/src/network/networkd-link.c
++++ b/src/network/networkd-link.c
+@@ -1771,6 +1771,18 @@ static void link_drop_from_master(Link *link, NetDev *netdev) {
+ link_unref(set_remove(master->slaves, link));
+ }
+
++static void link_drop_requests(Link *link) {
++ Request *req;
++ Iterator i;
++
++ assert(link);
++ assert(link->manager);
++
++ ORDERED_SET_FOREACH(req, link->manager->request_queue, i)
++ if (req->link == link)
++ request_drop(req);
++}
++
+ void link_drop(Link *link) {
+ if (!link)
+ return;
+@@ -1782,6 +1793,8 @@ void link_drop(Link *link) {
+ /* Drop all references from other links and manager. Note that async netlink calls may have
+ * references to the link, and they will be dropped when we receive replies. */
+
++ link_drop_requests(link);
++
+ link_free_carrier_maps(link);
+
+ if (link->network) {
+--
+2.17.1
+
diff --git a/meta/recipes-core/systemd/systemd/network-fix-Link-reference-counter-issue.patch b/meta/recipes-core/systemd/systemd/network-fix-Link-reference-counter-issue.patch
new file mode 100644
index 0000000000..a186bb4095
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/network-fix-Link-reference-counter-issue.patch
@@ -0,0 +1,278 @@
+From cc2d7efc5ca09a7de4bec55e80476986839a655c Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Fri, 14 May 2021 15:58:15 +0900
+Subject: [PATCH] network: fix Link reference counter issue
+
+Previously, when link_new() fails, `link_unref()` was called, so,
+`Manager::links` may become dirty.
+This introduces `link_drop_or_unref()` and it will be called on
+failure.
+
+Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/cc2d7efc5ca09a7de4bec55e80476986839a655c]
+Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
+
+---
+ src/network/networkd-link.c | 240 ++++++++++++++++++------------------
+ 1 file changed, 122 insertions(+), 118 deletions(-)
+
+diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
+index b56c232eca..d493afda4c 100644
+--- a/src/network/networkd-link.c
++++ b/src/network/networkd-link.c
+@@ -540,109 +540,6 @@ static int link_update_flags(Link *link,
+ return 0;
+ }
+
+-static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
+- _cleanup_(link_unrefp) Link *link = NULL;
+- uint16_t type;
+- const char *ifname, *kind = NULL;
+- int r, ifindex;
+- unsigned short iftype;
+-
+- assert(manager);
+- assert(message);
+- assert(ret);
+-
+- /* check for link kind */
+- r = sd_netlink_message_enter_container(message, IFLA_LINKINFO);
+- if (r == 0) {
+- (void) sd_netlink_message_read_string(message, IFLA_INFO_KIND, &kind);
+- r = sd_netlink_message_exit_container(message);
+- if (r < 0)
+- return r;
+- }
+-
+- r = sd_netlink_message_get_type(message, &type);
+- if (r < 0)
+- return r;
+- else if (type != RTM_NEWLINK)
+- return -EINVAL;
+-
+- r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
+- if (r < 0)
+- return r;
+- else if (ifindex <= 0)
+- return -EINVAL;
+-
+- r = sd_rtnl_message_link_get_type(message, &iftype);
+- if (r < 0)
+- return r;
+-
+- r = sd_netlink_message_read_string(message, IFLA_IFNAME, &ifname);
+- if (r < 0)
+- return r;
+-
+- link = new(Link, 1);
+- if (!link)
+- return -ENOMEM;
+-
+- *link = (Link) {
+- .n_ref = 1,
+- .manager = manager,
+- .state = LINK_STATE_PENDING,
+- .ifindex = ifindex,
+- .iftype = iftype,
+-
+- .n_dns = (unsigned) -1,
+- .dns_default_route = -1,
+- .llmnr = _RESOLVE_SUPPORT_INVALID,
+- .mdns = _RESOLVE_SUPPORT_INVALID,
+- .dnssec_mode = _DNSSEC_MODE_INVALID,
+- .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
+- };
+-
+- link->ifname = strdup(ifname);
+- if (!link->ifname)
+- return -ENOMEM;
+-
+- if (kind) {
+- link->kind = strdup(kind);
+- if (!link->kind)
+- return -ENOMEM;
+- }
+-
+- r = sd_netlink_message_read_u32(message, IFLA_MASTER, (uint32_t *)&link->master_ifindex);
+- if (r < 0)
+- log_link_debug_errno(link, r, "New device has no master, continuing without");
+-
+- r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
+- if (r < 0)
+- log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
+-
+- if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
+- return -ENOMEM;
+-
+- if (asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex) < 0)
+- return -ENOMEM;
+-
+- if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
+- return -ENOMEM;
+-
+- r = hashmap_ensure_allocated(&manager->links, NULL);
+- if (r < 0)
+- return r;
+-
+- r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
+- if (r < 0)
+- return r;
+-
+- r = link_update_flags(link, message, false);
+- if (r < 0)
+- return r;
+-
+- *ret = TAKE_PTR(link);
+-
+- return 0;
+-}
+-
+ void link_ntp_settings_clear(Link *link) {
+ link->ntp = strv_free(link->ntp);
+ }
+@@ -2030,9 +1927,9 @@ static void link_drop_requests(Link *lin
+ request_drop(req);
+ }
+
+-void link_drop(Link *link) {
++Link *link_drop(Link *link) {
+ if (!link)
+- return;
++ return NULL;
+
+ assert(link->manager);
+
+@@ -2057,7 +1954,7 @@ void link_drop(Link *link) {
+
+ /* The following must be called at last. */
+ assert_se(hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)) == link);
+- link_unref(link);
++ return link_unref(link);
+ }
+
+ static int link_joined(Link *link) {
+@@ -3295,6 +3192,112 @@ ipv4ll_address_fail:
+
+ return 0;
+ }
++
++static Link *link_drop_or_unref(Link *link) {
++ if (!link)
++ return NULL;
++ if (!link->manager)
++ return link_unref(link);
++ return link_drop(link);
++}
++
++DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_drop_or_unref);
++
++static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
++ _cleanup_(link_drop_or_unrefp) Link *link = NULL;
++ uint16_t type;
++ _cleanup_free_ char *ifname = NULL, *kind = NULL;
++ int r, ifindex;
++ unsigned short iftype;
++
++ assert(manager);
++ assert(message);
++ assert(ret);
++
++ r = sd_netlink_message_get_type(message, &type);
++ if (r < 0)
++ return r;
++ else if (type != RTM_NEWLINK)
++ return -EINVAL;
++
++ r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
++ if (r < 0)
++ return r;
++ else if (ifindex <= 0)
++ return -EINVAL;
++
++ r = sd_rtnl_message_link_get_type(message, &iftype);
++ if (r < 0)
++ return r;
++
++ r = sd_netlink_message_read_string_strdup(message, IFLA_IFNAME, &ifname);
++ if (r < 0)
++ return r;
++
++ /* check for link kind */
++ r = sd_netlink_message_enter_container(message, IFLA_LINKINFO);
++ if (r >= 0) {
++ (void) sd_netlink_message_read_string_strdup(message, IFLA_INFO_KIND, &kind);
++ r = sd_netlink_message_exit_container(message);
++ if (r < 0)
++ return r;
++ }
++
++ link = new(Link, 1);
++ if (!link)
++ return -ENOMEM;
++
++ *link = (Link) {
++ .n_ref = 1,
++ .state = LINK_STATE_PENDING,
++ .ifindex = ifindex,
++ .iftype = iftype,
++ .ifname = TAKE_PTR(ifname),
++ .kind = TAKE_PTR(kind),
++
++ .n_dns = (unsigned) -1,
++ .dns_default_route = -1,
++ .llmnr = _RESOLVE_SUPPORT_INVALID,
++ .mdns = _RESOLVE_SUPPORT_INVALID,
++ .dnssec_mode = _DNSSEC_MODE_INVALID,
++ .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
++ };
++
++ r = hashmap_ensure_allocated(&manager->links, NULL);
++ if (r < 0)
++ return r;
++
++ r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
++ if (r < 0)
++ return r;
++
++ link->manager = manager;
++
++ r = sd_netlink_message_read_u32(message, IFLA_MASTER, (uint32_t*) &link->master_ifindex);
++ if (r < 0)
++ log_link_debug_errno(link, r, "New device has no master, continuing without");
++
++ r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
++ if (r < 0)
++ log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
++
++ if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
++ return -ENOMEM;
++
++ if (asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex) < 0)
++ return -ENOMEM;
++
++ if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
++ return -ENOMEM;
++
++ r = link_update_flags(link, message, false);
++ if (r < 0)
++ return r;
++
++ *ret = TAKE_PTR(link);
++
++ return 0;
++}
+
+ int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
+ _cleanup_(sd_device_unrefp) sd_device *device = NULL;
+
+--- a/src/network/networkd-link.h 2021-09-02 18:04:16.900542857 +0530
++++ b/src/network/networkd-link.h 2021-09-02 18:18:56.776571563 +0530
+@@ -175,7 +175,7 @@ DEFINE_TRIVIAL_DESTRUCTOR(link_netlink_d
+
+ int link_get(Manager *m, int ifindex, Link **ret);
+ int link_add(Manager *manager, sd_netlink_message *message, Link **ret);
+-void link_drop(Link *link);
++Link *link_drop(Link *link);
+
+ int link_down(Link *link, link_netlink_message_handler_t callback);
+
+
diff --git a/meta/recipes-core/systemd/systemd/network-merge-link_drop-and-link_detach_from_manager.patch b/meta/recipes-core/systemd/systemd/network-merge-link_drop-and-link_detach_from_manager.patch
new file mode 100644
index 0000000000..65bdc611df
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/network-merge-link_drop-and-link_detach_from_manager.patch
@@ -0,0 +1,67 @@
+From 63130eb36dc51e4fd50716c585f98ebe456ca7cf Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Mon, 17 May 2021 15:40:15 +0900
+Subject: [PATCH] network: merge link_drop() and link_detach_from_manager()
+
+link_detach_from_manager() is only called by link_drop(). It is not
+necessary to split such tiny function.
+
+Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/63130eb36dc51e4fd50716c585f98ebe456ca7cf]
+Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
+
+---
+ src/network/networkd-link.c | 27 ++++++++++++---------------
+ 1 file changed, 12 insertions(+), 15 deletions(-)
+
+diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
+index 9d30e16b0a..67d01ac44d 100644
+--- a/src/network/networkd-link.c
++++ b/src/network/networkd-link.c
+@@ -2019,24 +2019,17 @@ static void link_drop_from_master(Link *link, NetDev *netdev) {
+ link_unref(set_remove(master->slaves, link));
+ }
+
+-static void link_detach_from_manager(Link *link) {
+- if (!link || !link->manager)
+- return;
+-
+- link_unref(set_remove(link->manager->links_requesting_uuid, link));
+- link_clean(link);
+-
+- /* The following must be called at last. */
+- assert_se(hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)) == link);
+- link_unref(link);
+-}
+-
+ void link_drop(Link *link) {
+- if (!link || link->state == LINK_STATE_LINGER)
++ if (!link)
+ return;
+
++ assert(link->manager);
++
+ link_set_state(link, LINK_STATE_LINGER);
+
++ /* Drop all references from other links and manager. Note that async netlink calls may have
++ * references to the link, and they will be dropped when we receive replies. */
++
+ link_free_carrier_maps(link);
+
+ if (link->network) {
+@@ -2044,10 +2037,14 @@ void link_drop(Link *link) {
+ link_drop_from_master(link, link->network->bond);
+ }
+
+- log_link_debug(link, "Link removed");
++ link_unref(set_remove(link->manager->links_requesting_uuid, link));
+
+ (void) unlink(link->state_file);
+- link_detach_from_manager(link);
++ link_clean(link);
++
++ /* The following must be called at last. */
++ assert_se(hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)) == link);
++ link_unref(link);
+ }
+
+ static int link_joined(Link *link) {
diff --git a/meta/recipes-core/systemd/systemd/rm-rf-optionally-fsync-after-removing-directory-tree.patch b/meta/recipes-core/systemd/systemd/rm-rf-optionally-fsync-after-removing-directory-tree.patch
new file mode 100644
index 0000000000..b860da008c
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/rm-rf-optionally-fsync-after-removing-directory-tree.patch
@@ -0,0 +1,35 @@
+Backport of the following upstream commit:
+From bdfe7ada0d4d66e6d6e65f2822acbb1ec230f9c2 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Tue, 5 Oct 2021 10:32:56 +0200
+Subject: [PATCH] rm-rf: optionally fsync() after removing directory tree
+
+Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/s/systemd/systemd_245.4-4ubuntu3.15.debian.tar.xz]
+Signed-off-by: Purushottam Choudhary <Purushottam.Choudhary@kpit.com>
+---
+ src/basic/rm-rf.c | 3 +++
+ src/basic/rm-rf.h | 1 +
+ 2 files changed, 4 insertions(+)
+
+--- a/src/basic/rm-rf.c
++++ b/src/basic/rm-rf.c
+@@ -161,6 +161,9 @@
+ ret = r;
+ }
+
++ if (FLAGS_SET(flags, REMOVE_SYNCFS) && syncfs(dirfd(d)) < 0 && ret >= 0)
++ ret = -errno;
++
+ return ret;
+ }
+
+--- a/src/basic/rm-rf.h
++++ b/src/basic/rm-rf.h
+@@ -11,6 +11,7 @@
+ REMOVE_PHYSICAL = 1 << 2, /* If not set, only removes files on tmpfs, never physical file systems */
+ REMOVE_SUBVOLUME = 1 << 3, /* Drop btrfs subvolumes in the tree too */
+ REMOVE_MISSING_OK = 1 << 4, /* If the top-level directory is missing, ignore the ENOENT for it */
++ REMOVE_SYNCFS = 1 << 7, /* syncfs() the root of the specified directory after removing everything in it */
+ } RemoveFlags;
+
+ int rm_rf_children(int fd, RemoveFlags flags, const struct stat *root_dev);
diff --git a/meta/recipes-core/systemd/systemd/rm-rf-refactor-rm-rf-children-split-out-body-of-directory.patch b/meta/recipes-core/systemd/systemd/rm-rf-refactor-rm-rf-children-split-out-body-of-directory.patch
new file mode 100644
index 0000000000..f80e6433c6
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/rm-rf-refactor-rm-rf-children-split-out-body-of-directory.patch
@@ -0,0 +1,318 @@
+Backport of the following upstream commit:
+From 96906b22417c65d70933976e0ee920c70c9113a4 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Tue, 26 Jan 2021 16:30:06 +0100
+Subject: [PATCH] rm-rf: refactor rm_rf_children(), split out body of directory
+ iteration loop
+
+This splits out rm_rf_children_inner() as body of the loop. We can use
+that to implement rm_rf_child() for deleting one specific entry in a
+directory.
+
+Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/s/systemd/systemd_245.4-4ubuntu3.15.debian.tar.xz]
+Signed-off-by: Purushottam Choudhary <Purushottam.Choudhary@kpit.com>
+---
+ src/basic/rm-rf.c | 223 ++++++++++++++++++++++++++-------------------
+ src/basic/rm-rf.h | 3 +-
+ 2 files changed, 131 insertions(+), 95 deletions(-)
+
+--- a/src/basic/rm-rf.c
++++ b/src/basic/rm-rf.c
+@@ -19,138 +19,153 @@
+ #include "stat-util.h"
+ #include "string-util.h"
+
++/* We treat tmpfs/ramfs + cgroupfs as non-physical file sytems. cgroupfs is similar to tmpfs in a way after
++ * all: we can create arbitrary directory hierarchies in it, and hence can also use rm_rf() on it to remove
++ * those again. */
+ static bool is_physical_fs(const struct statfs *sfs) {
+ return !is_temporary_fs(sfs) && !is_cgroup_fs(sfs);
+ }
+
+-int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
++static int rm_rf_children_inner(
++ int fd,
++ const char *fname,
++ int is_dir,
++ RemoveFlags flags,
++ const struct stat *root_dev) {
++
++ struct stat st;
++ int r;
++
++ assert(fd >= 0);
++ assert(fname);
++
++ if (is_dir < 0 || (is_dir > 0 && (root_dev || (flags & REMOVE_SUBVOLUME)))) {
++
++ r = fstatat(fd, fname, &st, AT_SYMLINK_NOFOLLOW);
++ if (r < 0)
++ return r;
++
++ is_dir = S_ISDIR(st.st_mode);
++ }
++
++ if (is_dir) {
++ _cleanup_close_ int subdir_fd = -1;
++ int q;
++
++ /* if root_dev is set, remove subdirectories only if device is same */
++ if (root_dev && st.st_dev != root_dev->st_dev)
++ return 0;
++
++ /* Stop at mount points */
++ r = fd_is_mount_point(fd, fname, 0);
++ if (r < 0)
++ return r;
++ if (r > 0)
++ return 0;
++
++ if ((flags & REMOVE_SUBVOLUME) && st.st_ino == 256) {
++
++ /* This could be a subvolume, try to remove it */
++
++ r = btrfs_subvol_remove_fd(fd, fname, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
++ if (r < 0) {
++ if (!IN_SET(r, -ENOTTY, -EINVAL))
++ return r;
++
++ /* ENOTTY, then it wasn't a btrfs subvolume, continue below. */
++ } else
++ /* It was a subvolume, done. */
++ return 1;
++ }
++
++ subdir_fd = openat(fd, fname, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
++ if (subdir_fd < 0)
++ return -errno;
++
++ /* We pass REMOVE_PHYSICAL here, to avoid doing the fstatfs() to check the file system type
++ * again for each directory */
++ q = rm_rf_children(TAKE_FD(subdir_fd), flags | REMOVE_PHYSICAL, root_dev);
++
++ r = unlinkat(fd, fname, AT_REMOVEDIR);
++ if (r < 0)
++ return r;
++ if (q < 0)
++ return q;
++
++ return 1;
++
++ } else if (!(flags & REMOVE_ONLY_DIRECTORIES)) {
++ r = unlinkat(fd, fname, 0);
++ if (r < 0)
++ return r;
++
++ return 1;
++ }
++
++ return 0;
++}
++
++int rm_rf_children(
++ int fd,
++ RemoveFlags flags,
++ const struct stat *root_dev) {
++
+ _cleanup_closedir_ DIR *d = NULL;
+ struct dirent *de;
+ int ret = 0, r;
+- struct statfs sfs;
+
+ assert(fd >= 0);
+
+ /* This returns the first error we run into, but nevertheless tries to go on. This closes the passed
+- * fd, in all cases, including on failure.. */
++ * fd, in all cases, including on failure. */
++
++ d = fdopendir(fd);
++ if (!d) {
++ safe_close(fd);
++ return -errno;
++ }
+
+ if (!(flags & REMOVE_PHYSICAL)) {
++ struct statfs sfs;
+
+- r = fstatfs(fd, &sfs);
+- if (r < 0) {
+- safe_close(fd);
++ if (fstatfs(dirfd(d), &sfs) < 0)
+ return -errno;
+ }
+
+ if (is_physical_fs(&sfs)) {
+- /* We refuse to clean physical file systems with this call,
+- * unless explicitly requested. This is extra paranoia just
+- * to be sure we never ever remove non-state data. */
++ /* We refuse to clean physical file systems with this call, unless explicitly
++ * requested. This is extra paranoia just to be sure we never ever remove non-state
++ * data. */
++
+ _cleanup_free_ char *path = NULL;
+
+ (void) fd_get_path(fd, &path);
+- log_error("Attempted to remove disk file system under \"%s\", and we can't allow that.",
+- strna(path));
+-
+- safe_close(fd);
+- return -EPERM;
++ return log_error_errno(SYNTHETIC_ERRNO(EPERM),
++ "Attempted to remove disk file system under \"%s\", and we can't allow that.",
++ strna(path));
+ }
+ }
+
+- d = fdopendir(fd);
+- if (!d) {
+- safe_close(fd);
+- return errno == ENOENT ? 0 : -errno;
+- }
+-
+ FOREACH_DIRENT_ALL(de, d, return -errno) {
+- bool is_dir;
+- struct stat st;
++ int is_dir;
+
+ if (dot_or_dot_dot(de->d_name))
+ continue;
+
+- if (de->d_type == DT_UNKNOWN ||
+- (de->d_type == DT_DIR && (root_dev || (flags & REMOVE_SUBVOLUME)))) {
+- if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
+- if (ret == 0 && errno != ENOENT)
+- ret = -errno;
+- continue;
+- }
+-
+- is_dir = S_ISDIR(st.st_mode);
+- } else
+- is_dir = de->d_type == DT_DIR;
+-
+- if (is_dir) {
+- _cleanup_close_ int subdir_fd = -1;
+-
+- /* if root_dev is set, remove subdirectories only if device is same */
+- if (root_dev && st.st_dev != root_dev->st_dev)
+- continue;
+-
+- subdir_fd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
+- if (subdir_fd < 0) {
+- if (ret == 0 && errno != ENOENT)
+- ret = -errno;
+- continue;
+- }
+-
+- /* Stop at mount points */
+- r = fd_is_mount_point(fd, de->d_name, 0);
+- if (r < 0) {
+- if (ret == 0 && r != -ENOENT)
+- ret = r;
+-
+- continue;
+- }
+- if (r > 0)
+- continue;
+-
+- if ((flags & REMOVE_SUBVOLUME) && st.st_ino == 256) {
+-
+- /* This could be a subvolume, try to remove it */
+-
+- r = btrfs_subvol_remove_fd(fd, de->d_name, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
+- if (r < 0) {
+- if (!IN_SET(r, -ENOTTY, -EINVAL)) {
+- if (ret == 0)
+- ret = r;
+-
+- continue;
+- }
+-
+- /* ENOTTY, then it wasn't a btrfs subvolume, continue below. */
+- } else
+- /* It was a subvolume, continue. */
+- continue;
+- }
+-
+- /* We pass REMOVE_PHYSICAL here, to avoid doing the fstatfs() to check the file
+- * system type again for each directory */
+- r = rm_rf_children(TAKE_FD(subdir_fd), flags | REMOVE_PHYSICAL, root_dev);
+- if (r < 0 && ret == 0)
+- ret = r;
+-
+- if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
+- if (ret == 0 && errno != ENOENT)
+- ret = -errno;
+- }
+-
+- } else if (!(flags & REMOVE_ONLY_DIRECTORIES)) {
+-
+- if (unlinkat(fd, de->d_name, 0) < 0) {
+- if (ret == 0 && errno != ENOENT)
+- ret = -errno;
+- }
+- }
++ is_dir =
++ de->d_type == DT_UNKNOWN ? -1 :
++ de->d_type == DT_DIR;
++
++ r = rm_rf_children_inner(dirfd(d), de->d_name, is_dir, flags, root_dev);
++ if (r < 0 && r != -ENOENT && ret == 0)
++ ret = r;
+ }
++
+ return ret;
+ }
+
+ int rm_rf(const char *path, RemoveFlags flags) {
+ int fd, r;
+- struct statfs s;
+
+ assert(path);
+
+@@ -195,9 +210,10 @@
+ if (FLAGS_SET(flags, REMOVE_ROOT)) {
+
+ if (!FLAGS_SET(flags, REMOVE_PHYSICAL)) {
++ struct statfs s;
++
+ if (statfs(path, &s) < 0)
+ return -errno;
+-
+ if (is_physical_fs(&s))
+ return log_error_errno(SYNTHETIC_ERRNO(EPERM),
+ "Attempted to remove files from a disk file system under \"%s\", refusing.",
+@@ -225,3 +241,22 @@
+
+ return r;
+ }
++
++int rm_rf_child(int fd, const char *name, RemoveFlags flags) {
++
++ /* Removes one specific child of the specified directory */
++
++ if (fd < 0)
++ return -EBADF;
++
++ if (!filename_is_valid(name))
++ return -EINVAL;
++
++ if ((flags & (REMOVE_ROOT|REMOVE_MISSING_OK)) != 0) /* Doesn't really make sense here, we are not supposed to remove 'fd' anyway */
++ return -EINVAL;
++
++ if (FLAGS_SET(flags, REMOVE_ONLY_DIRECTORIES|REMOVE_SUBVOLUME))
++ return -EINVAL;
++
++ return rm_rf_children_inner(fd, name, -1, flags, NULL);
++}
+--- a/src/basic/rm-rf.h
++++ b/src/basic/rm-rf.h
+@@ -13,7 +13,8 @@
+ REMOVE_MISSING_OK = 1 << 4, /* If the top-level directory is missing, ignore the ENOENT for it */
+ } RemoveFlags;
+
+-int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev);
++int rm_rf_children(int fd, RemoveFlags flags, const struct stat *root_dev);
++int rm_rf_child(int fd, const char *name, RemoveFlags flags);
+ int rm_rf(const char *path, RemoveFlags flags);
+
+ /* Useful for usage with _cleanup_(), destroys a directory and frees the pointer */
diff --git a/meta/recipes-core/systemd/systemd/systemd-pager.sh b/meta/recipes-core/systemd/systemd/systemd-pager.sh
new file mode 100644
index 0000000000..86e3e0ab78
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/systemd-pager.sh
@@ -0,0 +1,7 @@
+# Systemd expect a color capable pager, however the less provided
+# by busybox is not. This make many interaction with systemd pretty
+# annoying. As a workaround we disable the systemd pager if less
+# is not the GNU version.
+if ! less -V > /dev/null 2>&1 ; then
+ export SYSTEMD_PAGER=
+fi
diff --git a/meta/recipes-core/systemd/systemd_244.3.bb b/meta/recipes-core/systemd/systemd_244.5.bb
index 850d64e8b0..8b2f47b92f 100644
--- a/meta/recipes-core/systemd/systemd_244.3.bb
+++ b/meta/recipes-core/systemd/systemd_244.5.bb
@@ -18,9 +18,28 @@ SRC_URI += "file://touchscreen.rules \
file://00-create-volatile.conf \
file://init \
file://99-default.preset \
+ file://systemd-pager.sh \
file://0001-binfmt-Don-t-install-dependency-links-at-install-tim.patch \
file://0003-implment-systemd-sysv-install-for-OE.patch \
- file://CVE-2020-13776.patch \
+ file://CVE-2021-33910.patch \
+ file://CVE-2020-13529.patch \
+ file://basic-pass-allocation-info-for-ordered-set-new-and-introd.patch \
+ file://introduce-ordered_set_clear-free-with-destructor.patch \
+ file://network-add-skeleton-of-request-queue.patch \
+ file://network-merge-link_drop-and-link_detach_from_manager.patch \
+ file://network-also-drop-requests-when-link-enters-linger-state.patch \
+ file://network-fix-Link-reference-counter-issue.patch \
+ file://rm-rf-refactor-rm-rf-children-split-out-body-of-directory.patch \
+ file://rm-rf-optionally-fsync-after-removing-directory-tree.patch \
+ file://CVE-2018-21029.patch \
+ file://CVE-2021-3997-1.patch \
+ file://CVE-2021-3997-2.patch \
+ file://CVE-2021-3997-3.patch \
+ file://CVE-2022-3821.patch \
+ file://CVE-2023-26604-1.patch \
+ file://CVE-2023-26604-2.patch \
+ file://CVE-2023-26604-3.patch \
+ file://CVE-2023-26604-4.patch \
"
# patches needed by musl
@@ -50,6 +69,9 @@ SRC_URI_MUSL = "\
file://0004-src-shared-cpu-set-util.h-add-__cpu_mask-definition.patch \
"
+# already applied in 244.5
+CVE_CHECK_WHITELIST += "CVE-2020-13776"
+
PAM_PLUGINS = " \
pam-plugin-unix \
pam-plugin-loginuid \
@@ -86,6 +108,7 @@ PACKAGECONFIG ??= " \
timesyncd \
utmp \
vconsole \
+ wheel-group \
xz \
"
@@ -146,6 +169,7 @@ PACKAGECONFIG[manpages] = "-Dman=true,-Dman=false,libxslt-native xmlto-native do
PACKAGECONFIG[microhttpd] = "-Dmicrohttpd=true,-Dmicrohttpd=false,libmicrohttpd"
PACKAGECONFIG[myhostname] = "-Dnss-myhostname=true,-Dnss-myhostname=false,,libnss-myhostname"
PACKAGECONFIG[networkd] = "-Dnetworkd=true,-Dnetworkd=false"
+PACKAGECONFIG[no-dns-fallback] = "-Ddns-servers="
PACKAGECONFIG[nss] = "-Dnss-systemd=true,-Dnss-systemd=false"
PACKAGECONFIG[nss-mymachines] = "-Dnss-mymachines=true,-Dnss-mymachines=false"
PACKAGECONFIG[nss-resolve] = "-Dnss-resolve=true,-Dnss-resolve=false"
@@ -178,6 +202,7 @@ PACKAGECONFIG[sbinmerge] = "-Dsplit-bin=false,-Dsplit-bin=true"
PACKAGECONFIG[utmp] = "-Dutmp=true,-Dutmp=false"
PACKAGECONFIG[valgrind] = "-DVALGRIND=1,,valgrind"
PACKAGECONFIG[vconsole] = "-Dvconsole=true,-Dvconsole=false,,${PN}-vconsole-setup"
+PACKAGECONFIG[wheel-group] = "-Dwheel-group=true, -Dwheel-group=false"
# Verify keymaps on locale change
PACKAGECONFIG[xkbcommon] = "-Dxkbcommon=true,-Dxkbcommon=false,libxkbcommon"
PACKAGECONFIG[xz] = "-Dxz=true,-Dxz=false,xz"
@@ -195,10 +220,12 @@ rootlibexecdir = "${rootprefix}/lib"
EXTRA_OEMESON += "-Dlink-udev-shared=false"
EXTRA_OEMESON += "-Dnobody-user=nobody \
- -Dnobody-group=nobody \
+ -Dnobody-group=nogroup \
-Drootlibdir=${rootlibdir} \
-Drootprefix=${rootprefix} \
-Ddefault-locale=C \
+ -Dsystem-uid-max=999 \
+ -Dsystem-gid-max=999 \
"
# Hardcode target binary paths to avoid using paths from sysroot
@@ -296,6 +323,9 @@ do_install() {
# install default policy for presets
# https://www.freedesktop.org/wiki/Software/systemd/Preset/#howto
install -Dm 0644 ${WORKDIR}/99-default.preset ${D}${systemd_unitdir}/system-preset/99-default.preset
+
+ # add a profile fragment to disable systemd pager with busybox less
+ install -Dm 0644 ${WORKDIR}/systemd-pager.sh ${D}${sysconfdir}/profile.d/systemd-pager.sh
}
python populate_packages_prepend (){
@@ -383,9 +413,9 @@ FILES_${PN}-binfmt = "${sysconfdir}/binfmt.d/ \
${rootlibexecdir}/systemd/systemd-binfmt \
${systemd_unitdir}/system/proc-sys-fs-binfmt_misc.* \
${systemd_unitdir}/system/systemd-binfmt.service"
-RRECOMMENDS_${PN}-binfmt = "kernel-module-binfmt-misc"
+RRECOMMENDS_${PN}-binfmt = "${@bb.utils.contains('PACKAGECONFIG', 'binfmt', 'kernel-module-binfmt-misc', '', d)}"
-RRECOMMENDS_${PN}-vconsole-setup = "kbd kbd-consolefonts kbd-keymaps"
+RRECOMMENDS_${PN}-vconsole-setup = "${@bb.utils.contains('PACKAGECONFIG', 'vconsole', 'kbd kbd-consolefonts kbd-keymaps', '', d)}"
FILES_${PN}-journal-gatewayd = "${rootlibexecdir}/systemd/systemd-journal-gatewayd \
@@ -518,6 +548,7 @@ FILES_${PN} = " ${base_bindir}/* \
${sysconfdir}/dbus-1/ \
${sysconfdir}/modules-load.d/ \
${sysconfdir}/pam.d/ \
+ ${sysconfdir}/profile.d/ \
${sysconfdir}/sysctl.d/ \
${sysconfdir}/systemd/ \
${sysconfdir}/tmpfiles.d/ \