Compare commits

...

No commits in common. 'c9' and 'c8' have entirely different histories.
c9 ... c8

5
.gitignore vendored

@ -1,3 +1,2 @@
SOURCES/rhel-net-naming-sysattrs-v0.5.tar.gz
SOURCES/systemd-252.tar.gz
SOURCES/systemd-container-coredump.pp.bz2
SOURCES/0243-udev-Add-id-program-and-rule-for-FIDO-security-token.patch
SOURCES/systemd-239.tar.gz

@ -1,3 +1,2 @@
9ce6834429dbb9cb049de1bdf77bc8c84763709c SOURCES/rhel-net-naming-sysattrs-v0.5.tar.gz
7c961dc6e8bb950825b85129f59dc80f4536cabb SOURCES/systemd-252.tar.gz
36eac49c362dc6e142f23b570a9a6b75f7547250 SOURCES/systemd-container-coredump.pp.bz2
23da9fdb9eeaef49fe1adbf42a18d9e8a99d7911 SOURCES/0243-udev-Add-id-program-and-rule-for-FIDO-security-token.patch
8803baa484cbe36680463c8c5e6febeff074b8e7 SOURCES/systemd-239.tar.gz

@ -0,0 +1,105 @@
From 79df4db3fd122f5040bdf2225c3047375de3b0d2 Mon Sep 17 00:00:00 2001
From: Filipe Brandenburger <filbranden@google.com>
Date: Sun, 15 Jul 2018 22:43:35 -0700
Subject: [PATCH] build-sys: Detect whether struct statx is defined in
sys/stat.h
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Starting with glibc 2.27.9000-36.fc29, include file sys/stat.h will have a
definition for struct statx, in which case include file linux/stat.h should be
avoided, in order to prevent a duplicate definition.
In file included from ../src/basic/missing.h:18,
from ../src/basic/util.h:28,
from ../src/basic/hashmap.h:10,
from ../src/shared/bus-util.h:12,
from ../src/libsystemd/sd-bus/bus-creds.c:11:
/usr/include/linux/stat.h:99:8: error: redefinition of struct statx
struct statx {
^~~~~
In file included from /usr/include/sys/stat.h:446,
from ../src/basic/util.h:19,
from ../src/basic/hashmap.h:10,
from ../src/shared/bus-util.h:12,
from ../src/libsystemd/sd-bus/bus-creds.c:11:
/usr/include/bits/statx.h:36:8: note: originally defined here
struct statx
^~~~~
Extend our meson.build to look for struct statx when only sys/stat.h is
included and, in that case, do not include linux/stat.h anymore.
Tested that systemd builds correctly when using a glibc version that includes a
definition for struct statx.
glibc Fedora RPM update:
https://src.fedoraproject.org/rpms/glibc/c/28cb5d31fc1e5887912283c889689c47076278ae
glibc upstream commit:
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=fd70af45528d59a00eb3190ef6706cb299488fcd
---
meson.build | 5 +++++
src/basic/missing.h | 5 ++++-
src/basic/xattr-util.c | 1 -
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/meson.build b/meson.build
index 04331dd41a..a0e7240708 100644
--- a/meson.build
+++ b/meson.build
@@ -425,6 +425,7 @@ decl_headers = '''
#include <sys/stat.h>
'''
# FIXME: key_serial_t is only defined in keyutils.h, this is bound to fail
+# FIXME: these should use -D_GNU_SOURCE, since that is defined at build time
foreach decl : ['char16_t',
'char32_t',
@@ -439,6 +440,10 @@ foreach decl : ['char16_t',
conf.set10('HAVE_' + decl.underscorify().to_upper(), have)
endforeach
+conf.set10('HAVE_STRUCT_STATX_IN_SYS_STAT_H', cc.sizeof('struct statx', prefix : '''
+#include <sys/stat.h>
+''', args : '-D_GNU_SOURCE') > 0)
+
foreach decl : [['IFLA_INET6_ADDR_GEN_MODE', 'linux/if_link.h'],
['IN6_ADDR_GEN_MODE_STABLE_PRIVACY', 'linux/if_link.h'],
['IFLA_VRF_TABLE', 'linux/if_link.h'],
diff --git a/src/basic/missing.h b/src/basic/missing.h
index 71a07d0574..14ad3d4914 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -15,7 +15,6 @@
#include <linux/neighbour.h>
#include <linux/oom.h>
#include <linux/rtnetlink.h>
-#include <linux/stat.h>
#include <net/ethernet.h>
#include <stdlib.h>
#include <sys/resource.h>
@@ -25,6 +24,10 @@
#include <uchar.h>
#include <unistd.h>
+#if !HAVE_STRUCT_STATX_IN_SYS_STAT_H
+#include <linux/stat.h>
+#endif
+
#if HAVE_AUDIT
#include <libaudit.h>
#endif
diff --git a/src/basic/xattr-util.c b/src/basic/xattr-util.c
index c5c55ea846..0ee0979837 100644
--- a/src/basic/xattr-util.c
+++ b/src/basic/xattr-util.c
@@ -2,7 +2,6 @@
#include <errno.h>
#include <fcntl.h>
-#include <linux/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

@ -1,78 +0,0 @@
From 87bf366c97be1c811c4bfdf80b48d6c3e35da76a Mon Sep 17 00:00:00 2001
From: Jan Janssen <medhefgo@web.de>
Date: Tue, 25 Oct 2022 19:55:08 +0200
Subject: [PATCH] macro: Simply case macros for IN_SET
The CASE param would normally provide the operation for the compiler to
do in this macro magic. But in this case CASE_F_1 was hardcoding the
operation, making the parameter moot.
This just removes the somewhat pointless parameter instead of fixing
the one case. These macros are used for IN_SET case labels only and
not named generically anyways.
(cherry picked from commit 790f4dda74d7ecdb4e57101a37cc9f2f9236bef6)
Related #2138081
---
src/fundamental/macro-fundamental.h | 43 ++++++++++++++---------------
1 file changed, 21 insertions(+), 22 deletions(-)
diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h
index 2536c741c6..63f4c49e78 100644
--- a/src/fundamental/macro-fundamental.h
+++ b/src/fundamental/macro-fundamental.h
@@ -251,33 +251,32 @@
(UNIQ_T(X, xq) / UNIQ_T(Y, yq) + !!(UNIQ_T(X, xq) % UNIQ_T(Y, yq))); \
})
-#define CASE_F(X) case X:
-#define CASE_F_1(CASE, X) CASE_F(X)
-#define CASE_F_2(CASE, X, ...) CASE(X) CASE_F_1(CASE, __VA_ARGS__)
-#define CASE_F_3(CASE, X, ...) CASE(X) CASE_F_2(CASE, __VA_ARGS__)
-#define CASE_F_4(CASE, X, ...) CASE(X) CASE_F_3(CASE, __VA_ARGS__)
-#define CASE_F_5(CASE, X, ...) CASE(X) CASE_F_4(CASE, __VA_ARGS__)
-#define CASE_F_6(CASE, X, ...) CASE(X) CASE_F_5(CASE, __VA_ARGS__)
-#define CASE_F_7(CASE, X, ...) CASE(X) CASE_F_6(CASE, __VA_ARGS__)
-#define CASE_F_8(CASE, X, ...) CASE(X) CASE_F_7(CASE, __VA_ARGS__)
-#define CASE_F_9(CASE, X, ...) CASE(X) CASE_F_8(CASE, __VA_ARGS__)
-#define CASE_F_10(CASE, X, ...) CASE(X) CASE_F_9(CASE, __VA_ARGS__)
-#define CASE_F_11(CASE, X, ...) CASE(X) CASE_F_10(CASE, __VA_ARGS__)
-#define CASE_F_12(CASE, X, ...) CASE(X) CASE_F_11(CASE, __VA_ARGS__)
-#define CASE_F_13(CASE, X, ...) CASE(X) CASE_F_12(CASE, __VA_ARGS__)
-#define CASE_F_14(CASE, X, ...) CASE(X) CASE_F_13(CASE, __VA_ARGS__)
-#define CASE_F_15(CASE, X, ...) CASE(X) CASE_F_14(CASE, __VA_ARGS__)
-#define CASE_F_16(CASE, X, ...) CASE(X) CASE_F_15(CASE, __VA_ARGS__)
-#define CASE_F_17(CASE, X, ...) CASE(X) CASE_F_16(CASE, __VA_ARGS__)
-#define CASE_F_18(CASE, X, ...) CASE(X) CASE_F_17(CASE, __VA_ARGS__)
-#define CASE_F_19(CASE, X, ...) CASE(X) CASE_F_18(CASE, __VA_ARGS__)
-#define CASE_F_20(CASE, X, ...) CASE(X) CASE_F_19(CASE, __VA_ARGS__)
+#define CASE_F_1(X) case X:
+#define CASE_F_2(X, ...) case X: CASE_F_1( __VA_ARGS__)
+#define CASE_F_3(X, ...) case X: CASE_F_2( __VA_ARGS__)
+#define CASE_F_4(X, ...) case X: CASE_F_3( __VA_ARGS__)
+#define CASE_F_5(X, ...) case X: CASE_F_4( __VA_ARGS__)
+#define CASE_F_6(X, ...) case X: CASE_F_5( __VA_ARGS__)
+#define CASE_F_7(X, ...) case X: CASE_F_6( __VA_ARGS__)
+#define CASE_F_8(X, ...) case X: CASE_F_7( __VA_ARGS__)
+#define CASE_F_9(X, ...) case X: CASE_F_8( __VA_ARGS__)
+#define CASE_F_10(X, ...) case X: CASE_F_9( __VA_ARGS__)
+#define CASE_F_11(X, ...) case X: CASE_F_10( __VA_ARGS__)
+#define CASE_F_12(X, ...) case X: CASE_F_11( __VA_ARGS__)
+#define CASE_F_13(X, ...) case X: CASE_F_12( __VA_ARGS__)
+#define CASE_F_14(X, ...) case X: CASE_F_13( __VA_ARGS__)
+#define CASE_F_15(X, ...) case X: CASE_F_14( __VA_ARGS__)
+#define CASE_F_16(X, ...) case X: CASE_F_15( __VA_ARGS__)
+#define CASE_F_17(X, ...) case X: CASE_F_16( __VA_ARGS__)
+#define CASE_F_18(X, ...) case X: CASE_F_17( __VA_ARGS__)
+#define CASE_F_19(X, ...) case X: CASE_F_18( __VA_ARGS__)
+#define CASE_F_20(X, ...) case X: CASE_F_19( __VA_ARGS__)
#define GET_CASE_F(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,NAME,...) NAME
#define FOR_EACH_MAKE_CASE(...) \
GET_CASE_F(__VA_ARGS__,CASE_F_20,CASE_F_19,CASE_F_18,CASE_F_17,CASE_F_16,CASE_F_15,CASE_F_14,CASE_F_13,CASE_F_12,CASE_F_11, \
CASE_F_10,CASE_F_9,CASE_F_8,CASE_F_7,CASE_F_6,CASE_F_5,CASE_F_4,CASE_F_3,CASE_F_2,CASE_F_1) \
- (CASE_F,__VA_ARGS__)
+ (__VA_ARGS__)
#define IN_SET(x, ...) \
({ \

@ -1,11 +1,9 @@
From 49fab9715ce09b86652e9855555e4ab4fc185220 Mon Sep 17 00:00:00 2001
From 0b3833d6c3b751c6dfb40eeb2ef852984c58f546 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 1 Aug 2018 10:58:28 +0200
Subject: [PATCH] logind: set RemoveIPC to false by default
RHEL-only
Related: #2138081
Resolves: #1523233
---
man/logind.conf.xml | 2 +-
src/login/logind-core.c | 2 +-
@ -13,10 +11,10 @@ Related: #2138081
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
index 9682add08c..1a87cf6baf 100644
index 9e88764c6f..7d7e869a26 100644
--- a/man/logind.conf.xml
+++ b/man/logind.conf.xml
@@ -341,7 +341,7 @@
@@ -319,7 +319,7 @@
user fully logs out. Takes a boolean argument. If enabled, the user may not consume IPC resources after the
last of the user's sessions terminated. This covers System V semaphores, shared memory and message queues, as
well as POSIX shared memory and message queues. Note that IPC objects of the root user and other system users
@ -24,30 +22,29 @@ index 9682add08c..1a87cf6baf 100644
+ are excluded from the effect of this setting. Defaults to <literal>no</literal>.</para></listitem>
</varlistentry>
<varlistentry>
</variablelist>
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index 02adc81909..b5050c54c4 100644
index dbae4bf5af..511e3acf8f 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -34,7 +34,7 @@ void manager_reset_config(Manager *m) {
@@ -25,7 +25,7 @@ void manager_reset_config(Manager *m) {
m->n_autovts = 6;
m->reserve_vt = 6;
- m->remove_ipc = true;
+ m->remove_ipc = false;
m->inhibit_delay_max = 5 * USEC_PER_SEC;
m->user_stop_delay = 10 * USEC_PER_SEC;
m->handle_power_key = HANDLE_POWEROFF;
m->handle_suspend_key = HANDLE_SUSPEND;
diff --git a/src/login/logind.conf.in b/src/login/logind.conf.in
index 0b10df6839..09c363817a 100644
index 1029e29bc7..c7346f9819 100644
--- a/src/login/logind.conf.in
+++ b/src/login/logind.conf.in
@@ -43,7 +43,7 @@
@@ -32,6 +32,6 @@
#IdleAction=ignore
#IdleActionSec=30min
#RuntimeDirectorySize=10%
#RuntimeDirectoryInodesMax=
-#RemoveIPC=yes
+#RemoveIPC=no
#InhibitorsMax=8192
#SessionsMax=8192
#StopIdleSessionSec=infinity

@ -1,25 +0,0 @@
From 0c372e24bb30c25beccd76c071baca22258e71c9 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 26 Oct 2022 03:28:08 +0900
Subject: [PATCH] macro: fix indentation
(cherry picked from commit e967926b092d8635b3da28fc4ca492009e32228f)
Related #2138081
---
src/fundamental/macro-fundamental.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h
index 63f4c49e78..faab16ab31 100644
--- a/src/fundamental/macro-fundamental.h
+++ b/src/fundamental/macro-fundamental.h
@@ -290,7 +290,7 @@
switch (x) { \
FOR_EACH_MAKE_CASE(__VA_ARGS__) \
_found = true; \
- break; \
+ break; \
default: \
break; \
} \

@ -0,0 +1,53 @@
From b924c79720cc2bf2edf75fa3ff43bb4954fccf1f Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 1 Aug 2018 13:19:39 +0200
Subject: [PATCH] pid1: bump DefaultTasksMax to 80% of the kernel pid.max value
This should be hopefully high enough even for the very big deployments.
Resolves: #1523236
---
man/systemd-system.conf.xml | 2 +-
src/basic/cgroup-util.h | 2 +-
src/core/system.conf.in | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
index a914ef2523..085086200a 100644
--- a/man/systemd-system.conf.xml
+++ b/man/systemd-system.conf.xml
@@ -339,7 +339,7 @@
<listitem><para>Configure the default value for the per-unit <varname>TasksMax=</varname> setting. See
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. This setting applies to all unit types that support resource control settings, with the exception
- of slice units. Defaults to 15%, which equals 4915 with the kernel's defaults on the host, but might be smaller
+ of slice units. Defaults to 80%, which equals 26214 with the kernel's defaults on the host, but might be smaller
in OS containers.</para></listitem>
</varlistentry>
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index 1a28a8163a..f10c26ad51 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -100,7 +100,7 @@ static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) {
}
/* Default resource limits */
-#define DEFAULT_TASKS_MAX_PERCENTAGE 15U /* 15% of PIDs, 4915 on default settings */
+#define DEFAULT_TASKS_MAX_PERCENTAGE 80U /* 80% of PIDs, 26214 on default settings */
#define DEFAULT_USER_TASKS_MAX_PERCENTAGE 33U /* 33% of PIDs, 10813 on default settings */
typedef enum CGroupUnified {
diff --git a/src/core/system.conf.in b/src/core/system.conf.in
index f0a59a79a5..653ec6b8c9 100644
--- a/src/core/system.conf.in
+++ b/src/core/system.conf.in
@@ -45,7 +45,7 @@
#DefaultBlockIOAccounting=no
#DefaultMemoryAccounting=@MEMORY_ACCOUNTING_DEFAULT@
#DefaultTasksAccounting=yes
-#DefaultTasksMax=15%
+#DefaultTasksMax=80%
#DefaultLimitCPU=
#DefaultLimitFSIZE=
#DefaultLimitDATA=

@ -1,61 +0,0 @@
From 5ac8c56f111f2875467422c851a05891c0ec7d1b Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Mon, 31 Oct 2022 12:11:59 +0100
Subject: [PATCH] test: add a couple of sanity tests for journalctl
(cherry picked from commit ca46781c5ffa3aaa7a8fb6f09976357d003c4aae)
Related #2138081
---
test/units/testsuite-04.sh | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/test/units/testsuite-04.sh b/test/units/testsuite-04.sh
index b5468cbea4..fdc3273fea 100755
--- a/test/units/testsuite-04.sh
+++ b/test/units/testsuite-04.sh
@@ -119,6 +119,44 @@ systemctl start silent-success
journalctl --sync
[[ -z "$(journalctl -b -q -u silent-success.service)" ]]
+# Exercise the matching machinery
+SYSTEMD_LOG_LEVEL=debug journalctl -b -n 1 /dev/null /dev/zero /dev/null /dev/null /dev/null
+journalctl -b -n 1 /bin/true /bin/false
+journalctl -b -n 1 /bin/true + /bin/false
+journalctl -b -n 1 -r --unit "systemd*"
+
+systemd-run --user -M "testuser@.host" /bin/echo hello
+journalctl --sync
+journalctl -b -n 1 -r --user-unit "*"
+
+(! journalctl -b /dev/lets-hope-this-doesnt-exist)
+(! journalctl -b /dev/null /dev/zero /dev/this-also-shouldnt-exist)
+(! journalctl -b --unit "this-unit-should-not-exist*")
+
+# Facilities & priorities
+journalctl --facility help
+journalctl --facility kern -n 1
+journalctl --facility syslog --priority 0..3 -n 1
+journalctl --facility syslog --priority 3..0 -n 1
+journalctl --facility user --priority 0..0 -n 1
+journalctl --facility daemon --priority warning -n 1
+journalctl --facility daemon --priority warning..info -n 1
+journalctl --facility daemon --priority notice..crit -n 1
+journalctl --facility daemon --priority 5..crit -n 1
+
+(! journalctl --facility hopefully-an-unknown-facility)
+(! journalctl --priority hello-world)
+(! journalctl --priority 0..128)
+(! journalctl --priority 0..systemd)
+
+# Other options
+journalctl --disk-usage
+journalctl --dmesg -n 1
+journalctl --fields
+journalctl --list-boots
+journalctl --update-catalog
+journalctl --list-catalog
+
# Add new tests before here, the journald restarts below
# may make tests flappy.

@ -0,0 +1,51 @@
From f58c5ced373c2532b5cc44ba2e0c3a28b41472f2 Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Tue, 15 May 2018 09:24:20 +0200
Subject: [PATCH] Avoid /tmp being mounted as tmpfs without the user's will
Ensure PrivateTmp doesn't require tmpfs through tmp.mount, but rather
adds an After relationship.
rhel-only
Resolves: #1578772
---
src/core/unit.c | 12 ++++++------
units/basic.target | 3 ++-
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/core/unit.c b/src/core/unit.c
index 113205bf25..c9f756c9c7 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -982,13 +982,13 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
return 0;
if (c->private_tmp) {
- const char *p;
+ r = unit_add_dependency_by_name(u, UNIT_AFTER, "tmp.mount", NULL, true, UNIT_DEPENDENCY_FILE);
+ if (r < 0)
+ return r;
- FOREACH_STRING(p, "/tmp", "/var/tmp") {
- r = unit_require_mounts_for(u, p, UNIT_DEPENDENCY_FILE);
- if (r < 0)
- return r;
- }
+ r = unit_require_mounts_for(u, "/var/tmp", UNIT_DEPENDENCY_FILE);
+ if (r < 0)
+ return r;
r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_TMPFILES_SETUP_SERVICE, NULL, true, UNIT_DEPENDENCY_FILE);
if (r < 0)
diff --git a/units/basic.target b/units/basic.target
index 4f44292249..8fc7c73ef2 100644
--- a/units/basic.target
+++ b/units/basic.target
@@ -19,4 +19,5 @@ After=sysinit.target sockets.target paths.target slices.target tmp.mount
# require /var and /var/tmp, but only add a Wants= type dependency on /tmp, as
# we support that unit being masked, and this should not be considered an error.
RequiresMountsFor=/var /var/tmp
-Wants=tmp.mount
+# RHEL-only: Disable /tmp on tmpfs.
+#Wants=tmp.mount

@ -1,25 +0,0 @@
From b1a2687cf5b419d6928d024f26aabe1de8ff7727 Mon Sep 17 00:00:00 2001
From: Luca Boccassi <bluca@debian.org>
Date: Mon, 31 Oct 2022 21:17:47 +0000
Subject: [PATCH] man: fix typo found by Lintian
(cherry picked from commit 84033dd40588dbf4f57a746c141fe7d111247a93)
Related #2138081
---
man/loader.conf.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/man/loader.conf.xml b/man/loader.conf.xml
index 3ee42cdb73..7f173aec61 100644
--- a/man/loader.conf.xml
+++ b/man/loader.conf.xml
@@ -236,7 +236,7 @@
<para>The different sets of variables can be set up under <filename>/loader/keys/<replaceable>NAME</replaceable></filename>
where <replaceable>NAME</replaceable> is the name that is going to be used as the name of the entry.
- This allows to ship multiple sets of Secure Boot variables and choose which one to enroll at runtime.</para>
+ This allows one to ship multiple sets of Secure Boot variables and choose which one to enroll at runtime.</para>
<para>Supported secure boot variables are one database for authorized images, one key exchange key (KEK)
and one platform key (PK). For more information, refer to the <ulink url="https://uefi.org/specifications">UEFI specification</ulink>,

@ -0,0 +1,35 @@
From c7f77dfd2bfa593bfbbdf82eea8b600ca1b46f4c Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 1 Aug 2018 17:17:07 +0200
Subject: [PATCH] pid1: bump maximum number of process in user slice to 80% of
pid_max
Related: #1523236
---
src/basic/cgroup-util.h | 2 +-
units/user-.slice.d/10-defaults.conf | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index f10c26ad51..26e3ae0404 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -101,7 +101,7 @@ static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) {
/* Default resource limits */
#define DEFAULT_TASKS_MAX_PERCENTAGE 80U /* 80% of PIDs, 26214 on default settings */
-#define DEFAULT_USER_TASKS_MAX_PERCENTAGE 33U /* 33% of PIDs, 10813 on default settings */
+#define DEFAULT_USER_TASKS_MAX_PERCENTAGE 80U /* 80% of PIDs, 26214 on default settings */
typedef enum CGroupUnified {
CGROUP_UNIFIED_UNKNOWN = -1,
diff --git a/units/user-.slice.d/10-defaults.conf b/units/user-.slice.d/10-defaults.conf
index 95ab11b30b..efc9d37c8e 100644
--- a/units/user-.slice.d/10-defaults.conf
+++ b/units/user-.slice.d/10-defaults.conf
@@ -12,4 +12,4 @@ Description=User Slice of UID %j
After=systemd-user-sessions.service
[Slice]
-TasksMax=33%
+TasksMax=80%

@ -1,19 +0,0 @@
From 3d2fc0517d43ff2c5c6fc03ebb68ef9429be5fd4 Mon Sep 17 00:00:00 2001
From: Luca Boccassi <bluca@debian.org>
Date: Mon, 31 Oct 2022 21:18:53 +0000
Subject: [PATCH] test: add +x to assert.sh
The script has a shebang and .sh extension, so make it executable
W: systemd-tests: script-not-executable [usr/lib/systemd/tests/testdata/units/assert.sh]
(cherry picked from commit fb4f7271d9f75a44756b110706cdb53b82f407ce)
Related #2138081
---
test/units/assert.sh | 0
1 file changed, 0 insertions(+), 0 deletions(-)
mode change 100644 => 100755 test/units/assert.sh
diff --git a/test/units/assert.sh b/test/units/assert.sh
old mode 100644
new mode 100755

@ -1,25 +0,0 @@
From a2cb8467652ca36bd5420dc685d5e6b76014c3e1 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 1 Nov 2022 13:10:20 +0900
Subject: [PATCH] parse_hwdb: allow negative value for EVDEV_ABS_ properties
(cherry picked from commit f0b75cda5a3eac3fe953fd1a429a39e077387997)
Related #2138081
---
hwdb.d/parse_hwdb.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hwdb.d/parse_hwdb.py b/hwdb.d/parse_hwdb.py
index c0dde75650..5a1ae5a6a0 100755
--- a/hwdb.d/parse_hwdb.py
+++ b/hwdb.d/parse_hwdb.py
@@ -202,7 +202,7 @@ def property_grammar():
]
abs_props = [Regex(r'EVDEV_ABS_[0-9a-f]{2}')('NAME')
- Suppress('=') -
- Word(nums + ':')('VALUE')
+ Word('-' + nums + ':')('VALUE')
]
grammar = Or(fixed_props + kbd_props + abs_props) + EOL

@ -0,0 +1,33 @@
From 787420ac2ba9c404e13db08601946bde263523f8 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 22 Sep 2014 07:41:06 +0200
Subject: [PATCH] rules: automatically online hot-plugged CPUs
Related: #1523227
---
rules/40-redhat.rules | 3 +++
rules/meson.build | 1 +
2 files changed, 4 insertions(+)
create mode 100644 rules/40-redhat.rules
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
new file mode 100644
index 0000000000..2b494e57cf
--- /dev/null
+++ b/rules/40-redhat.rules
@@ -0,0 +1,3 @@
+# do not edit this file, it will be overwritten on update
+
+SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
diff --git a/rules/meson.build b/rules/meson.build
index b6a32ba77e..e7e4362c0c 100644
--- a/rules/meson.build
+++ b/rules/meson.build
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: LGPL-2.1+
rules = files('''
+ 40-redhat.rules
60-block.rules
60-cdrom_id.rules
60-drm.rules

@ -1,24 +0,0 @@
From 07aa3fcbb7b4e4cca7b2e9be6e038ab92bfc5fdc Mon Sep 17 00:00:00 2001
From: Youfu Zhang <1315097+zhangyoufu@users.noreply.github.com>
Date: Tue, 1 Nov 2022 13:18:25 +0800
Subject: [PATCH] resolved: fix typo in feature level table
(cherry picked from commit 2ab0042854934827e61076c6e42c7381fdf78fdf)
Related #2138081
---
src/resolve/resolved-dns-server.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c
index 9b74a8d6d8..04a4f53ed0 100644
--- a/src/resolve/resolved-dns-server.c
+++ b/src/resolve/resolved-dns-server.c
@@ -1087,6 +1087,6 @@ static const char* const dns_server_feature_level_table[_DNS_SERVER_FEATURE_LEVE
[DNS_SERVER_FEATURE_LEVEL_EDNS0] = "UDP+EDNS0",
[DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN] = "TLS+EDNS0",
[DNS_SERVER_FEATURE_LEVEL_DO] = "UDP+EDNS0+DO",
- [DNS_SERVER_FEATURE_LEVEL_TLS_DO] = "TLS+EDNS0+D0",
+ [DNS_SERVER_FEATURE_LEVEL_TLS_DO] = "TLS+EDNS0+DO",
};
DEFINE_STRING_TABLE_LOOKUP(dns_server_feature_level, DnsServerFeatureLevel);

@ -0,0 +1,37 @@
From 2991b22f5f40a66ad1cc088e502e7f40ae1806c2 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 22 Sep 2014 07:53:52 +0200
Subject: [PATCH] rules: add rule for naming Dell iDRAC USB Virtual NIC as
'idrac'
Related: #1523227
---
rules/73-idrac.rules | 6 ++++++
rules/meson.build | 1 +
2 files changed, 7 insertions(+)
create mode 100644 rules/73-idrac.rules
diff --git a/rules/73-idrac.rules b/rules/73-idrac.rules
new file mode 100644
index 0000000000..d67fc425b1
--- /dev/null
+++ b/rules/73-idrac.rules
@@ -0,0 +1,6 @@
+# do not edit this file, it will be overwritten on update
+
+# On Dell PowerEdge systems, the iDRAC7 and later support a USB Virtual NIC
+# with terminates in the iDRAC. Help identify this with 'idrac'
+
+ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", ATTRS{idVendor}=="413c", ATTRS{idProduct}=="a102", NAME="idrac"
diff --git a/rules/meson.build b/rules/meson.build
index e7e4362c0c..e04a18aca6 100644
--- a/rules/meson.build
+++ b/rules/meson.build
@@ -17,6 +17,7 @@ rules = files('''
70-joystick.rules
70-mouse.rules
70-touchpad.rules
+ 73-idrac.rules
75-net-description.rules
75-probe_mtd.rules
78-sound-card.rules

@ -1,28 +0,0 @@
From a1f18876d5f7122c9f94af9a84f1324f50dba0ed Mon Sep 17 00:00:00 2001
From: Jan Janssen <medhefgo@web.de>
Date: Tue, 1 Nov 2022 09:43:32 +0100
Subject: [PATCH] coverage: Mark _coverage__exit as noreturn
../src/basic/coverage.h:15:48: warning: function '_coverage__exit' could
be declared with attribute 'noreturn' [-Wmissing-noreturn]
(cherry picked from commit 0bab5534b334677652bb69fe15eaa54ce84cbe7d)
Related #2138081
---
src/basic/coverage.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/basic/coverage.h b/src/basic/coverage.h
index 3ef02cf70e..640bddc485 100644
--- a/src/basic/coverage.h
+++ b/src/basic/coverage.h
@@ -12,7 +12,7 @@
extern void _exit(int);
extern void __gcov_dump(void);
-static inline void _coverage__exit(int status) {
+static inline _Noreturn void _coverage__exit(int status) {
__gcov_dump();
_exit(status);
}

@ -0,0 +1,22 @@
From d5215083fa1d10f1624ab2f0fb5ba420a2594938 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Wed, 13 May 2015 16:56:44 +0200
Subject: [PATCH] rules: enable memory hotplug
Related: #1523227
---
rules/40-redhat.rules | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 2b494e57cf..8231caae98 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -1,3 +1,7 @@
# do not edit this file, it will be overwritten on update
+# CPU hotadd request
SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
+
+# Memory hotadd request
+SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online"

@ -1,154 +0,0 @@
From 6ab61ac93e534aec1ea4d16e77c1c355c8286e64 Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
Date: Thu, 27 Oct 2022 13:14:12 +0200
Subject: [PATCH] namespace: Add hidepid/subset support check
Using fsopen()/fsconfig(), we can check if hidepid/subset are supported to
avoid the noisy logs from the kernel if they aren't supported. This works
on centos/redhat 8 as well since they've backported fsopen()/fsconfig().
(cherry picked from commit 1c265fcd5963603d338233840129ecad8d9c1420)
Related #2138081
---
meson.build | 2 ++
src/basic/missing_syscall.h | 40 +++++++++++++++++++++++++++++++
src/core/namespace.c | 47 ++++++++++++++++++++++++++++++++-----
3 files changed, 83 insertions(+), 6 deletions(-)
diff --git a/meson.build b/meson.build
index 76ad51d3fb..7750534466 100644
--- a/meson.build
+++ b/meson.build
@@ -606,6 +606,8 @@ foreach ident : [
['mount_setattr', '''#include <sys/mount.h>'''],
['move_mount', '''#include <sys/mount.h>'''],
['open_tree', '''#include <sys/mount.h>'''],
+ ['fsopen', '''#include <sys/mount.h>'''],
+ ['fsconfig', '''#include <sys/mount.h>'''],
['getdents64', '''#include <dirent.h>'''],
]
diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h
index 793d111c55..d54e59fdf9 100644
--- a/src/basic/missing_syscall.h
+++ b/src/basic/missing_syscall.h
@@ -593,6 +593,46 @@ static inline int missing_move_mount(
/* ======================================================================= */
+#if !HAVE_FSOPEN
+
+#ifndef FSOPEN_CLOEXEC
+#define FSOPEN_CLOEXEC 0x00000001
+#endif
+
+static inline int missing_fsopen(const char *fsname, unsigned flags) {
+# if defined __NR_fsopen && __NR_fsopen >= 0
+ return syscall(__NR_fsopen, fsname, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+
+# define fsopen missing_fsopen
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_FSCONFIG
+
+#ifndef FSCONFIG_SET_STRING
+#define FSCONFIG_SET_STRING 1 /* Set parameter, supplying a string value */
+#endif
+
+static inline int missing_fsconfig(int fd, unsigned cmd, const char *key, const void *value, int aux) {
+# if defined __NR_fsconfig && __NR_fsconfig >= 0
+ return syscall(__NR_fsconfig, fd, cmd, key, value, aux);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+
+# define fsconfig missing_fsconfig
+#endif
+
+/* ======================================================================= */
+
#if !HAVE_GETDENTS64
static inline ssize_t missing_getdents64(int fd, void *buffer, size_t length) {
diff --git a/src/core/namespace.c b/src/core/namespace.c
index c3cced7410..852be3bdde 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -26,6 +26,7 @@
#include "list.h"
#include "loop-util.h"
#include "loopback-setup.h"
+#include "missing_syscall.h"
#include "mkdir-label.h"
#include "mount-util.h"
#include "mountpoint-util.h"
@@ -1073,6 +1074,27 @@ static int mount_sysfs(const MountEntry *m) {
return 1;
}
+static bool mount_option_supported(const char *fstype, const char *key, const char *value) {
+ _cleanup_close_ int fd = -1;
+ int r;
+
+ /* This function assumes support by default. Only if the fsconfig() call fails with -EINVAL/-EOPNOTSUPP
+ * will it report that the option/value is not supported. */
+
+ fd = fsopen(fstype, FSOPEN_CLOEXEC);
+ if (fd < 0) {
+ if (errno != ENOSYS)
+ log_debug_errno(errno, "Failed to open superblock context for '%s': %m", fstype);
+ return true; /* If fsopen() fails for whatever reason, assume the value is supported. */
+ }
+
+ r = fsconfig(fd, FSCONFIG_SET_STRING, key, value, 0);
+ if (r < 0 && !IN_SET(errno, EINVAL, EOPNOTSUPP, ENOSYS))
+ log_debug_errno(errno, "Failed to set '%s=%s' on '%s' superblock context: %m", key, value, fstype);
+
+ return r >= 0 || !IN_SET(errno, EINVAL, EOPNOTSUPP);
+}
+
static int mount_procfs(const MountEntry *m, const NamespaceInfo *ns_info) {
_cleanup_free_ char *opts = NULL;
const char *entry_path;
@@ -1090,12 +1112,25 @@ static int mount_procfs(const MountEntry *m, const NamespaceInfo *ns_info) {
* per-instance, we'll exclusively use the textual value for hidepid=, since support was
* added in the same commit: if it's supported it is thus also per-instance. */
- opts = strjoin("hidepid=",
- ns_info->protect_proc == PROTECT_PROC_DEFAULT ? "off" :
- protect_proc_to_string(ns_info->protect_proc),
- ns_info->proc_subset == PROC_SUBSET_PID ? ",subset=pid" : "");
- if (!opts)
- return -ENOMEM;
+ const char *hpv = ns_info->protect_proc == PROTECT_PROC_DEFAULT ?
+ "off" :
+ protect_proc_to_string(ns_info->protect_proc);
+
+ /* hidepid= support was added in 5.8, so we can use fsconfig()/fsopen() (which were added in
+ * 5.2) to check if hidepid= is supported. This avoids a noisy dmesg log by the kernel when
+ * trying to use hidepid= on systems where it isn't supported. The same applies for subset=.
+ * fsopen()/fsconfig() was also backported on some distros which allows us to detect
+ * hidepid=/subset= support in even more scenarios. */
+
+ if (mount_option_supported("proc", "hidepid", hpv)) {
+ opts = strjoin("hidepid=", hpv);
+ if (!opts)
+ return -ENOMEM;
+ }
+
+ if (ns_info->proc_subset == PROC_SUBSET_PID && mount_option_supported("proc", "subset", "pid"))
+ if (!strextend_with_separator(&opts, ",", "subset=pid"))
+ return -ENOMEM;
}
entry_path = mount_entry_path(m);

@ -0,0 +1,22 @@
From 4a7602e27a50828ac8a0eb6b83a1c2c722af652d Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Wed, 13 May 2015 17:11:48 +0200
Subject: [PATCH] rules: reload sysctl settings when the bridge module is
loaded
Related: #1523227
---
rules/40-redhat.rules | 3 +++
1 file changed, 3 insertions(+)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 8231caae98..556a3a3a90 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -5,3 +5,6 @@ SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}
# Memory hotadd request
SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online"
+
+# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
+ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"

@ -0,0 +1,21 @@
From a42b57dc8b265f183a8fb6fe9ae32a9d77cbb7c5 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Wed, 20 May 2015 12:34:18 +0200
Subject: [PATCH] rules: load sg module
Related: #1523227
---
rules/40-redhat.rules | 3 +++
1 file changed, 3 insertions(+)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 556a3a3a90..305e752285 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -8,3 +8,6 @@ SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online"
# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"
+
+# load SCSI generic (sg) driver
+SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST!="[module/sg]", RUN+="/sbin/modprobe -bv sg"

@ -1,75 +0,0 @@
From 07f188e9ca17345af904e6549c03b1c57d34405a Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Tue, 1 Nov 2022 09:17:58 +0100
Subject: [PATCH] test: add a couple of sanity tests for loginctl
(cherry picked from commit 70e9066bc2eaf159e9cde7d95bbee99e44f3045a)
Related #2138081
---
test/units/testsuite-35.sh | 45 ++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/test/units/testsuite-35.sh b/test/units/testsuite-35.sh
index 4ef0f0c11c..85925f2471 100755
--- a/test/units/testsuite-35.sh
+++ b/test/units/testsuite-35.sh
@@ -338,6 +338,50 @@ EOF
assert_eq "$(loginctl --no-legend | awk '$3=="logind-test-user" { print $5 }')" "tty2"
}
+test_sanity_check() {
+ # Exercise basic loginctl options
+
+ if [[ ! -c /dev/tty2 ]]; then
+ echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}."
+ return
+ fi
+
+ trap cleanup_session RETURN
+ create_session
+
+ # Run most of the loginctl commands from a user session to make
+ # the seat/session autodetection work-ish
+ systemd-run --user --pipe --wait -M "logind-test-user@.host" bash -eux <<\EOF
+ loginctl list-sessions
+ loginctl session-status
+ loginctl show-session
+ loginctl show-session -P DelayInhibited
+
+ # We're not in the same session scope, so in this case we need to specify
+ # the session ID explicitly
+ session=$(loginctl --no-legend | awk '$3 == "logind-test-user" { print $1; exit; }')
+ loginctl kill-session --signal=SIGCONT "$session"
+ # FIXME(?)
+ #loginctl kill-session --signal=SIGCONT --kill-who=leader "$session"
+
+ loginctl list-users
+ loginctl user-status
+ loginctl show-user -a
+ loginctl show-user -P IdleAction
+ loginctl kill-user --signal=SIGCONT ""
+
+ loginctl list-seats
+ loginctl seat-status
+ loginctl show-seat
+ loginctl show-seat -P IdleActionUSec
+EOF
+
+ # Requires root privileges
+ loginctl lock-sessions
+ loginctl unlock-sessions
+ loginctl flush-devices
+}
+
test_session() {
local dev
@@ -537,6 +581,7 @@ test_properties
test_started
test_suspend_on_lid
test_shutdown
+test_sanity_check
test_session
test_lock_idle_action
test_session_properties

@ -0,0 +1,21 @@
From 21c96c3781f473cdbfe7acdb1affba75b50081f1 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Tue, 22 Sep 2015 12:28:28 +0200
Subject: [PATCH] rules: prandom character device node permissions
Related: #1523227
---
rules/40-redhat.rules | 3 +++
1 file changed, 3 insertions(+)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 305e752285..9a48adde19 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -11,3 +11,6 @@ ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/sys
# load SCSI generic (sg) driver
SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST!="[module/sg]", RUN+="/sbin/modprobe -bv sg"
+
+# Rule for prandom character device node permissions
+KERNEL=="prandom", MODE="0644"

@ -1,48 +0,0 @@
From 66a9a36c3bcd5709c30ac1f2be998eea034a9f6d Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Tue, 1 Nov 2022 17:53:42 +0100
Subject: [PATCH] test: rename TEST-26-SETENV to TEST-26-SYSTEMCTL
(cherry picked from commit c5c258ae0a4a0cfc829ed07ff96c7fab79b6ca71)
Related #2138081
---
test/{TEST-26-SETENV => TEST-26-SYSTEMCTL}/Makefile | 0
test/{TEST-26-SETENV => TEST-26-SYSTEMCTL}/test.sh | 2 +-
test/units/testsuite-26.service | 2 +-
3 files changed, 2 insertions(+), 2 deletions(-)
rename test/{TEST-26-SETENV => TEST-26-SYSTEMCTL}/Makefile (100%)
rename test/{TEST-26-SETENV => TEST-26-SYSTEMCTL}/test.sh (79%)
diff --git a/test/TEST-26-SETENV/Makefile b/test/TEST-26-SYSTEMCTL/Makefile
similarity index 100%
rename from test/TEST-26-SETENV/Makefile
rename to test/TEST-26-SYSTEMCTL/Makefile
diff --git a/test/TEST-26-SETENV/test.sh b/test/TEST-26-SYSTEMCTL/test.sh
similarity index 79%
rename from test/TEST-26-SETENV/test.sh
rename to test/TEST-26-SYSTEMCTL/test.sh
index b38e37bfce..64accf850f 100755
--- a/test/TEST-26-SETENV/test.sh
+++ b/test/TEST-26-SYSTEMCTL/test.sh
@@ -2,7 +2,7 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
-TEST_DESCRIPTION="test setenv"
+TEST_DESCRIPTION="systemctl-related tests"
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
diff --git a/test/units/testsuite-26.service b/test/units/testsuite-26.service
index aa553b61a6..d8fdaffb06 100644
--- a/test/units/testsuite-26.service
+++ b/test/units/testsuite-26.service
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Unit]
-Description=TEST-26-SETENV
+Description=TEST-26-SYSTEMCTL
[Service]
ExecStartPre=rm -f /failed /testok

@ -0,0 +1,22 @@
From fab2dff96f59e0851884b4ef32dccab763f5eef1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nykr=C3=BDn?= <lnykryn@redhat.com>
Date: Thu, 18 Aug 2016 14:51:19 +0200
Subject: [PATCH] rules: load sg driver also when scsi_target appears (#45)
Related: #1523227
---
rules/40-redhat.rules | 1 +
1 file changed, 1 insertion(+)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 9a48adde19..3335fe5075 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -11,6 +11,7 @@ ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/sys
# load SCSI generic (sg) driver
SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST!="[module/sg]", RUN+="/sbin/modprobe -bv sg"
+SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_target", TEST!="[module/sg]", RUN+="/sbin/modprobe -bv sg"
# Rule for prandom character device node permissions
KERNEL=="prandom", MODE="0644"

@ -1,251 +0,0 @@
From 680d2b33d3b2a0bed17c2c1594690155bdb910bb Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Tue, 1 Nov 2022 20:47:37 +0100
Subject: [PATCH] test: add a couple of sanity tests for systemctl
(cherry picked from commit d16684fe13e1d56e55df19b57b6c01b9a9303086)
Related #2138081
---
test/units/testsuite-26.sh | 209 +++++++++++++++++++++++++++++++++++--
1 file changed, 202 insertions(+), 7 deletions(-)
diff --git a/test/units/testsuite-26.sh b/test/units/testsuite-26.sh
index ad08415317..b83f85917b 100755
--- a/test/units/testsuite-26.sh
+++ b/test/units/testsuite-26.sh
@@ -3,32 +3,227 @@
set -eux
set -o pipefail
+at_exit() {
+ if [[ -v UNIT_NAME && -e "/usr/lib/systemd/system/$UNIT_NAME" ]]; then
+ rm -fv "/usr/lib/systemd/system/$UNIT_NAME"
+ fi
+}
+
+trap at_exit EXIT
+
+# Create a simple unit file for testing
+# Note: the service file is created under /usr on purpose to test
+# the 'revert' verb as well
+UNIT_NAME="systemctl-test-$RANDOM.service"
+cat >"/usr/lib/systemd/system/$UNIT_NAME" <<\EOF
+[Unit]
+Description=systemctl test
+
+[Service]
+ExecStart=sleep infinity
+ExecReload=true
+
+# For systemctl clean
+CacheDirectory=%n
+ConfigurationDirectory=%n
+LogsDirectory=%n
+RuntimeDirectory=%n
+StateDirectory=%n
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+# Configure the preset setting for the unit file
+mkdir /run/systemd/system-preset/
+echo "disable $UNIT_NAME" >/run/systemd/system-preset/99-systemd-test.preset
+
+systemctl daemon-reload
+
+# Argument help
+systemctl --state help
+systemctl --signal help
+systemctl --type help
+
+# list-dependencies
+systemctl list-dependencies systemd-journald
+systemctl list-dependencies --after systemd-journald
+systemctl list-dependencies --before systemd-journald
+systemctl list-dependencies --after --reverse systemd-journald
+systemctl list-dependencies --before --reverse systemd-journald
+systemctl list-dependencies --plain systemd-journald
+
+# list-* verbs
+systemctl list-units
+systemctl list-units --recursive
+systemctl list-units --type=socket
+systemctl list-units --type=service,timer
+systemctl list-units --legend=yes -a "systemd-*"
+systemctl list-units --state=active
+systemctl list-units --with-dependencies systemd-journald.service
+systemctl list-units --with-dependencies --after systemd-journald.service
+systemctl list-units --with-dependencies --before --reverse systemd-journald.service
+systemctl list-sockets
+systemctl list-sockets --legend=no -a "*journal*"
+systemctl list-sockets --show-types
+systemctl list-sockets --state=listening
+systemctl list-timers -a -l
+systemctl list-unit-files
+systemctl list-unit-files "*journal*"
+systemctl list-jobs
+systemctl list-jobs --after
+systemctl list-jobs --before
+systemctl list-jobs --after --before
+systemctl list-jobs "*"
+
+# Basic service management
+systemctl start --show-transaction "$UNIT_NAME"
+systemctl status -n 5 "$UNIT_NAME"
+systemctl is-active "$UNIT_NAME"
+systemctl reload -T "$UNIT_NAME"
+systemctl restart -T "$UNIT_NAME"
+systemctl try-restart --show-transaction "$UNIT_NAME"
+systemctl try-reload-or-restart --show-transaction "$UNIT_NAME"
+systemctl kill "$UNIT_NAME"
+(! systemctl is-active "$UNIT_NAME")
+systemctl restart "$UNIT_NAME"
+systemctl is-active "$UNIT_NAME"
+systemctl restart "$UNIT_NAME"
+systemctl stop "$UNIT_NAME"
+(! systemctl is-active "$UNIT_NAME")
+
+# enable/disable/preset
+(! systemctl is-enabled "$UNIT_NAME")
+systemctl enable "$UNIT_NAME"
+systemctl is-enabled -l "$UNIT_NAME"
+# We created a preset file for this unit above with a "disable" policy
+systemctl preset "$UNIT_NAME"
+(! systemctl is-enabled "$UNIT_NAME")
+systemctl reenable "$UNIT_NAME"
+systemctl is-enabled "$UNIT_NAME"
+systemctl preset --preset-mode=enable-only "$UNIT_NAME"
+systemctl is-enabled "$UNIT_NAME"
+systemctl preset --preset-mode=disable-only "$UNIT_NAME"
+(! systemctl is-enabled "$UNIT_NAME")
+systemctl enable --runtime "$UNIT_NAME"
+[[ -e "/run/systemd/system/multi-user.target.wants/$UNIT_NAME" ]]
+systemctl is-enabled "$UNIT_NAME"
+systemctl disable "$UNIT_NAME"
+# The unit should be still enabled, as we didn't use the --runtime switch
+systemctl is-enabled "$UNIT_NAME"
+systemctl disable --runtime "$UNIT_NAME"
+(! systemctl is-enabled "$UNIT_NAME")
+
+# mask/unmask/revert
+systemctl disable "$UNIT_NAME"
+[[ "$(systemctl is-enabled "$UNIT_NAME")" == disabled ]]
+systemctl mask "$UNIT_NAME"
+[[ "$(systemctl is-enabled "$UNIT_NAME")" == masked ]]
+systemctl unmask "$UNIT_NAME"
+[[ "$(systemctl is-enabled "$UNIT_NAME")" == disabled ]]
+systemctl mask "$UNIT_NAME"
+[[ "$(systemctl is-enabled "$UNIT_NAME")" == masked ]]
+systemctl revert "$UNIT_NAME"
+[[ "$(systemctl is-enabled "$UNIT_NAME")" == disabled ]]
+systemctl mask --runtime "$UNIT_NAME"
+[[ "$(systemctl is-enabled "$UNIT_NAME")" == masked-runtime ]]
+# This should be a no-op without the --runtime switch
+systemctl unmask "$UNIT_NAME"
+[[ "$(systemctl is-enabled "$UNIT_NAME")" == masked-runtime ]]
+systemctl unmask --runtime "$UNIT_NAME"
+[[ "$(systemctl is-enabled "$UNIT_NAME")" == disabled ]]
+
+# add-wants/add-requires
+(! systemctl show -P Wants "$UNIT_NAME" | grep "systemd-journald.service")
+systemctl add-wants "$UNIT_NAME" "systemd-journald.service"
+systemctl show -P Wants "$UNIT_NAME" | grep "systemd-journald.service"
+(! systemctl show -P Requires "$UNIT_NAME" | grep "systemd-journald.service")
+systemctl add-requires "$UNIT_NAME" "systemd-journald.service"
+systemctl show -P Requires "$UNIT_NAME" | grep "systemd-journald.service"
+
+# set-property
+systemctl set-property "$UNIT_NAME" IPAccounting=yes MemoryMax=1234567
+systemctl cat "$UNIT_NAME"
+# These properties should be saved to a persistent storage
+grep -r "IPAccounting=yes" "/etc/systemd/system.control/${UNIT_NAME}.d/"
+grep -r "MemoryMax=1234567" "/etc/systemd/system.control/${UNIT_NAME}.d"
+systemctl revert "$UNIT_NAME"
+(! grep -r "IPAccounting=" "/etc/systemd/system.control/${UNIT_NAME}.d/")
+(! grep -r "MemoryMax=" "/etc/systemd/system.control/${UNIT_NAME}.d/")
+# Same stuff, but with --runtime, which should use /run
+systemctl set-property --runtime "$UNIT_NAME" CPUAccounting=no CPUQuota=10%
+systemctl cat "$UNIT_NAME"
+grep -r "CPUAccounting=no" "/run/systemd/system.control/${UNIT_NAME}.d/"
+grep -r "CPUQuota=10%" "/run/systemd/system.control/${UNIT_NAME}.d/"
+systemctl revert "$UNIT_NAME"
+(! grep -r "CPUAccounting=" "/run/systemd/system.control/${UNIT_NAME}.d/")
+(! grep -r "CPUQuota=" "/run/systemd/system.control/${UNIT_NAME}.d/")
+
+# Failed-unit related tests
+systemd-run --unit "failed.service" /bin/false
+systemctl is-failed failed.service
+systemctl --state=failed | grep failed.service
+systemctl --failed | grep failed.service
+systemctl reset-failed "fail*.service"
+(! systemctl is-failed failed.service)
+
+# clean
+systemctl restart "$UNIT_NAME"
+systemctl stop "$UNIT_NAME"
+# Check if the directories from *Directory= directives exist
+# (except RuntimeDirectory= in /run, which is removed when the unit is stopped)
+for path in /var/lib /var/cache /var/log /etc; do
+ [[ -e "$path/$UNIT_NAME" ]]
+done
+# Run the cleanup
+for what in "" configuration state cache logs runtime all; do
+ systemctl clean ${what:+--what="$what"} "$UNIT_NAME"
+done
+# All respective directories should be removed
+for path in /run /var/lib /var/cache /var/log /etc; do
+ [[ ! -e "$path/$UNIT_NAME" ]]
+done
+
+# --timestamp
+for value in pretty us µs utc us+utc µs+utc; do
+ systemctl show -P KernelTimestamp --timestamp="$value"
+done
+
+# Aux verbs & assorted checks
+systemctl is-active "*-journald.service"
+systemctl cat "*journal*"
+systemctl cat "$UNIT_NAME"
+systemctl help "$UNIT_NAME"
+
+# show/set-environment
# Make sure PATH is set
systemctl show-environment | grep -q '^PATH='
-
# Let's add an entry and override a built-in one
systemctl set-environment PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/testaddition FOO=BAR
-
# Check that both are set
systemctl show-environment | grep -q '^PATH=.*testaddition$'
systemctl show-environment | grep -q '^FOO=BAR$'
-
systemctl daemon-reload
-
# Check again after the reload
systemctl show-environment | grep -q '^PATH=.*testaddition$'
systemctl show-environment | grep -q '^FOO=BAR$'
-
# Check that JSON output is supported
systemctl show-environment --output=json | grep -q '^{.*"FOO":"BAR".*}$'
-
# Drop both
systemctl unset-environment FOO PATH
-
# Check that one is gone and the other reverted to the built-in
systemctl show-environment | grep '^FOO=$' && exit 1
systemctl show-environment | grep '^PATH=.*testaddition$' && exit 1
systemctl show-environment | grep -q '^PATH='
+# Check import-environment
+export IMPORT_THIS=hello
+export IMPORT_THIS_TOO=world
+systemctl import-environment IMPORT_THIS IMPORT_THIS_TOO
+systemctl show-environment | grep "^IMPORT_THIS=$IMPORT_THIS"
+systemctl show-environment | grep "^IMPORT_THIS_TOO=$IMPORT_THIS_TOO"
+systemctl unset-environment IMPORT_THIS IMPORT_THIS_TOO
+(! systemctl show-environment | grep "^IMPORT_THIS=")
+(! systemctl show-environment | grep "^IMPORT_THIS_TOO=")
echo OK >/testok

@ -0,0 +1,23 @@
From fd091394e52cd652ff5163735b2a91a8c0efe415 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Tue, 13 Sep 2016 13:18:38 +0200
Subject: [PATCH] rules: don't hoplug memory on s390x
Related: #1523227
---
rules/40-redhat.rules | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 3335fe5075..4c56950dab 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -4,7 +4,7 @@
SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
# Memory hotadd request
-SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online"
+SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/usr/bin/systemd-detect-virt", RESULT!="zvm", ATTR{state}=="offline", ATTR{state}="online"
# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"

@ -1,49 +0,0 @@
From a9424191821c8c967edd7dd92a19d02ff5bbca87 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 2 Nov 2022 07:06:46 +0900
Subject: [PATCH] core: fix memleak in GetUnitFileLinks method
(cherry picked from commit a12ba535fa677e642c7ba19e81062ed6e9365ceb)
Related #2138081
---
src/core/dbus-manager.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 919aa58cde..88f098ec86 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -2647,21 +2647,27 @@ static int method_get_unit_file_links(sd_bus_message *message, void *userdata, s
(runtime ? UNIT_FILE_RUNTIME : 0);
r = unit_file_disable(LOOKUP_SCOPE_SYSTEM, flags, NULL, p, &changes, &n_changes);
- if (r < 0)
- return log_error_errno(r, "Failed to get file links for %s: %m", name);
+ if (r < 0) {
+ log_error_errno(r, "Failed to get file links for %s: %m", name);
+ goto finish;
+ }
for (i = 0; i < n_changes; i++)
if (changes[i].type == INSTALL_CHANGE_UNLINK) {
r = sd_bus_message_append(reply, "s", changes[i].path);
if (r < 0)
- return r;
+ goto finish;
}
r = sd_bus_message_close_container(reply);
if (r < 0)
- return r;
+ goto finish;
- return sd_bus_send(NULL, reply, NULL);
+ r = sd_bus_send(NULL, reply, NULL);
+
+finish:
+ install_changes_free(changes, n_changes);
+ return r;
}
static int method_get_job_waiting(sd_bus_message *message, void *userdata, sd_bus_error *error) {

@ -0,0 +1,24 @@
From a0802638f02b964cb9d2d68bad009561b2bcc910 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Fri, 16 Sep 2016 14:45:01 +0200
Subject: [PATCH] rules: disable auto-online of hot-plugged memory on IBM z
Systems
Related: #1523227
---
rules/40-redhat.rules | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 4c56950dab..c3df320234 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -4,7 +4,7 @@
SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
# Memory hotadd request
-SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/usr/bin/systemd-detect-virt", RESULT!="zvm", ATTR{state}=="offline", ATTR{state}="online"
+SUBSYSTEM=="memory", ACTION=="add", PROGRAM=="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online"
# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"

@ -1,42 +0,0 @@
From ada95dd4f4c0014815a2c3162de6297107569b05 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 2 Nov 2022 11:48:23 +0100
Subject: [PATCH] man: use the correct 'Markers' property name for marking
units
Follow-up to c9615f7352 and 70666e28a1.
(cherry picked from commit 1ca1bb03dec9ae3e8d734bd40eeb60210ffd7a0a)
Related #2138081
---
man/org.freedesktop.systemd1.xml | 2 +-
man/systemctl.xml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
index cbd552bd99..5e08b35234 100644
--- a/man/org.freedesktop.systemd1.xml
+++ b/man/org.freedesktop.systemd1.xml
@@ -1250,7 +1250,7 @@ node /org/freedesktop/systemd1 {
"ReloadOrRestart" flavors attempt a reload if the unit supports it and use a restart otherwise.</para>
<para><function>EnqueueMarkedJobs()</function> creates reload/restart jobs for units which have been
- appropriately marked, see <varname>Marks</varname> property above. This is equivalent to calling
+ appropriately marked, see <varname>Markers</varname> property above. This is equivalent to calling
<function>TryRestartUnit()</function> or <function>ReloadOrTryRestartUnit()</function> for the marked
units.</para>
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 4d4f6c3992..997925892d 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -2386,7 +2386,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<listitem><para>Only allowed with <command>reload-or-restart</command>. Enqueues restart jobs for all
units that have the <literal>needs-restart</literal> mark, and reload jobs for units that have the
<literal>needs-reload</literal> mark. When a unit marked for reload does not support reload, restart
- will be queued. Those properties can be set using <command>set-property Marks</command>.</para>
+ will be queued. Those properties can be set using <command>set-property Markers=…</command>.</para>
<para>Unless <option>--no-block</option> is used, <command>systemctl</command> will wait for the
queued jobs to finish.</para></listitem>

@ -0,0 +1,39 @@
From 0c5b8096cb23701f8048dba33a38e1b55249cab3 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Wed, 28 Mar 2018 17:22:30 +0200
Subject: [PATCH] rules: introduce old-style by-path symlinks for FCP based
SCSI devices
Related: #1523227
---
rules/40-redhat.rules | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index c3df320234..8ac96933c3 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -15,3 +15,23 @@ SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_target", TEST!="[module/sg]", RUN+="/sbin
# Rule for prandom character device node permissions
KERNEL=="prandom", MODE="0644"
+
+# Rules for creating the ID_PATH for SCSI devices based on the CCW bus
+# using the form: ccw-<BUS_ID>-zfcp-<WWPN>:<LUN>
+#
+ACTION=="remove", GOTO="zfcp_scsi_device_end"
+
+#
+# Set environment variable "ID_ZFCP_BUS" to "1" if the devices
+# (both disk and partition) are SCSI devices based on FCP devices
+#
+KERNEL=="sd*", SUBSYSTEMS=="ccw", DRIVERS=="zfcp", ENV{.ID_ZFCP_BUS}="1"
+
+# For SCSI disks
+KERNEL=="sd*[!0-9]", SUBSYSTEMS=="scsi", ENV{.ID_ZFCP_BUS}=="1", ENV{DEVTYPE}=="disk", SYMLINK+="disk/by-path/ccw-$attr{hba_id}-zfcp-$attr{wwpn}:$attr{fcp_lun}"
+
+
+# For partitions on a SCSI disk
+KERNEL=="sd*[0-9]", SUBSYSTEMS=="scsi", ENV{.ID_ZFCP_BUS}=="1", ENV{DEVTYPE}=="partition", SYMLINK+="disk/by-path/ccw-$attr{hba_id}-zfcp-$attr{wwpn}:$attr{fcp_lun}-part%n"
+
+LABEL="zfcp_scsi_device_end"

@ -0,0 +1,123 @@
From 1bb734a44952a51285057409ba7b1c3e7a162cea Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 2 Aug 2018 13:16:49 +0200
Subject: [PATCH] Revert "udev: remove WAIT_FOR key"
This reverts commit f2b8052fb648b788936dd3e85be6a9aca90fbb2f.
Resolves: #1523213
---
man/udev.xml | 9 +++++++
src/udev/udev-rules.c | 50 +++++++++++++++++++++++++++++++++++++++
test/rule-syntax-check.py | 2 +-
3 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/man/udev.xml b/man/udev.xml
index 15e6d8eae1..bdf901a8f0 100644
--- a/man/udev.xml
+++ b/man/udev.xml
@@ -515,6 +515,15 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>WAIT_FOR</varname></term>
+ <listitem>
+ <para>Wait for a file to become available or until a timeout of
+ 10 seconds expires. The path is relative to the sysfs device;
+ if no path is specified, this waits for an attribute to appear.</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>OPTIONS</varname></term>
<listitem>
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index f029395884..58af863f3d 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -676,6 +676,41 @@ static int import_parent_into_properties(struct udev_device *dev, const char *fi
return 0;
}
+#define WAIT_LOOP_PER_SECOND 50
+static int wait_for_file(struct udev_device *dev, const char *file, int timeout) {
+ char filepath[UTIL_PATH_SIZE];
+ char devicepath[UTIL_PATH_SIZE];
+ struct stat stats;
+ int loop = timeout * WAIT_LOOP_PER_SECOND;
+
+ /* a relative path is a device attribute */
+ devicepath[0] = '\0';
+ if (file[0] != '/') {
+ strscpyl(devicepath, sizeof(devicepath), udev_device_get_syspath(dev), NULL);
+ strscpyl(filepath, sizeof(filepath), devicepath, "/", file, NULL);
+ file = filepath;
+ }
+
+ while (--loop) {
+ const struct timespec duration = { 0, 1000 * 1000 * 1000 / WAIT_LOOP_PER_SECOND };
+
+ /* lookup file */
+ if (stat(file, &stats) == 0) {
+ log_debug("file '%s' appeared after %i loops", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1);
+ return 0;
+ }
+ /* make sure, the device did not disappear in the meantime */
+ if (devicepath[0] != '\0' && stat(devicepath, &stats) != 0) {
+ log_debug("device disappeared while waiting for '%s'", file);
+ return -2;
+ }
+ log_debug("wait for '%s' for %i mseconds", file, 1000 / WAIT_LOOP_PER_SECOND);
+ nanosleep(&duration, NULL);
+ }
+ log_debug("waiting for '%s' failed", file);
+ return -1;
+}
+
static void attr_subst_subdir(char *attr, size_t len) {
const char *pos, *tail, *path;
_cleanup_closedir_ DIR *dir = NULL;
@@ -1284,7 +1319,12 @@ static void add_rule(struct udev_rules *rules, char *line,
rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd);
} else
LOG_RULE_ERROR("ignoring unknown %s{} type '%s'", "RUN", attr);
+ } else if (streq(key, "WAIT_FOR") || streq(key, "WAIT_FOR_SYSFS")) {
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
+ rule_add_key(&rule_tmp, TK_M_WAITFOR, 0, value, NULL);
+ continue;
} else if (streq(key, "LABEL")) {
if (op == OP_REMOVE)
LOG_AND_RETURN("invalid %s operation", key);
@@ -1838,6 +1878,16 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
if (match_key(rules, cur, udev_device_get_driver(event->dev)) != 0)
goto nomatch;
break;
+ case TK_M_WAITFOR: {
+ char filename[UTIL_PATH_SIZE];
+ int found;
+
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename), false);
+ found = (wait_for_file(event->dev, filename, 10) == 0);
+ if (!found && (cur->key.op != OP_NOMATCH))
+ goto nomatch;
+ break;
+ }
case TK_M_ATTR:
if (match_attr(rules, event->dev, event, cur) != 0)
goto nomatch;
diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py
index dfb06d9ed9..706d93632e 100755
--- a/test/rule-syntax-check.py
+++ b/test/rule-syntax-check.py
@@ -18,7 +18,7 @@ if not rules_files:
quoted_string_re = r'"(?:[^\\"]|\\.)*"'
no_args_tests = re.compile(r'(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|PROGRAM|RESULT|TEST)\s*(?:=|!)=\s*' + quoted_string_re + '$')
args_tests = re.compile(r'(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$')
-no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$')
+no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$')
args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*' + quoted_string_re + '$')
# Find comma-separated groups, but allow commas that are inside quoted strings.
# Using quoted_string_re + '?' so that strings missing the last double quote

@ -1,115 +0,0 @@
From cce2e337e37524df5ff81e758dbcfa91bf8b696a Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 2 Nov 2022 11:44:00 +0100
Subject: [PATCH] test: further extend systemctl's sanity coverage
Also, fix a race condition introduced by d16684fe13:
```
[ 16.904218] H testsuite-26.sh[394]: + systemd-run --unit failed.service /bin/false
[ 16.964783] H systemd[845]: failed.service: Executing: /bin/false
[ 16.965062] H systemd[1]: Started failed.service.
[ 16.965462] H testsuite-26.sh[844]: Running as unit: failed.service
[ 16.966390] H testsuite-26.sh[394]: + systemctl is-failed failed.service
[ 16.977970] H testsuite-26.sh[846]: active
[ 16.978403] H systemd[1]: failed.service: Main process exited, code=exited, status=1/FAILURE
[ 16.978478] H systemd[1]: failed.service: Failed with result 'exit-code'.
```
(cherry picked from commit 23f3a6f5ff864fd26063c6c35fdaa6d85de566c7)
Related #2138081
---
test/units/testsuite-26.sh | 61 +++++++++++++++++++++++++++++++++++++-
1 file changed, 60 insertions(+), 1 deletion(-)
diff --git a/test/units/testsuite-26.sh b/test/units/testsuite-26.sh
index b83f85917b..7c7a12b1ae 100755
--- a/test/units/testsuite-26.sh
+++ b/test/units/testsuite-26.sh
@@ -58,6 +58,9 @@ systemctl list-units
systemctl list-units --recursive
systemctl list-units --type=socket
systemctl list-units --type=service,timer
+# Compat: --type= allows load states for compatibility reasons
+systemctl list-units --type=loaded
+systemctl list-units --type=loaded,socket
systemctl list-units --legend=yes -a "systemd-*"
systemctl list-units --state=active
systemctl list-units --with-dependencies systemd-journald.service
@@ -160,7 +163,7 @@ systemctl revert "$UNIT_NAME"
(! grep -r "CPUQuota=" "/run/systemd/system.control/${UNIT_NAME}.d/")
# Failed-unit related tests
-systemd-run --unit "failed.service" /bin/false
+(! systemd-run --wait --unit "failed.service" /bin/false)
systemctl is-failed failed.service
systemctl --state=failed | grep failed.service
systemctl --failed | grep failed.service
@@ -189,11 +192,67 @@ for value in pretty us µs utc us+utc µs+utc; do
systemctl show -P KernelTimestamp --timestamp="$value"
done
+# set-default/get-default
+target="$(systemctl get-default)"
+systemctl set-default emergency.target
+[[ "$(systemctl get-default)" == emergency.target ]]
+systemctl set-default "$target"
+[[ "$(systemctl get-default)" == "$target" ]]
+
+# show/status
+systemctl show --property ""
+# Pick a heavily sandboxed unit for the best effect on coverage
+systemctl show systemd-logind.service
+systemctl status
+# Ignore the exit code in this case, as it might try to load non-existing units
+systemctl status -a >/dev/null || :
+systemctl status -a --state active,running,plugged >/dev/null
+systemctl status "systemd-*.timer"
+systemctl status "systemd-journald*.socket"
+systemctl status "sys-devices-*-ttyS0.device"
+systemctl status -- -.mount
+
+# --marked
+systemctl restart "$UNIT_NAME"
+systemctl set-property "$UNIT_NAME" Markers=needs-restart
+systemctl show -P Markers "$UNIT_NAME" | grep needs-restart
+systemctl reload-or-restart --marked
+(! systemctl show -P Markers "$UNIT_NAME" | grep needs-restart)
+
+# --dry-run with destructive verbs
+# kexec is skipped intentionally, as it requires a bit more involved setup
+VERBS=(
+ default
+ emergency
+ exit
+ halt
+ hibernate
+ hybrid-sleep
+ poweroff
+ reboot
+ rescue
+ suspend
+ suspend-then-hibernate
+)
+
+for verb in "${VERBS[@]}"; do
+ systemctl --dry-run "$verb"
+
+ if [[ "$verb" =~ (halt|poweroff|reboot) ]]; then
+ systemctl --dry-run --message "Hello world" "$verb"
+ systemctl --dry-run --no-wall "$verb"
+ systemctl --dry-run -f "$verb"
+ systemctl --dry-run -ff "$verb"
+ fi
+done
+
# Aux verbs & assorted checks
systemctl is-active "*-journald.service"
systemctl cat "*journal*"
systemctl cat "$UNIT_NAME"
systemctl help "$UNIT_NAME"
+systemctl service-watchdogs
+systemctl service-watchdogs "$(systemctl service-watchdogs)"
# show/set-environment
# Make sure PATH is set

@ -0,0 +1,22 @@
From ab0228c3d6ceba20cf89ceb1b16b7e314aaaf989 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Tue, 7 Aug 2018 10:38:33 +0200
Subject: [PATCH] net_setup_link: allow renaming interfaces that were renamed
previously
---
src/udev/net/link-config.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index cec4f4f779..5113586457 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -306,7 +306,6 @@ static bool should_rename(struct udev_device *device, bool respect_predictable)
switch (type) {
case NET_NAME_USER:
- case NET_NAME_RENAMED:
/* these were already named by userspace, do not touch again */
return false;
case NET_NAME_PREDICTABLE:

@ -1,131 +0,0 @@
From d68d785ba0e3ecd59a2678fe00fbd7b1bde90622 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 2 Nov 2022 17:51:51 +0100
Subject: [PATCH] test: add a sanity coverage for systemd-analyze verbs
(cherry picked from commit 6c83054c0133eb53245e479d71589dceff76cf74)
Related #2138081
---
test/units/testsuite-65.sh | 108 +++++++++++++++++++++++++++++++++++++
1 file changed, 108 insertions(+)
diff --git a/test/units/testsuite-65.sh b/test/units/testsuite-65.sh
index 64ce629f3b..ece6b8734e 100755
--- a/test/units/testsuite-65.sh
+++ b/test/units/testsuite-65.sh
@@ -9,6 +9,114 @@ set -eux
systemd-analyze log-level debug
export SYSTEMD_LOG_LEVEL=debug
+# Sanity checks
+#
+# We can't really test time, blame, critical-chain and plot verbs here, as
+# the testsuite service is a part of the boot transaction, so let's assume
+# they fail
+systemd-analyze || :
+systemd-analyze time || :
+systemd-analyze blame || :
+systemd-analyze critical-chain || :
+systemd-analyze plot >/dev/null || :
+# dot
+systemd-analyze dot >/dev/null
+systemd-analyze dot systemd-journald.service >/dev/null
+systemd-analyze dot systemd-journald.service systemd-logind.service >/dev/null
+systemd-analyze dot --from-pattern="*" --from-pattern="*.service" systemd-journald.service >/dev/null
+systemd-analyze dot --to-pattern="*" --to-pattern="*.service" systemd-journald.service >/dev/null
+systemd-analyze dot --from-pattern="*.service" --to-pattern="*.service" systemd-journald.service >/dev/null
+systemd-analyze dot --order systemd-journald.service systemd-logind.service >/dev/null
+systemd-analyze dot --require systemd-journald.service systemd-logind.service >/dev/null
+systemd-analyze dot "systemd-*.service" >/dev/null
+(! systemd-analyze dot systemd-journald.service systemd-logind.service "*" bbb ccc)
+# dump
+systemd-analyze dump >/dev/null
+systemd-analyze dump "*" >/dev/null
+systemd-analyze dump "*.socket" >/dev/null
+systemd-analyze dump systemd-journald.service >/dev/null
+(! systemd-analyze dump "")
+# unit-paths
+systemd-analyze unit-paths
+systemd-analyze unit-paths --user
+systemd-analyze unit-paths --global
+# exist-status
+systemd-analyze exit-status
+systemd-analyze exit-status STDOUT BPF
+systemd-analyze exit-status 0 1 {63..65}
+(! systemd-analyze exit-status STDOUT BPF "hello*")
+# capability
+systemd-analyze capability
+systemd-analyze capability cap_chown CAP_KILL
+systemd-analyze capability 0 1 {30..32}
+(! systemd-analyze capability cap_chown CAP_KILL "hello*")
+# condition
+mkdir -p /run/systemd/system
+UNIT_NAME="analyze-condition-$RANDOM.service"
+cat >"/run/systemd/system/$UNIT_NAME" <<EOF
+[Unit]
+AssertPathExists=/etc/os-release
+AssertEnvironment=!FOOBAR
+ConditionKernelVersion=>1.0
+ConditionPathExists=/etc/os-release
+
+[Service]
+ExecStart=/bin/true
+EOF
+systemctl daemon-reload
+systemd-analyze condition --unit="$UNIT_NAME"
+systemd-analyze condition 'ConditionKernelVersion = ! <4.0' \
+ 'ConditionKernelVersion = >=3.1' \
+ 'ConditionACPower=|false' \
+ 'ConditionArchitecture=|!arm' \
+ 'AssertPathExists=/etc/os-release'
+(! systemd-analyze condition 'ConditionArchitecture=|!arm' 'AssertXYZ=foo')
+(! systemd-analyze condition 'ConditionKernelVersion=<1.0')
+(! systemd-analyze condition 'AssertKernelVersion=<1.0')
+# syscall-filter
+systemd-analyze syscall-filter >/dev/null
+systemd-analyze syscall-filter @chown @sync
+systemd-analyze syscall-filter @sync @sync @sync
+(! systemd-analyze syscall-filter @chown @sync @foobar)
+# filesystems (requires libbpf support)
+if systemctl --version | grep "+BPF_FRAMEWORK"; then
+ systemd-analyze filesystems >/dev/null
+ systemd-analyze filesystems @basic-api
+ systemd-analyze filesystems @basic-api @basic-api @basic-api
+ (! systemd-analyze filesystems @basic-api @basic-api @foobar @basic-api)
+fi
+# calendar
+systemd-analyze calendar '*-2-29 0:0:0'
+systemd-analyze calendar --iterations=5 '*-2-29 0:0:0'
+systemd-analyze calendar '*-* *:*:*'
+systemd-analyze calendar --iterations=5 '*-* *:*:*'
+systemd-analyze calendar --iterations=50 '*-* *:*:*'
+systemd-analyze calendar --iterations=0 '*-* *:*:*'
+systemd-analyze calendar --base-time=yesterday --iterations=5 '*-* *:*:*'
+(! systemd-analyze calendar --iterations=0 '*-* 99:*:*')
+(! systemd-analyze calendar --base-time=never '*-* *:*:*')
+(! systemd-analyze calendar 1)
+(! systemd-analyze calendar "")
+# timestamp
+systemd-analyze timestamp now
+systemd-analyze timestamp -- -1
+systemd-analyze timestamp yesterday now tomorrow
+(! systemd-analyze timestamp yesterday never tomorrow)
+(! systemd-analyze timestamp 1)
+(! systemd-analyze timestamp "")
+# timespan
+systemd-analyze timespan 1
+systemd-analyze timespan 1s 300s '1year 0.000001s'
+(! systemd-analyze timespan 1s 300s aaaaaa '1year 0.000001s')
+(! systemd-analyze timespan -- -1)
+(! systemd-analyze timespan "")
+# cat-config
+systemd-analyze cat-config systemd/system.conf >/dev/null
+systemd-analyze cat-config /etc/systemd/system.conf >/dev/null
+systemd-analyze cat-config systemd/system.conf systemd/journald.conf >/dev/null
+systemd-analyze cat-config systemd/system.conf foo/bar systemd/journald.conf >/dev/null
+systemd-analyze cat-config foo/bar
+
mkdir -p /tmp/img/usr/lib/systemd/system/
mkdir -p /tmp/img/opt/

@ -1,37 +0,0 @@
From 080747ee6685b9c5877073c5120375e7a04d8216 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 3 Nov 2022 09:39:36 +0900
Subject: [PATCH] udev: first set properties based on usb subsystem
After 479da1107a0d4e2f7ef5cd938512b87a0e45f180, the usb_id builtin
command does not set ID_SERIAL if ID_BUS is already set.
Before the commit, all properties set based on pci bus were overwritten
by the usb_id, hence now it is sufficient setting them only when ID_BUS is
not set yet.
Fixes #25238.
(cherry picked from commit 01e704eba982fbc1517287cd261d229ff8e0a779)
Related #2138081
---
rules.d/60-serial.rules | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/rules.d/60-serial.rules b/rules.d/60-serial.rules
index f303e27fd5..c133f26109 100644
--- a/rules.d/60-serial.rules
+++ b/rules.d/60-serial.rules
@@ -3,9 +3,10 @@
ACTION=="remove", GOTO="serial_end"
SUBSYSTEM!="tty", GOTO="serial_end"
-SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
-SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci"
SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
+SUBSYSTEMS=="pci", ENV{ID_BUS}=="", ENV{ID_BUS}="pci", \
+ ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}", \
+ IMPORT{builtin}="hwdb --subsystem=pci"
# /dev/serial/by-path/, /dev/serial/by-id/ for USB devices
KERNEL!="ttyUSB[0-9]*|ttyACM[0-9]*", GOTO="serial_end"

@ -0,0 +1,23 @@
From b61e8046ebcb28225423fc0073183d68d4c577c4 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 9 Aug 2018 15:28:44 +0200
Subject: [PATCH] units: drop DynamicUser=yes from systemd-resolved.service
We don't really need DynamicUser since we add systemd-resolve user
from rpm script
---
units/systemd-resolved.service.in | 1 -
1 file changed, 1 deletion(-)
diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in
index 9982ecebff..aaed406ab2 100644
--- a/units/systemd-resolved.service.in
+++ b/units/systemd-resolved.service.in
@@ -26,7 +26,6 @@ RestartSec=0
ExecStart=!!@rootlibexecdir@/systemd-resolved
WatchdogSec=3min
User=systemd-resolve
-DynamicUser=yes
CapabilityBoundingSet=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE
PrivateDevices=yes

@ -0,0 +1,73 @@
From 8618ef2fb30b4139c9bec4e45fb499cd8192a87f Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 9 Aug 2018 23:23:00 +0200
Subject: [PATCH] journal: remove journal audit socket
Resolves: #1614554
---
units/meson.build | 2 --
units/systemd-journald-audit.socket | 22 ----------------------
units/systemd-journald.service.in | 4 ++--
3 files changed, 2 insertions(+), 26 deletions(-)
delete mode 100644 units/systemd-journald-audit.socket
diff --git a/units/meson.build b/units/meson.build
index e4ac6ced64..e54a84ccbf 100644
--- a/units/meson.build
+++ b/units/meson.build
@@ -89,8 +89,6 @@ units = [
'sockets.target.wants/'],
['systemd-journal-gatewayd.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'],
['systemd-journal-remote.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'],
- ['systemd-journald-audit.socket', '',
- 'sockets.target.wants/'],
['systemd-journald-dev-log.socket', '',
'sockets.target.wants/'],
['systemd-journald.socket', '',
diff --git a/units/systemd-journald-audit.socket b/units/systemd-journald-audit.socket
deleted file mode 100644
index cb8b774963..0000000000
--- a/units/systemd-journald-audit.socket
+++ /dev/null
@@ -1,22 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1+
-#
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-[Unit]
-Description=Journal Audit Socket
-Documentation=man:systemd-journald.service(8) man:journald.conf(5)
-DefaultDependencies=no
-Before=sockets.target
-ConditionSecurity=audit
-ConditionCapability=CAP_AUDIT_READ
-
-[Socket]
-Service=systemd-journald.service
-ReceiveBuffer=128M
-ListenNetlink=audit 1
-PassCredentials=yes
diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
index 52939e6820..8f5021d0de 100644
--- a/units/systemd-journald.service.in
+++ b/units/systemd-journald.service.in
@@ -12,12 +12,12 @@ Description=Journal Service
Documentation=man:systemd-journald.service(8) man:journald.conf(5)
DefaultDependencies=no
Requires=systemd-journald.socket
-After=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket syslog.socket
+After=systemd-journald.socket systemd-journald-dev-log.socket syslog.socket
Before=sysinit.target
[Service]
Type=notify
-Sockets=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket
+Sockets=systemd-journald.socket systemd-journald-dev-log.socket
ExecStart=@rootlibexecdir@/systemd-journald
Restart=always
RestartSec=0

@ -1,30 +0,0 @@
From 35ec16bfef92d072edacad892fc138b3595ee69b Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 3 Nov 2022 09:43:14 +0900
Subject: [PATCH] udev: drop redundant call of usb_id and assignment of
ID_USB_INTERFACE_NUM
The usb_id builtin command is already called in the above, and the
command sets the ID_USB_INTERFACE_NUM property.
(cherry picked from commit b2e53f5a0f12db65c88404477fedee5c57d201ba)
Related #2138081
---
rules.d/60-serial.rules | 2 --
1 file changed, 2 deletions(-)
diff --git a/rules.d/60-serial.rules b/rules.d/60-serial.rules
index c133f26109..2c1488e930 100644
--- a/rules.d/60-serial.rules
+++ b/rules.d/60-serial.rules
@@ -17,9 +17,7 @@ IMPORT{builtin}="path_id"
ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="", SYMLINK+="serial/by-path/$env{ID_PATH}"
ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-path/$env{ID_PATH}-port$env{.ID_PORT}"
-IMPORT{builtin}="usb_id"
ENV{ID_SERIAL}=="", GOTO="serial_end"
-SUBSYSTEMS=="usb", ENV{ID_USB_INTERFACE_NUM}="$attr{bInterfaceNumber}"
ENV{ID_USB_INTERFACE_NUM}=="", GOTO="serial_end"
ENV{.ID_PORT}=="", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}"
ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}-port$env{.ID_PORT}"

@ -0,0 +1,117 @@
From c6903d1b42d1773fda4df6676618489ad760a2a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 18 Jul 2018 12:16:33 +0200
Subject: [PATCH] bus: move BUS_DONT_DESTROY calls after asserts
It's not useful to bump the reference count before checking if the object is
NULL. Thanks to d40f5cc498 we can do this ;).
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1576084,
https://bugzilla.redhat.com/show_bug.cgi?id=1575340,
https://bugzilla.redhat.com/show_bug.cgi?id=1575350. I'm not sure why those two
people hit this code path, while most people don't. At least we won't abort.
(cherry picked from commit 7ae8edcd03f74da123298330b76c3fc5425042ef)
Resolves: #1610397
---
src/libsystemd/sd-bus/bus-objects.c | 15 ++++++++-------
src/libsystemd/sd-bus/sd-bus.c | 3 ++-
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c
index 9609834fa9..a18ff88b07 100644
--- a/src/libsystemd/sd-bus/bus-objects.c
+++ b/src/libsystemd/sd-bus/bus-objects.c
@@ -2090,7 +2090,6 @@ _public_ int sd_bus_emit_properties_changed_strv(
const char *interface,
char **names) {
- BUS_DONT_DESTROY(bus);
bool found_interface = false;
char *prefix;
int r;
@@ -2111,6 +2110,8 @@ _public_ int sd_bus_emit_properties_changed_strv(
if (names && names[0] == NULL)
return 0;
+ BUS_DONT_DESTROY(bus);
+
do {
bus->nodes_modified = false;
@@ -2310,8 +2311,6 @@ static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *p
}
_public_ int sd_bus_emit_object_added(sd_bus *bus, const char *path) {
- BUS_DONT_DESTROY(bus);
-
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
struct node *object_manager;
int r;
@@ -2341,6 +2340,8 @@ _public_ int sd_bus_emit_object_added(sd_bus *bus, const char *path) {
if (r == 0)
return -ESRCH;
+ BUS_DONT_DESTROY(bus);
+
do {
bus->nodes_modified = false;
m = sd_bus_message_unref(m);
@@ -2481,8 +2482,6 @@ static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char
}
_public_ int sd_bus_emit_object_removed(sd_bus *bus, const char *path) {
- BUS_DONT_DESTROY(bus);
-
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
struct node *object_manager;
int r;
@@ -2512,6 +2511,8 @@ _public_ int sd_bus_emit_object_removed(sd_bus *bus, const char *path) {
if (r == 0)
return -ESRCH;
+ BUS_DONT_DESTROY(bus);
+
do {
bus->nodes_modified = false;
m = sd_bus_message_unref(m);
@@ -2645,8 +2646,6 @@ static int interfaces_added_append_one(
}
_public_ int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, char **interfaces) {
- BUS_DONT_DESTROY(bus);
-
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
struct node *object_manager;
char **i;
@@ -2669,6 +2668,8 @@ _public_ int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, ch
if (r == 0)
return -ESRCH;
+ BUS_DONT_DESTROY(bus);
+
do {
bus->nodes_modified = false;
m = sd_bus_message_unref(m);
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 089b51a6d9..7f03528b89 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -2883,7 +2883,6 @@ finish:
}
static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
- BUS_DONT_DESTROY(bus);
int r;
/* Returns 0 when we didn't do anything. This should cause the
@@ -2899,6 +2898,8 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit
assert_return(!bus->current_message, -EBUSY);
assert(!bus->current_slot);
+ BUS_DONT_DESTROY(bus);
+
switch (bus->state) {
case BUS_UNSET:

@ -1,26 +0,0 @@
From 03bb31bbb875e20da7ae37eb44e98d244823e0e7 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 3 Nov 2022 09:52:23 +0900
Subject: [PATCH] udev: add safe guard for setting by-id symlink
The ID_BUS property is necessary for creating by-id symlinks.
(cherry picked from commit 5286da064c97d2ac934cb301066aaa8605a3c8f9)
Related #2138081
---
rules.d/60-serial.rules | 1 +
1 file changed, 1 insertion(+)
diff --git a/rules.d/60-serial.rules b/rules.d/60-serial.rules
index 2c1488e930..a0e66323a9 100644
--- a/rules.d/60-serial.rules
+++ b/rules.d/60-serial.rules
@@ -17,6 +17,7 @@ IMPORT{builtin}="path_id"
ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="", SYMLINK+="serial/by-path/$env{ID_PATH}"
ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-path/$env{ID_PATH}-port$env{.ID_PORT}"
+ENV{ID_BUS}=="", GOTO="serial_end"
ENV{ID_SERIAL}=="", GOTO="serial_end"
ENV{ID_USB_INTERFACE_NUM}=="", GOTO="serial_end"
ENV{.ID_PORT}=="", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}"

@ -0,0 +1,23 @@
From 56f614a5d6305dc1d304c30438db5b394d16e2da Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Fri, 12 Oct 2018 13:58:34 +0000
Subject: [PATCH] random-seed: raise POOL_SIZE_MIN constant to 1024
Resolves: #1619268
---
src/random-seed/random-seed.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c
index 223b56306c..adc9f298c1 100644
--- a/src/random-seed/random-seed.c
+++ b/src/random-seed/random-seed.c
@@ -14,7 +14,7 @@
#include "string-util.h"
#include "util.h"
-#define POOL_SIZE_MIN 512
+#define POOL_SIZE_MIN 1024
int main(int argc, char *argv[]) {
_cleanup_close_ int seed_fd = -1, random_fd = -1;

@ -1,45 +0,0 @@
From 266baa71dbb336d9c2eb1e4e7db3983477cc6ce0 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Thu, 3 Nov 2022 10:59:38 +0100
Subject: [PATCH] test: cover legacy/deprecated systemd-analyze verbs
They're no longer documented since 26e1e97345 but still work.
(cherry picked from commit 926d95cd4c209b8c292829511542b11d7c43e662)
Related #2138081
---
test/units/testsuite-65.sh | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/test/units/testsuite-65.sh b/test/units/testsuite-65.sh
index ece6b8734e..89406a108e 100755
--- a/test/units/testsuite-65.sh
+++ b/test/units/testsuite-65.sh
@@ -6,7 +6,7 @@ set -eux
# shellcheck source=test/units/assert.sh
. "$(dirname "$0")"/assert.sh
-systemd-analyze log-level debug
+systemctl log-level debug
export SYSTEMD_LOG_LEVEL=debug
# Sanity checks
@@ -19,6 +19,17 @@ systemd-analyze time || :
systemd-analyze blame || :
systemd-analyze critical-chain || :
systemd-analyze plot >/dev/null || :
+# legacy/deprecated options (moved to systemctl, but still usable from analyze)
+systemd-analyze log-level
+systemd-analyze log-level "$(systemctl log-level)"
+systemd-analyze get-log-level
+systemd-analyze set-log-level "$(systemctl log-level)"
+systemd-analyze log-target
+systemd-analyze log-target "$(systemctl log-target)"
+systemd-analyze get-log-target
+systemd-analyze set-log-target "$(systemctl log-target)"
+systemd-analyze service-watchdogs
+systemd-analyze service-watchdogs "$(systemctl service-watchdogs)"
# dot
systemd-analyze dot >/dev/null
systemd-analyze dot systemd-journald.service >/dev/null

@ -0,0 +1,119 @@
From a046230cfb7e02938e3ad2ac85515636b319651e Mon Sep 17 00:00:00 2001
From: Dimitri John Ledkov <xnox@ubuntu.com>
Date: Wed, 29 Aug 2018 15:38:09 +0100
Subject: [PATCH] cryptsetup: add support for sector-size= option (#9936)
Bug-Ubuntu: https://launchpad.net/bugs/1776626
Closes #8881.
(cherry picked from commit a9fc640671ef60ac949f1ace6fa687ff242fc233)
Resolves: #1572563
---
man/crypttab.xml | 9 +++++++++
meson.build | 6 ++++++
src/cryptsetup/cryptsetup.c | 30 ++++++++++++++++++++++++++++++
3 files changed, 45 insertions(+)
diff --git a/man/crypttab.xml b/man/crypttab.xml
index dcaf03d2ca..3574ce00da 100644
--- a/man/crypttab.xml
+++ b/man/crypttab.xml
@@ -250,6 +250,15 @@
option.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>sector-size=</option></term>
+
+ <listitem><para>Specifies the sector size in bytes. See
+ <citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ for possible values and the default value of this
+ option.</para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>swap</option></term>
diff --git a/meson.build b/meson.build
index a0e7240708..f308db2631 100644
--- a/meson.build
+++ b/meson.build
@@ -927,11 +927,17 @@ if want_libcryptsetup != 'false' and not fuzzer_build
version : '>= 1.6.0',
required : want_libcryptsetup == 'true')
have = libcryptsetup.found()
+ have_sector = cc.has_member(
+ 'struct crypt_params_plain',
+ 'sector_size',
+ prefix : '#include <libcryptsetup.h>')
else
have = false
+ have_sector = false
libcryptsetup = []
endif
conf.set10('HAVE_LIBCRYPTSETUP', have)
+conf.set10('HAVE_LIBCRYPTSETUP_SECTOR_SIZE', have_sector)
want_libcurl = get_option('libcurl')
if want_libcurl != 'false' and not fuzzer_build
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 832168184a..87008cb969 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -23,10 +23,14 @@
/* internal helper */
#define ANY_LUKS "LUKS"
+/* as in src/cryptsetup.h */
+#define CRYPT_SECTOR_SIZE 512
+#define CRYPT_MAX_SECTOR_SIZE 4096
static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */
static char *arg_cipher = NULL;
static unsigned arg_key_size = 0;
+static unsigned arg_sector_size = CRYPT_SECTOR_SIZE;
static int arg_key_slot = CRYPT_ANY_SLOT;
static unsigned arg_keyfile_size = 0;
static uint64_t arg_keyfile_offset = 0;
@@ -86,6 +90,29 @@ static int parse_one_option(const char *option) {
arg_key_size /= 8;
+ } else if ((val = startswith(option, "sector-size="))) {
+
+#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE
+ r = safe_atou(val, &arg_sector_size);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
+ return 0;
+ }
+
+ if (arg_sector_size % 2) {
+ log_error("sector-size= not a multiple of 2, ignoring.");
+ return 0;
+ }
+
+ if (arg_sector_size < CRYPT_SECTOR_SIZE || arg_sector_size > CRYPT_MAX_SECTOR_SIZE) {
+ log_error("sector-size= is outside of %u and %u, ignoring.", CRYPT_SECTOR_SIZE, CRYPT_MAX_SECTOR_SIZE);
+ return 0;
+ }
+#else
+ log_error("sector-size= is not supported, compiled with old libcryptsetup.");
+ return 0;
+#endif
+
} else if ((val = startswith(option, "key-slot="))) {
arg_type = ANY_LUKS;
@@ -471,6 +498,9 @@ static int attach_luks_or_plain(struct crypt_device *cd,
struct crypt_params_plain params = {
.offset = arg_offset,
.skip = arg_skip,
+#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE
+ .sector_size = arg_sector_size,
+#endif
};
const char *cipher, *cipher_mode;
_cleanup_free_ char *truncated_cipher = NULL;

@ -1,56 +0,0 @@
From 37614533602981aa3757cd3e847f184fdae1432e Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Thu, 3 Nov 2022 11:33:13 +0100
Subject: [PATCH] test: cover a couple of previously missed analyze code paths
(cherry picked from commit 8b1879bcd0ed1168f5ad35a3dd0e213a31a2ee42)
Related #2138081
---
test/units/testsuite-65.sh | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/test/units/testsuite-65.sh b/test/units/testsuite-65.sh
index 89406a108e..1f34308b44 100755
--- a/test/units/testsuite-65.sh
+++ b/test/units/testsuite-65.sh
@@ -45,8 +45,16 @@ systemd-analyze dot "systemd-*.service" >/dev/null
systemd-analyze dump >/dev/null
systemd-analyze dump "*" >/dev/null
systemd-analyze dump "*.socket" >/dev/null
+systemd-analyze dump "*.socket" "*.service" aaaaaaa ... >/dev/null
systemd-analyze dump systemd-journald.service >/dev/null
(! systemd-analyze dump "")
+# unit-files
+systemd-analyze unit-files >/dev/null
+systemd-analyze unit-files systemd-journald.service >/dev/null
+systemd-analyze unit-files "*" >/dev/null
+systemd-analyze unit-files "*" aaaaaa "*.service" "*.target" >/dev/null
+systemd-analyze unit-files --user >/dev/null
+systemd-analyze unit-files --user "*" aaaaaa "*.service" "*.target" >/dev/null
# unit-paths
systemd-analyze unit-paths
systemd-analyze unit-paths --user
@@ -103,6 +111,7 @@ systemd-analyze calendar '*-* *:*:*'
systemd-analyze calendar --iterations=5 '*-* *:*:*'
systemd-analyze calendar --iterations=50 '*-* *:*:*'
systemd-analyze calendar --iterations=0 '*-* *:*:*'
+systemd-analyze calendar --iterations=5 '01-01-22 01:00:00'
systemd-analyze calendar --base-time=yesterday --iterations=5 '*-* *:*:*'
(! systemd-analyze calendar --iterations=0 '*-* 99:*:*')
(! systemd-analyze calendar --base-time=never '*-* *:*:*')
@@ -114,12 +123,14 @@ systemd-analyze timestamp -- -1
systemd-analyze timestamp yesterday now tomorrow
(! systemd-analyze timestamp yesterday never tomorrow)
(! systemd-analyze timestamp 1)
+(! systemd-analyze timestamp '*-2-29 0:0:0')
(! systemd-analyze timestamp "")
# timespan
systemd-analyze timespan 1
systemd-analyze timespan 1s 300s '1year 0.000001s'
(! systemd-analyze timespan 1s 300s aaaaaa '1year 0.000001s')
(! systemd-analyze timespan -- -1)
+(! systemd-analyze timespan '*-2-29 0:0:0')
(! systemd-analyze timespan "")
# cat-config
systemd-analyze cat-config systemd/system.conf >/dev/null

@ -0,0 +1,29 @@
From 96b6171376bfdb7417143a2026beda059fe3e22f Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sat, 1 Sep 2018 23:47:46 +0900
Subject: [PATCH] cryptsetup: do not define arg_sector_size if libgcrypt is
v1.x (#9990)
Follow-up for #9936.
(cherry picked from commit 645461f0cf6ec91e5b0b571559fb4cc4898192bc)
Related: #1572563
---
src/cryptsetup/cryptsetup.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 87008cb969..abeba44ee8 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -30,7 +30,9 @@
static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */
static char *arg_cipher = NULL;
static unsigned arg_key_size = 0;
+#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE
static unsigned arg_sector_size = CRYPT_SECTOR_SIZE;
+#endif
static int arg_key_slot = CRYPT_ANY_SLOT;
static unsigned arg_keyfile_size = 0;
static uint64_t arg_keyfile_offset = 0;

@ -1,371 +0,0 @@
From e0d51a65a8bbe8c86af4bb843a5f9ac7d590fa01 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Thu, 3 Nov 2022 13:13:03 +0100
Subject: [PATCH] test: introduce sanity coverage for auxiliary utils
(cherry picked from commit d1020334fd15e0cffe68cb4d7e862a36253cc481)
Related #2138081
---
test/TEST-74-AUX-UTILS/Makefile | 1 +
test/TEST-74-AUX-UTILS/test.sh | 10 ++
test/units/testsuite-74.cgls.sh | 26 +++++
test/units/testsuite-74.cgtop.sh | 32 ++++++
test/units/testsuite-74.delta.sh | 59 +++++++++++
test/units/testsuite-74.firstboot.sh | 145 +++++++++++++++++++++++++++
test/units/testsuite-74.service | 8 ++
test/units/testsuite-74.sh | 14 +++
8 files changed, 295 insertions(+)
create mode 120000 test/TEST-74-AUX-UTILS/Makefile
create mode 100755 test/TEST-74-AUX-UTILS/test.sh
create mode 100755 test/units/testsuite-74.cgls.sh
create mode 100755 test/units/testsuite-74.cgtop.sh
create mode 100755 test/units/testsuite-74.delta.sh
create mode 100755 test/units/testsuite-74.firstboot.sh
create mode 100644 test/units/testsuite-74.service
create mode 100755 test/units/testsuite-74.sh
diff --git a/test/TEST-74-AUX-UTILS/Makefile b/test/TEST-74-AUX-UTILS/Makefile
new file mode 120000
index 0000000000..e9f93b1104
--- /dev/null
+++ b/test/TEST-74-AUX-UTILS/Makefile
@@ -0,0 +1 @@
+../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-74-AUX-UTILS/test.sh b/test/TEST-74-AUX-UTILS/test.sh
new file mode 100755
index 0000000000..f422c89141
--- /dev/null
+++ b/test/TEST-74-AUX-UTILS/test.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -e
+
+TEST_DESCRIPTION="Tests for auxiliary utilities"
+
+# shellcheck source=test/test-functions
+. "${TEST_BASE_DIR:?}/test-functions"
+
+do_test "$@"
diff --git a/test/units/testsuite-74.cgls.sh b/test/units/testsuite-74.cgls.sh
new file mode 100755
index 0000000000..120570c9cc
--- /dev/null
+++ b/test/units/testsuite-74.cgls.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+systemd-cgls
+systemd-cgls --all --full
+systemd-cgls -k
+systemd-cgls --xattr=yes
+systemd-cgls --xattr=no
+systemd-cgls --cgroup-id=yes
+systemd-cgls --cgroup-id=no
+
+systemd-cgls /system.slice/systemd-journald.service
+systemd-cgls /system.slice/systemd-journald.service /init.scope
+systemd-cgls /sys/fs/cgroup/system.slice/systemd-journald.service /init.scope
+(cd /sys/fs/cgroup/init.scope && systemd-cgls)
+systemd-cgls --unit=systemd-journald.service
+# There's most likely no user session running, so we need to create one
+systemd-run --user --wait --pipe -M testuser@.host systemd-cgls --user-unit=app.slice
+
+(! systemd-cgls /foo/bar)
+(! systemd-cgls --unit=hello.world)
+(! systemd-cgls --user-unit=hello.world)
+(! systemd-cgls --xattr=foo)
+(! systemd-cgls --cgroup-id=foo)
diff --git a/test/units/testsuite-74.cgtop.sh b/test/units/testsuite-74.cgtop.sh
new file mode 100755
index 0000000000..8141ec1b1f
--- /dev/null
+++ b/test/units/testsuite-74.cgtop.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+# Without tty attached cgtop should default to --iterations=1
+systemd-cgtop
+systemd-cgtop --iterations=1
+# Same as --iterations=1
+systemd-cgtop -1
+systemd-cgtop --delay=1ms
+systemd-cgtop --raw
+systemd-cgtop --batch
+systemd-cgtop --cpu=percentage
+systemd-cgtop --cpu=time
+systemd-cgtop -P
+systemd-cgtop -k
+# FIXME: https://github.com/systemd/systemd/issues/25248
+#systemd-cgtop --recursive=no
+systemd-cgtop --depth=0
+systemd-cgtop --depth=100
+
+for order in path tasks cpu memory io; do
+ systemd-cgtop --order="$order"
+done
+systemd-cgtop -p -t -c -m -i
+
+(! systemd-cgtop --cpu=foo)
+(! systemd-cgtop --order=foo)
+(! systemd-cgtop --depth=-1)
+(! systemd-cgtop --recursive=foo)
+(! systemd-cgtop --delay=1foo)
diff --git a/test/units/testsuite-74.delta.sh b/test/units/testsuite-74.delta.sh
new file mode 100755
index 0000000000..a0e1cb52dd
--- /dev/null
+++ b/test/units/testsuite-74.delta.sh
@@ -0,0 +1,59 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+at_exit() {
+ rm -rfv /{run,etc}/systemd/system/delta-test*
+}
+
+trap at_exit EXIT
+
+# Create a couple of supporting units with overrides
+#
+# Extended unit
+cat >"/run/systemd/system/delta-test-unit-extended.service" <<EOF
+[Service]
+ExecStart=/bin/true
+EOF
+mkdir -p "/run/systemd/system/delta-test-unit-extended.service.d"
+cat >"/run/systemd/system/delta-test-unit-extended.service.d/override.conf" <<EOF
+[Unit]
+Description=Foo Bar
+[Service]
+ExecStartPre=/bin/true
+EOF
+# Masked unit
+cp -fv /run/systemd/system/delta-test-unit-extended.service /run/systemd/system/delta-test-unit-masked.service
+systemctl mask delta-test-unit-masked.service
+# Overridden unit
+cp -fv /run/systemd/system/delta-test-unit-extended.service /run/systemd/system/delta-test-unit-overridden.service
+cp -fv /run/systemd/system/delta-test-unit-overridden.service /etc/systemd/system/delta-test-unit-overridden.service
+echo "ExecStartPost=/bin/true" >>/etc/systemd/system/delta-test-unit-overridden.service
+# Overridden but equivalent unit
+ln -srfv /run/systemd/system/delta-test-unit-extended.service /run/systemd/system/delta-test-unit-equivalent.service
+ln -sfv /run/systemd/system/delta-test-unit-extended.service /etc/systemd/system/delta-test-unit-equivalent.service
+# Redirected unit
+ln -srfv /run/systemd/system/delta-test-unit-extended.service /run/systemd/system/delta-test-unit-redirected.service
+ln -sfv /run/systemd/system/delta-test-unit-overidden.service /etc/systemd/system/delta-test-unit-extended.service
+
+systemctl daemon-reload
+
+systemd-delta
+systemd-delta /run
+systemd-delta systemd/system
+systemd-delta /run systemd/system /run
+systemd-delta /run foo/bar hello/world systemd/system /run
+systemd-delta foo/bar
+systemd-delta --diff=true
+systemd-delta --diff=false
+
+for type in masked equivalent redirected overridden extended unchanged; do
+ systemd-delta --type="$type"
+ systemd-delta --type="$type" /run
+done
+systemd-delta --type=equivalent,redirected
+
+(! systemd-delta --diff=foo)
+(! systemd-delta --type=foo)
+(! systemd-delta --type=equivalent,redirected,foo)
diff --git a/test/units/testsuite-74.firstboot.sh b/test/units/testsuite-74.firstboot.sh
new file mode 100755
index 0000000000..02f9f5cd7a
--- /dev/null
+++ b/test/units/testsuite-74.firstboot.sh
@@ -0,0 +1,145 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+if ! command -v systemd-firstboot >/dev/null; then
+ echo "systemd-firstboot not found, skipping the test"
+ exit 0
+fi
+
+at_exit() {
+ if [[ -v ROOT && -n "$ROOT" ]]; then
+ ls -lR "$ROOT"
+ rm -fr "$ROOT"
+ fi
+}
+
+trap at_exit EXIT
+
+# Generated via `mkpasswd -m sha-512 -S foobarsalt password1`
+# shellcheck disable=SC2016
+ROOT_HASHED_PASSWORD1='$6$foobarsalt$YbwdaATX6IsFxvWbY3QcZj2gB31R/LFRFrjlFrJtTTqFtSfn4dfOAg/km2k4Sl.a2g7LOYDo31wMTaEsCo9j41'
+# Generated via `mkpasswd -m sha-512 -S foobarsalt password2`
+# shellcheck disable=SC2016
+ROOT_HASHED_PASSWORD2='$6$foobarsalt$q.P2932zYMLbKnjFwIxPI8y3iuxeuJ2BgE372LcZMMnj3Gcg/9mJg2LPKUl.ha0TG/.fRNNnRQcLfzM0SNot3.'
+
+# Create a minimal root so we don't modify the testbed
+ROOT=test-root
+mkdir -p "$ROOT/bin"
+# Dummy shell for --root-shell=
+touch "$ROOT/bin/fooshell" "$ROOT/bin/barshell"
+
+systemd-firstboot --root="$ROOT" --locale=foo
+grep -q "LANG=foo" "$ROOT/etc/locale.conf"
+rm -fv "$ROOT/etc/locale.conf"
+# FIXME: https://github.com/systemd/systemd/issues/25249
+#systemd-firstboot --root="$ROOT" --locale-messages=foo
+#grep -q "LC_MESSAGES=foo" "$ROOT/etc/locale.conf"
+#rm -fv "$ROOT/etc/locale.conf"
+systemd-firstboot --root="$ROOT" --locale=foo --locale-messages=bar
+grep -q "LANG=foo" "$ROOT/etc/locale.conf"
+grep -q "LC_MESSAGES=bar" "$ROOT/etc/locale.conf"
+
+systemd-firstboot --root="$ROOT" --keymap=foo
+grep -q "KEYMAP=foo" "$ROOT/etc/vconsole.conf"
+
+systemd-firstboot --root="$ROOT" --timezone=Europe/Berlin
+readlink "$ROOT/etc/localtime" | grep -q "Europe/Berlin"
+
+systemd-firstboot --root="$ROOT" --hostname "foobar"
+grep -q "foobar" "$ROOT/etc/hostname"
+
+systemd-firstboot --root="$ROOT" --machine-id=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+grep -q "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "$ROOT/etc/machine-id"
+
+rm -fv "$ROOT/etc/passwd" "$ROOT/etc/shadow"
+systemd-firstboot --root="$ROOT" --root-password=foo
+grep -q "^root:x:0:0:" "$ROOT/etc/passwd"
+grep -q "^root:" "$ROOT/etc/shadow"
+rm -fv "$ROOT/etc/passwd" "$ROOT/etc/shadow"
+echo "foo" >root.passwd
+systemd-firstboot --root="$ROOT" --root-password-file=root.passwd
+grep -q "^root:x:0:0:" "$ROOT/etc/passwd"
+grep -q "^root:" "$ROOT/etc/shadow"
+rm -fv "$ROOT/etc/passwd" "$ROOT/etc/shadow" root.passwd
+# Set the shell together with the password, as firstboot won't touch
+# /etc/passwd if it already exists
+systemd-firstboot --root="$ROOT" --root-password-hashed="$ROOT_HASHED_PASSWORD1" --root-shell=/bin/fooshell
+grep -q "^root:x:0:0:.*:/bin/fooshell$" "$ROOT/etc/passwd"
+grep -q "^root:$ROOT_HASHED_PASSWORD1:" "$ROOT/etc/shadow"
+
+systemd-firstboot --root="$ROOT" --kernel-command-line="foo.bar=42"
+grep -q "foo.bar=42" "$ROOT/etc/kernel/cmdline"
+
+# Configs should not get overwritten if they exist unless --force is used
+systemd-firstboot --root="$ROOT" \
+ --locale=locale-overwrite \
+ --locale-messages=messages-overwrite \
+ --keymap=keymap-overwrite \
+ --timezone=CET \
+ --hostname=hostname-overwrite \
+ --machine-id=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \
+ --root-password-hashed="$ROOT_HASHED_PASSWORD2" \
+ --root-shell=/bin/barshell \
+ --kernel-command-line="hello.world=0"
+grep -q "LANG=foo" "$ROOT/etc/locale.conf"
+grep -q "LC_MESSAGES=bar" "$ROOT/etc/locale.conf"
+grep -q "KEYMAP=foo" "$ROOT/etc/vconsole.conf"
+readlink "$ROOT/etc/localtime" | grep -q "Europe/Berlin$"
+grep -q "foobar" "$ROOT/etc/hostname"
+grep -q "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "$ROOT/etc/machine-id"
+grep -q "^root:x:0:0:.*:/bin/fooshell$" "$ROOT/etc/passwd"
+grep -q "^root:$ROOT_HASHED_PASSWORD1:" "$ROOT/etc/shadow"
+grep -q "foo.bar=42" "$ROOT/etc/kernel/cmdline"
+
+# The same thing, but now with --force
+systemd-firstboot --root="$ROOT" --force \
+ --locale=locale-overwrite \
+ --locale-messages=messages-overwrite \
+ --keymap=keymap-overwrite \
+ --timezone=CET \
+ --hostname=hostname-overwrite \
+ --machine-id=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \
+ --root-password-hashed="$ROOT_HASHED_PASSWORD2" \
+ --root-shell=/bin/barshell \
+ --kernel-command-line="hello.world=0"
+grep -q "LANG=locale-overwrite" "$ROOT/etc/locale.conf"
+grep -q "LC_MESSAGES=messages-overwrite" "$ROOT/etc/locale.conf"
+grep -q "KEYMAP=keymap-overwrite" "$ROOT/etc/vconsole.conf"
+readlink "$ROOT/etc/localtime" | grep -q "/CET$"
+grep -q "hostname-overwrite" "$ROOT/etc/hostname"
+grep -q "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "$ROOT/etc/machine-id"
+grep -q "^root:x:0:0:.*:/bin/barshell$" "$ROOT/etc/passwd"
+grep -q "^root:$ROOT_HASHED_PASSWORD2:" "$ROOT/etc/shadow"
+grep -q "hello.world=0" "$ROOT/etc/kernel/cmdline"
+
+# --copy-* options
+rm -fr "$ROOT"
+mkdir "$ROOT"
+# Copy everything at once (--copy)
+systemd-firstboot --root="$ROOT" --copy
+diff /etc/locale.conf "$ROOT/etc/locale.conf"
+diff <(awk -F: '/^root/ { print $7; }' /etc/passwd) <(awk -F: '/^root/ { print $7; }' "$ROOT/etc/passwd")
+diff <(awk -F: '/^root/ { print $2; }' /etc/shadow) <(awk -F: '/^root/ { print $2; }' "$ROOT/etc/shadow")
+[[ -e /etc/vconsole.conf ]] && diff /etc/vconsole.conf "$ROOT/etc/vconsole.conf"
+[[ -e /etc/localtime ]] && diff <(readlink /etc/localtime) <(readlink "$ROOT/etc/localtime")
+rm -fr "$ROOT"
+mkdir "$ROOT"
+# Copy everything at once, but now by using separate switches
+systemd-firstboot --root="$ROOT" --copy-locale --copy-keymap --copy-timezone --copy-root-password --copy-root-shell
+diff /etc/locale.conf "$ROOT/etc/locale.conf"
+diff <(awk -F: '/^root/ { print $7; }' /etc/passwd) <(awk -F: '/^root/ { print $7; }' "$ROOT/etc/passwd")
+diff <(awk -F: '/^root/ { print $2; }' /etc/shadow) <(awk -F: '/^root/ { print $2; }' "$ROOT/etc/shadow")
+[[ -e /etc/vconsole.conf ]] && diff /etc/vconsole.conf "$ROOT/etc/vconsole.conf"
+[[ -e /etc/localtime ]] && diff <(readlink /etc/localtime) <(readlink "$ROOT/etc/localtime")
+
+# Assorted tests
+rm -fr "$ROOT"
+mkdir "$ROOT"
+
+systemd-firstboot --root="$ROOT" --setup-machine-id
+grep -E "[a-z0-9]{32}" "$ROOT/etc/machine-id"
+
+systemd-firstboot --root="$ROOT" --delete-root-password
+diff <(echo) <(awk -F: '/^root/ { print $2; }' "$ROOT/etc/shadow")
diff --git a/test/units/testsuite-74.service b/test/units/testsuite-74.service
new file mode 100644
index 0000000000..f782132a92
--- /dev/null
+++ b/test/units/testsuite-74.service
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+Description=TEST-74-AUX-UTILS
+
+[Service]
+ExecStartPre=rm -f /failed /testok
+ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
+Type=oneshot
diff --git a/test/units/testsuite-74.sh b/test/units/testsuite-74.sh
new file mode 100755
index 0000000000..13c767e490
--- /dev/null
+++ b/test/units/testsuite-74.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+: >/failed
+
+for script in "${0%.sh}".*.sh; do
+ echo "Running $script"
+ "./$script"
+done
+
+touch /testok
+rm /failed

@ -1,56 +0,0 @@
From 1ef6ffdf0923095752665c7ff6062514dfa6c6bf Mon Sep 17 00:00:00 2001
From: Luca Boccassi <bluca@debian.org>
Date: Fri, 4 Nov 2022 00:01:16 +0000
Subject: [PATCH] firstboot: fix segfault when --locale-messages= is passed
without --locale=
\#0 __strcmp_evex () at ../sysdeps/x86_64/multiarch/strcmp-evex.S:295
No locals.
\#1 0x0000557444eb172b in process_locale () at ../src/firstboot/firstboot.c:342
etc_localeconf = 0x7ffd40217b80 "/root/root/etc/locale.conf"
locales = {0x0, 0x0, 0x0}
i = 0
r = <optimized out>
__PRETTY_FUNCTION__ = "process_locale"
__func__ = "process_locale"
\#2 0x0000557444eaff93 in run (argv=0x7ffd40217d98, argc=3) at ../src/firstboot/firstboot.c:1401
loop_device = 0x0
unlink_dir = 0x0
r = <optimized out>
loop_device = <optimized out>
unlink_dir = <optimized out>
r = <optimized out>
__func__ = <optimized out>
__PRETTY_FUNCTION__ = <optimized out>
enabled = <optimized out>
_error = <optimized out>
_level = <optimized out>
_e = <optimized out>
_level = <optimized out>
_e = <optimized out>
\#3 main (argc=3, argv=0x7ffd40217d98) at ../src/firstboot/firstboot.c:1432
r = <optimized out>
__PRETTY_FUNCTION__ = "main"
Fixes https://github.com/systemd/systemd/issues/25249
(cherry picked from commit 4c4a73ce068ef16cfe7ad07c7c3386ac1dbc58fe)
Related #2138081
---
src/firstboot/firstboot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index 065ee896cd..63db78b52d 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -339,7 +339,7 @@ static int process_locale(void) {
if (!isempty(arg_locale))
locales[i++] = strjoina("LANG=", arg_locale);
- if (!isempty(arg_locale_messages) && !streq(arg_locale_messages, arg_locale))
+ if (!isempty(arg_locale_messages) && !streq_ptr(arg_locale_messages, arg_locale))
locales[i++] = strjoina("LC_MESSAGES=", arg_locale_messages);
if (i == 0)

@ -0,0 +1,112 @@
From e143339ac712f745727951973417ce93b5d06d78 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Fri, 12 Oct 2018 14:50:09 +0000
Subject: [PATCH] units: don't enable per-service IP firewall by default
Resolves: #1630219
---
units/systemd-coredump@.service.in | 1 -
units/systemd-hostnamed.service.in | 1 -
units/systemd-journald.service.in | 1 -
units/systemd-localed.service.in | 1 -
units/systemd-logind.service.in | 1 -
units/systemd-machined.service.in | 1 -
units/systemd-portabled.service.in | 1 -
units/systemd-timedated.service.in | 1 -
units/systemd-udevd.service.in | 1 -
9 files changed, 9 deletions(-)
diff --git a/units/systemd-coredump@.service.in b/units/systemd-coredump@.service.in
index 215696ecd1..68a68a5055 100644
--- a/units/systemd-coredump@.service.in
+++ b/units/systemd-coredump@.service.in
@@ -37,5 +37,4 @@ SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
StateDirectory=systemd/coredump
diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in
index da74b4fe8b..4e5470dd29 100644
--- a/units/systemd-hostnamed.service.in
+++ b/units/systemd-hostnamed.service.in
@@ -33,5 +33,4 @@ SystemCallFilter=@system-service sethostname
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
ReadWritePaths=/etc
diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
index 8f5021d0de..2d5fd0120d 100644
--- a/units/systemd-journald.service.in
+++ b/units/systemd-journald.service.in
@@ -33,7 +33,6 @@ SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
# Increase the default a bit in order to allow many simultaneous
# services being run since we keep one fd open per service. Also, when
diff --git a/units/systemd-localed.service.in b/units/systemd-localed.service.in
index a24e61a0cd..ce043db154 100644
--- a/units/systemd-localed.service.in
+++ b/units/systemd-localed.service.in
@@ -33,5 +33,4 @@ SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
ReadWritePaths=/etc
diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
index 5e090bcf23..6953fac55b 100644
--- a/units/systemd-logind.service.in
+++ b/units/systemd-logind.service.in
@@ -34,7 +34,6 @@ SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
FileDescriptorStoreMax=512
# Increase the default a bit in order to allow many simultaneous
diff --git a/units/systemd-machined.service.in b/units/systemd-machined.service.in
index 1200a90a61..dec2c4b0dc 100644
--- a/units/systemd-machined.service.in
+++ b/units/systemd-machined.service.in
@@ -27,7 +27,6 @@ SystemCallFilter=@system-service @mount
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
# Note that machined cannot be placed in a mount namespace, since it
# needs access to the host's mount namespace in order to implement the
diff --git a/units/systemd-portabled.service.in b/units/systemd-portabled.service.in
index a868f61dba..64f14071e8 100644
--- a/units/systemd-portabled.service.in
+++ b/units/systemd-portabled.service.in
@@ -23,4 +23,3 @@ RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io @reboot @swap
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in
index 906bb4326c..662b39557a 100644
--- a/units/systemd-timedated.service.in
+++ b/units/systemd-timedated.service.in
@@ -31,5 +31,4 @@ SystemCallFilter=@system-service @clock
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
ReadWritePaths=/etc
diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in
index 6a3814e5d9..fd9ead3bb8 100644
--- a/units/systemd-udevd.service.in
+++ b/units/systemd-udevd.service.in
@@ -33,4 +33,3 @@ SystemCallFilter=@system-service @module @raw-io
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any

@ -0,0 +1,45 @@
From 87922b7adc47f311e89b21e37b26ee300a401e1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 9 Jul 2018 13:21:44 +0200
Subject: [PATCH] bus-message: do not crash on message with a string of zero
length
We'd calculate the "real" length of the string as 'item_size - 1', which does
not work out well when item_size == 0.
(cherry picked from commit 81b6e63029eefcb0ec03a3a7c248490e38106073)
Resolves: #1635439
---
src/libsystemd/sd-bus/bus-message.c | 6 ++++++
.../crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e | Bin 0 -> 51 bytes
2 files changed, 6 insertions(+)
create mode 100644 test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 8d92bc2002..381034f5f8 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -3312,6 +3312,12 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
bool ok;
+ /* D-Bus spec: The marshalling formats for the string-like types all end
+ * with a single zero (NUL) byte, but that byte is not considered to be part
+ * of the text. */
+ if (c->item_size == 0)
+ return -EBADMSG;
+
r = message_peek_body(m, &rindex, 1, c->item_size, &q);
if (r < 0)
return r;
diff --git a/test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e b/test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e
new file mode 100644
index 0000000000000000000000000000000000000000..4488f0a6c685b5d43eddbe41a0c6a3b6be9b02e2
GIT binary patch
literal 51
fcmc~1WMC4sJpJnr13KV`0|t%6q+%$@&=ddw)CUPg
literal 0
HcmV?d00001

@ -1,76 +0,0 @@
From 1d41d2789bb67f5909d6974d2fd916e462a0a5cf Mon Sep 17 00:00:00 2001
From: Franck Bui <fbui@suse.com>
Date: Fri, 4 Nov 2022 12:24:10 +0100
Subject: [PATCH] tests: make test-execute pass on openSUSE
In my understanding user group "3" (aka "sys") is kept for historical reasons
but not really useful these days. That's probably explained why this group
isn't defined on openSUSE.
Hence let's drop reference to this user group, this shouldn't lessen the
revelance of the test since SupplementaryGroups= is still tested with 2 other
groups.
(cherry picked from commit d723b0467d7b8c5c772086d5352442f3fca4368d)
Related #2138081
---
test/test-execute/exec-dynamicuser-supplementarygroups.service | 3 +--
...plementarygroups-multiple-groups-default-group-user.service | 3 +--
.../exec-supplementarygroups-multiple-groups-withgid.service | 3 +--
.../exec-supplementarygroups-multiple-groups-withuid.service | 3 +--
4 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/test/test-execute/exec-dynamicuser-supplementarygroups.service b/test/test-execute/exec-dynamicuser-supplementarygroups.service
index fb0b57bc00..53ba0ec7cb 100644
--- a/test/test-execute/exec-dynamicuser-supplementarygroups.service
+++ b/test/test-execute/exec-dynamicuser-supplementarygroups.service
@@ -5,7 +5,6 @@ Description=Test DynamicUser with SupplementaryGroups=
[Service]
ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "3" && HAVE=1; done; test "$$HAVE" -eq 1'
Type=oneshot
DynamicUser=yes
-SupplementaryGroups=1 2 3
+SupplementaryGroups=1 2
diff --git a/test/test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service b/test/test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service
index 362e539287..4cb0326320 100644
--- a/test/test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service
+++ b/test/test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service
@@ -6,7 +6,6 @@ Description=Test for Supplementary Group with multiple groups without Group and
ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "%G" && HAVE=1; done; test "$$HAVE" -eq 1'
ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "3" && HAVE=1; done; test "$$HAVE" -eq 1'
ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "%G" && test "$$(id -u)" = "%U"'
Type=oneshot
-SupplementaryGroups=1 2 3
+SupplementaryGroups=1 2
diff --git a/test/test-execute/exec-supplementarygroups-multiple-groups-withgid.service b/test/test-execute/exec-supplementarygroups-multiple-groups-withgid.service
index ff3fdc8142..e11743d754 100644
--- a/test/test-execute/exec-supplementarygroups-multiple-groups-withgid.service
+++ b/test/test-execute/exec-supplementarygroups-multiple-groups-withgid.service
@@ -5,8 +5,7 @@ Description=Test for Supplementary Group with multiple groups and Group=1
[Service]
ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "3" && HAVE=1; done; test "$$HAVE" -eq 1'
ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "%U"'
Type=oneshot
Group=1
-SupplementaryGroups=1 2 3
+SupplementaryGroups=1 2
diff --git a/test/test-execute/exec-supplementarygroups-multiple-groups-withuid.service b/test/test-execute/exec-supplementarygroups-multiple-groups-withuid.service
index f35ff84765..3efbbfb0f9 100644
--- a/test/test-execute/exec-supplementarygroups-multiple-groups-withuid.service
+++ b/test/test-execute/exec-supplementarygroups-multiple-groups-withuid.service
@@ -5,7 +5,6 @@ Description=Test for Supplementary Group with multiple groups and Uid=1
[Service]
ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "3" && HAVE=1; done; test "$$HAVE" -eq 1'
Type=oneshot
User=1
-SupplementaryGroups=1 2 3
+SupplementaryGroups=1 2

@ -0,0 +1,279 @@
From 26de3af817b0c5746cb61b798ae8e138e01ea17c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 9 Jul 2018 07:03:01 +0200
Subject: [PATCH] Introduce free_and_strndup and use it in bus-message.c
v2: fix error in free_and_strndup()
When the orignal and copied message were the same, but shorter than specified
length l, memory read past the end of the buffer would be performed. A test
case is included: a string that had an embedded NUL ("q\0") is used to replace
"q".
v3: Fix one more bug in free_and_strndup and add tests.
v4: Some style fixed based on review, one more use of free_and_replace, and
make the tests more comprehensive.
(cherry picked from commit 7f546026abbdc56c453a577e52d57159458c3e9c)
Resolves: #1635428
---
src/basic/string-util.c | 28 +++++++-
src/basic/string-util.h | 1 +
src/libsystemd/sd-bus/bus-message.c | 34 ++++------
src/test/test-string-util.c | 62 ++++++++++++++++++
...h-b88ad9ecf4aacf4a0caca5b5543953265367f084 | Bin 0 -> 32 bytes
5 files changed, 103 insertions(+), 22 deletions(-)
create mode 100644 test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
index 0a40683493..dfa739996f 100644
--- a/src/basic/string-util.c
+++ b/src/basic/string-util.c
@@ -1004,7 +1004,7 @@ int free_and_strdup(char **p, const char *s) {
assert(p);
- /* Replaces a string pointer with an strdup()ed new string,
+ /* Replaces a string pointer with a strdup()ed new string,
* possibly freeing the old one. */
if (streq_ptr(*p, s))
@@ -1023,6 +1023,32 @@ int free_and_strdup(char **p, const char *s) {
return 1;
}
+int free_and_strndup(char **p, const char *s, size_t l) {
+ char *t;
+
+ assert(p);
+ assert(s || l == 0);
+
+ /* Replaces a string pointer with a strndup()ed new string,
+ * freeing the old one. */
+
+ if (!*p && !s)
+ return 0;
+
+ if (*p && s && strneq(*p, s, l) && (l > strlen(*p) || (*p)[l] == '\0'))
+ return 0;
+
+ if (s) {
+ t = strndup(s, l);
+ if (!t)
+ return -ENOMEM;
+ } else
+ t = NULL;
+
+ free_and_replace(*p, t);
+ return 1;
+}
+
#if !HAVE_EXPLICIT_BZERO
/*
* Pointer to memset is volatile so that compiler must de-reference
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
index c0cc4e78d7..96a9260f93 100644
--- a/src/basic/string-util.h
+++ b/src/basic/string-util.h
@@ -176,6 +176,7 @@ char *strrep(const char *s, unsigned n);
int split_pair(const char *s, const char *sep, char **l, char **r);
int free_and_strdup(char **p, const char *s);
+int free_and_strndup(char **p, const char *s, size_t l);
/* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 381034f5f8..7c8bad2bdd 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -4175,20 +4175,19 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (contents) {
size_t l;
- char *sig;
r = signature_element_length(c->signature+c->index+1, &l);
if (r < 0)
return r;
- assert(l >= 1);
+ /* signature_element_length does verification internally */
- sig = strndup(c->signature + c->index + 1, l);
- if (!sig)
+ assert(l >= 1);
+ if (free_and_strndup(&c->peeked_signature,
+ c->signature + c->index + 1, l) < 0)
return -ENOMEM;
- free(c->peeked_signature);
- *contents = c->peeked_signature = sig;
+ *contents = c->peeked_signature;
}
if (type)
@@ -4201,19 +4200,17 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (contents) {
size_t l;
- char *sig;
r = signature_element_length(c->signature+c->index, &l);
if (r < 0)
return r;
assert(l >= 2);
- sig = strndup(c->signature + c->index + 1, l - 2);
- if (!sig)
+ if (free_and_strndup(&c->peeked_signature,
+ c->signature + c->index + 1, l - 2) < 0)
return -ENOMEM;
- free(c->peeked_signature);
- *contents = c->peeked_signature = sig;
+ *contents = c->peeked_signature;
}
if (type)
@@ -4253,9 +4250,8 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (k > c->item_size)
return -EBADMSG;
- free(c->peeked_signature);
- c->peeked_signature = strndup((char*) q + 1, k - 1);
- if (!c->peeked_signature)
+ if (free_and_strndup(&c->peeked_signature,
+ (char*) q + 1, k - 1) < 0)
return -ENOMEM;
if (!signature_is_valid(c->peeked_signature, true))
@@ -5085,25 +5081,21 @@ int bus_message_parse_fields(sd_bus_message *m) {
if (*p == 0) {
size_t l;
- char *c;
/* We found the beginning of the signature
* string, yay! We require the body to be a
* structure, so verify it and then strip the
* opening/closing brackets. */
- l = ((char*) m->footer + m->footer_accessible) - p - (1 + sz);
+ l = (char*) m->footer + m->footer_accessible - p - (1 + sz);
if (l < 2 ||
p[1] != SD_BUS_TYPE_STRUCT_BEGIN ||
p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END)
return -EBADMSG;
- c = strndup(p + 1 + 1, l - 2);
- if (!c)
+ if (free_and_strndup(&m->root_container.signature,
+ p + 1 + 1, l - 2) < 0)
return -ENOMEM;
-
- free(m->root_container.signature);
- m->root_container.signature = c;
break;
}
diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c
index 3e72ce2c0a..43a6b14c34 100644
--- a/src/test/test-string-util.c
+++ b/src/test/test-string-util.c
@@ -5,6 +5,7 @@
#include "macro.h"
#include "string-util.h"
#include "strv.h"
+#include "tests.h"
#include "utf8.h"
static void test_string_erase(void) {
@@ -30,6 +31,64 @@ static void test_string_erase(void) {
assert_se(x[9] == '\0');
}
+static void test_free_and_strndup_one(char **t, const char *src, size_t l, const char *expected, bool change) {
+ int r;
+
+ log_debug("%s: \"%s\", \"%s\", %zd (expect \"%s\", %s)",
+ __func__, strnull(*t), strnull(src), l, strnull(expected), yes_no(change));
+
+ r = free_and_strndup(t, src, l);
+ assert_se(streq_ptr(*t, expected));
+ assert_se(r == change); /* check that change occurs only when necessary */
+}
+
+static void test_free_and_strndup(void) {
+ static const struct test_case {
+ const char *src;
+ size_t len;
+ const char *expected;
+ } cases[] = {
+ {"abc", 0, ""},
+ {"abc", 0, ""},
+ {"abc", 1, "a"},
+ {"abc", 2, "ab"},
+ {"abc", 3, "abc"},
+ {"abc", 4, "abc"},
+ {"abc", 5, "abc"},
+ {"abc", 5, "abc"},
+ {"abc", 4, "abc"},
+ {"abc", 3, "abc"},
+ {"abc", 2, "ab"},
+ {"abc", 1, "a"},
+ {"abc", 0, ""},
+
+ {"", 0, ""},
+ {"", 1, ""},
+ {"", 2, ""},
+ {"", 0, ""},
+ {"", 1, ""},
+ {"", 2, ""},
+ {"", 2, ""},
+ {"", 1, ""},
+ {"", 0, ""},
+
+ {NULL, 0, NULL},
+
+ {"foo", 3, "foo"},
+ {"foobar", 6, "foobar"},
+ };
+
+ _cleanup_free_ char *t = NULL;
+ const char *prev_expected = t;
+
+ for (unsigned i = 0; i < ELEMENTSOF(cases); i++) {
+ test_free_and_strndup_one(&t,
+ cases[i].src, cases[i].len, cases[i].expected,
+ !streq_ptr(cases[i].expected, prev_expected));
+ prev_expected = t;
+ }
+}
+
static void test_ascii_strcasecmp_n(void) {
assert_se(ascii_strcasecmp_n("", "", 0) == 0);
@@ -497,7 +556,10 @@ static void test_memory_startswith(void) {
}
int main(int argc, char *argv[]) {
+ test_setup_logging(LOG_DEBUG);
+
test_string_erase();
+ test_free_and_strndup();
test_ascii_strcasecmp_n();
test_ascii_strcasecmp_nn();
test_cellescape();
diff --git a/test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084 b/test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084
new file mode 100644
index 0000000000000000000000000000000000000000..52469650b5498a45d5d95bd9d933c989cfb47ca7
GIT binary patch
literal 32
ccmd1#|DTBg0(2Mzp)7_%AVVXuuuM|`09r!?!~g&Q
literal 0
HcmV?d00001

@ -1,150 +0,0 @@
From 5685a8b01abf34ec5da7c43a99ede6e3bb7394eb Mon Sep 17 00:00:00 2001
From: Franck Bui <fbui@suse.com>
Date: Fri, 4 Nov 2022 12:50:04 +0100
Subject: [PATCH] tests: minor simplification in test-execute
No functional change.
(cherry picked from commit 09415aef940f4a471da7cb899b9a66f1504d7c77)
Related #2138081
---
...xec-dynamicuser-fixeduser-one-supplementarygroup.service | 2 +-
test/test-execute/exec-dynamicuser-fixeduser.service | 2 +-
.../exec-dynamicuser-supplementarygroups.service | 4 ++--
...mentarygroups-multiple-groups-default-group-user.service | 6 +++---
...exec-supplementarygroups-multiple-groups-withgid.service | 4 ++--
...exec-supplementarygroups-multiple-groups-withuid.service | 4 ++--
.../exec-supplementarygroups-single-group-user.service | 2 +-
.../exec-supplementarygroups-single-group.service | 2 +-
test/test-execute/exec-supplementarygroups.service | 4 ++--
9 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/test/test-execute/exec-dynamicuser-fixeduser-one-supplementarygroup.service b/test/test-execute/exec-dynamicuser-fixeduser-one-supplementarygroup.service
index 0c2a218be0..bbb1af5fb3 100644
--- a/test/test-execute/exec-dynamicuser-fixeduser-one-supplementarygroup.service
+++ b/test/test-execute/exec-dynamicuser-fixeduser-one-supplementarygroup.service
@@ -3,7 +3,7 @@
Description=Test DynamicUser with User= and SupplementaryGroups=
[Service]
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "1" && exit 0; done; exit 1'
ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "1"'
Type=oneshot
User=1
diff --git a/test/test-execute/exec-dynamicuser-fixeduser.service b/test/test-execute/exec-dynamicuser-fixeduser.service
index 061bbd2b93..c5828c2a93 100644
--- a/test/test-execute/exec-dynamicuser-fixeduser.service
+++ b/test/test-execute/exec-dynamicuser-fixeduser.service
@@ -3,7 +3,7 @@
Description=Test DynamicUser with User=
[Service]
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "1" && exit 0; done; exit 1'
ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "1"'
Type=oneshot
User=1
diff --git a/test/test-execute/exec-dynamicuser-supplementarygroups.service b/test/test-execute/exec-dynamicuser-supplementarygroups.service
index 53ba0ec7cb..d601af272e 100644
--- a/test/test-execute/exec-dynamicuser-supplementarygroups.service
+++ b/test/test-execute/exec-dynamicuser-supplementarygroups.service
@@ -3,8 +3,8 @@
Description=Test DynamicUser with SupplementaryGroups=
[Service]
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "1" && exit 0; done; exit 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "2" && exit 0; done; exit 1'
Type=oneshot
DynamicUser=yes
SupplementaryGroups=1 2
diff --git a/test/test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service b/test/test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service
index 4cb0326320..0ecc34441c 100644
--- a/test/test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service
+++ b/test/test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service
@@ -3,9 +3,9 @@
Description=Test for Supplementary Group with multiple groups without Group and User
[Service]
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "%G" && HAVE=1; done; test "$$HAVE" -eq 1'
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "%G" && exit 0; done; exit 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "1" && exit 0; done; exit 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "2" && exit 0; done; exit 1'
ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "%G" && test "$$(id -u)" = "%U"'
Type=oneshot
SupplementaryGroups=1 2
diff --git a/test/test-execute/exec-supplementarygroups-multiple-groups-withgid.service b/test/test-execute/exec-supplementarygroups-multiple-groups-withgid.service
index e11743d754..cd1021bbdf 100644
--- a/test/test-execute/exec-supplementarygroups-multiple-groups-withgid.service
+++ b/test/test-execute/exec-supplementarygroups-multiple-groups-withgid.service
@@ -3,8 +3,8 @@
Description=Test for Supplementary Group with multiple groups and Group=1
[Service]
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "1" && exit 0; done; exit 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "2" && exit 0; done; exit 1'
ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "%U"'
Type=oneshot
Group=1
diff --git a/test/test-execute/exec-supplementarygroups-multiple-groups-withuid.service b/test/test-execute/exec-supplementarygroups-multiple-groups-withuid.service
index 3efbbfb0f9..7913a2c2ed 100644
--- a/test/test-execute/exec-supplementarygroups-multiple-groups-withuid.service
+++ b/test/test-execute/exec-supplementarygroups-multiple-groups-withuid.service
@@ -3,8 +3,8 @@
Description=Test for Supplementary Group with multiple groups and Uid=1
[Service]
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "1" && exit 0; done; exit 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "2" && exit 0; done; exit 1'
Type=oneshot
User=1
SupplementaryGroups=1 2
diff --git a/test/test-execute/exec-supplementarygroups-single-group-user.service b/test/test-execute/exec-supplementarygroups-single-group-user.service
index aae71d0a30..ee4017e74e 100644
--- a/test/test-execute/exec-supplementarygroups-single-group-user.service
+++ b/test/test-execute/exec-supplementarygroups-single-group-user.service
@@ -3,7 +3,7 @@
Description=Test for Supplementary Group with only one group and uid 1
[Service]
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "1" && exit 0; done; exit 1'
ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "1"'
Type=oneshot
User=1
diff --git a/test/test-execute/exec-supplementarygroups-single-group.service b/test/test-execute/exec-supplementarygroups-single-group.service
index c870774382..62275201cc 100644
--- a/test/test-execute/exec-supplementarygroups-single-group.service
+++ b/test/test-execute/exec-supplementarygroups-single-group.service
@@ -3,7 +3,7 @@
Description=Test for Supplementary Group with only one group
[Service]
-ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "1" && exit 0; done; exit 1'
ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "0"'
Type=oneshot
Group=1
diff --git a/test/test-execute/exec-supplementarygroups.service b/test/test-execute/exec-supplementarygroups.service
index 75601eab57..03406c3ee8 100644
--- a/test/test-execute/exec-supplementarygroups.service
+++ b/test/test-execute/exec-supplementarygroups.service
@@ -3,7 +3,7 @@
Description=Test for Supplementary Group
[Service]
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "%G" && HAVE=1; done; test "$$HAVE" -eq 1'
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "%G" && exit 0; done; exit 1'
+ExecStart=/bin/sh -x -c 'for g in $$(id -G); do test "$$g" = "1" && exit 0; done; exit 1'
Type=oneshot
SupplementaryGroups=1

@ -0,0 +1,34 @@
From ab6a1bdf3519d4344dee4e0225c74fc1198c8a60 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 15 Oct 2018 10:54:11 +0000
Subject: [PATCH] tests: backport test_setup_logging()
Related: #1635428
---
src/shared/tests.c | 6 ++++++
src/shared/tests.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/src/shared/tests.c b/src/shared/tests.c
index 6b3df0aa07..b10343650f 100644
--- a/src/shared/tests.c
+++ b/src/shared/tests.c
@@ -54,3 +54,9 @@ const char* get_testdata_dir(const char *suffix) {
strncpy(testdir + strlen(testdir), suffix, sizeof(testdir) - strlen(testdir) - 1);
return testdir;
}
+
+void test_setup_logging(int level) {
+ log_set_max_level(level);
+ log_parse_environment();
+ log_open();
+}
diff --git a/src/shared/tests.h b/src/shared/tests.h
index b88135ed93..cad21169f8 100644
--- a/src/shared/tests.h
+++ b/src/shared/tests.h
@@ -3,3 +3,4 @@
char* setup_fake_runtime_dir(void);
const char* get_testdata_dir(const char *suffix);
+void test_setup_logging(int level);

@ -1,29 +0,0 @@
From 6d8f91ab2f7db862d95d0565bad3aaf4279c00bc Mon Sep 17 00:00:00 2001
From: Luca Boccassi <bluca@debian.org>
Date: Thu, 3 Nov 2022 20:10:57 +0000
Subject: [PATCH] tmpfiles.d: do not fail if provision.conf fails
On a read-only filesystem creating /root/.ssh might fail, but that's ok.
Do not fail the run, as this is only needed to add the credential, which
is a separate step.
(cherry picked from commit e0fc9be37e4d15e2c322eb8281692c2639dac023)
Related #2138081
---
tmpfiles.d/provision.conf | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tmpfiles.d/provision.conf b/tmpfiles.d/provision.conf
index 3c56f42d58..093104aaaf 100644
--- a/tmpfiles.d/provision.conf
+++ b/tmpfiles.d/provision.conf
@@ -17,6 +17,6 @@ f^ /etc/issue.d/50-provision.conf - - - - login.issue
f^ /etc/hosts - - - - network.hosts
# Provision SSH key for root
-d /root :0700 root :root -
-d /root/.ssh :0700 root :root -
+d- /root :0700 root :root -
+d- /root/.ssh :0700 root :root -
f^ /root/.ssh/authorized_keys :0600 root :root - ssh.authorized_keys.root

@ -0,0 +1,23 @@
From 80d5f0e2057717e9e5588edcabac95b8c238795c Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 15 Oct 2018 10:55:50 +0000
Subject: [PATCH] journal: change support URL shown in the catalog entries
Resolves: #1550548
---
meson_options.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/meson_options.txt b/meson_options.txt
index 16c1f2b2fa..ab2a658713 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -205,7 +205,7 @@ option('ntp-servers', type : 'string',
value : 'time1.google.com time2.google.com time3.google.com time4.google.com')
option('support-url', type : 'string',
description : 'the support URL to show in catalog entries included in systemd',
- value : 'https://lists.freedesktop.org/mailman/listinfo/systemd-devel')
+ value : 'https://access.redhat.com/support')
option('www-target', type : 'string',
description : 'the address and dir to upload docs too',
value : 'www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd')

@ -1,31 +0,0 @@
From d3b559f5e561750e6c50449b2ca84b40abeb492d Mon Sep 17 00:00:00 2001
From: Antonio Alvarez Feijoo <antonio.feijoo@suse.com>
Date: Fri, 4 Nov 2022 09:57:24 +0100
Subject: [PATCH] kernel-install/90-loaderentry: do not add multiple
systemd.machine_id options
Do not unconditionally add a new systemd.machine_id command line option, first
check if it already exists with the expected value.
Fixes #25203
(cherry picked from commit 981502c5cc9ce32c3f77ff74aad87cd6f0da3b16)
Related #2138081
---
src/kernel-install/90-loaderentry.install | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install
index 743af33aa9..ea75e1b0d8 100755
--- a/src/kernel-install/90-loaderentry.install
+++ b/src/kernel-install/90-loaderentry.install
@@ -85,7 +85,7 @@ BOOT_OPTIONS="${BOOT_OPTIONS% }"
# command line with the machine ID we use, so that the machine ID remains
# stable, even during factory reset, in the initrd (where the system's machine
# ID is not directly accessible yet), and if the root file system is volatile.
-if [ "$ENTRY_TOKEN" = "$MACHINE_ID" ]; then
+if [ "$ENTRY_TOKEN" = "$MACHINE_ID" ] && ! echo "$BOOT_OPTIONS" | grep -q "systemd.machine_id=$MACHINE_ID"; then
BOOT_OPTIONS="$BOOT_OPTIONS systemd.machine_id=$MACHINE_ID"
fi

@ -1,120 +0,0 @@
From 1b7dfe48d6d66cad5d0368b8e8b387a4d9586ccd Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
Date: Thu, 27 Oct 2022 11:12:10 +0200
Subject: [PATCH] condition: Check that subsystem is enabled in
ConditionSecurity=tpm2
Instead of succeeding when either the firmware reports a TPM device
or we find a TPM device, let's check that the firmware reports a TPM
device and the TPM subsystem is enabled in the kernel.
To check whether the subsystem enabled, we check if the relevant
subdirectory in /sys exists at all.
(cherry picked from commit 300bba79c22e4be1effe2faad0e59ac725d396a1)
Related #2138081
---
man/systemd-creds.xml | 4 ++--
src/creds/creds.c | 6 ++++--
src/shared/condition.c | 9 ++++-----
src/shared/tpm2-util.c | 6 +++++-
src/shared/tpm2-util.h | 11 ++++++-----
5 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/man/systemd-creds.xml b/man/systemd-creds.xml
index 1e5632e63d..003fbcd463 100644
--- a/man/systemd-creds.xml
+++ b/man/systemd-creds.xml
@@ -175,8 +175,8 @@
by the OS kernel drivers and by userspace (i.e. systemd) this prints <literal>yes</literal> and exits
with exit status zero. If no such device is discovered/supported/used, prints
<literal>no</literal>. Otherwise prints <literal>partial</literal>. In either of these two cases
- exits with non-zero exit status. It also shows three lines indicating separately whether drivers,
- firmware and the system discovered/support/use TPM2.</para>
+ exits with non-zero exit status. It also shows four lines indicating separately whether firmware,
+ drivers, the system and the kernel discovered/support/use TPM2.</para>
<para>Combine with <option>--quiet</option> to suppress the output.</para></listitem>
</varlistentry>
diff --git a/src/creds/creds.c b/src/creds/creds.c
index 5586fd776a..a755a52c34 100644
--- a/src/creds/creds.c
+++ b/src/creds/creds.c
@@ -637,10 +637,12 @@ static int verb_has_tpm2(int argc, char **argv, void *userdata) {
printf("%sfirmware\n"
"%sdriver\n"
- "%ssystem\n",
+ "%ssystem\n"
+ "%ssubsystem\n",
plus_minus(s & TPM2_SUPPORT_FIRMWARE),
plus_minus(s & TPM2_SUPPORT_DRIVER),
- plus_minus(s & TPM2_SUPPORT_SYSTEM));
+ plus_minus(s & TPM2_SUPPORT_SYSTEM),
+ plus_minus(s & TPM2_SUPPORT_SUBSYSTEM));
}
/* Return inverted bit flags. So that TPM2_SUPPORT_FULL becomes EXIT_SUCCESS and the other values
diff --git a/src/shared/condition.c b/src/shared/condition.c
index 310ffcbdc6..a23d6a3e45 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -664,14 +664,13 @@ static int condition_test_ac_power(Condition *c, char **env) {
}
static int has_tpm2(void) {
- /* Checks whether the system has at least one TPM2 resource manager device, i.e. at least one "tpmrm"
- * class device. Alternatively, we are also happy if the firmware reports support (this is to cover
- * for cases where we simply haven't loaded the driver for it yet, i.e. during early boot where we
- * very likely want to use this condition check).
+ /* Checks whether the kernel has the TPM subsystem enabled and the firmware reports support. Note
+ * we don't check for actual TPM devices, since we might not have loaded the driver for it yet, i.e.
+ * during early boot where we very likely want to use this condition check).
*
* Note that we don't check if we ourselves are built with TPM2 support here! */
- return (tpm2_support() & (TPM2_SUPPORT_DRIVER|TPM2_SUPPORT_FIRMWARE)) != 0;
+ return FLAGS_SET(tpm2_support(), TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_FIRMWARE);
}
static int condition_test_security(Condition *c, char **env) {
diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
index 13e92c4144..65e8d48347 100644
--- a/src/shared/tpm2-util.c
+++ b/src/shared/tpm2-util.c
@@ -2189,7 +2189,11 @@ Tpm2Support tpm2_support(void) {
if (r != -ENOENT)
log_debug_errno(r, "Unable to test whether /sys/class/tpmrm/ exists and is populated, assuming it is not: %m");
} else if (r == 0) /* populated! */
- support |= TPM2_SUPPORT_DRIVER;
+ support |= TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_DRIVER;
+ else
+ /* If the directory exists but is empty, we know the subsystem is enabled but no
+ * driver has been loaded yet. */
+ support |= TPM2_SUPPORT_SUBSYSTEM;
}
if (efi_has_tpm2())
diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h
index 048c28d6ca..c240335ae6 100644
--- a/src/shared/tpm2-util.h
+++ b/src/shared/tpm2-util.h
@@ -137,11 +137,12 @@ typedef struct {
typedef enum Tpm2Support {
/* NOTE! The systemd-creds tool returns these flags 1:1 as exit status. Hence these flags are pretty
* much ABI! Hence, be extra careful when changing/extending these definitions. */
- TPM2_SUPPORT_NONE = 0, /* no support */
- TPM2_SUPPORT_FIRMWARE = 1 << 0, /* firmware reports TPM2 was used */
- TPM2_SUPPORT_DRIVER = 1 << 1, /* the kernel has a driver loaded for it */
- TPM2_SUPPORT_SYSTEM = 1 << 2, /* we support it ourselves */
- TPM2_SUPPORT_FULL = TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER|TPM2_SUPPORT_SYSTEM,
+ TPM2_SUPPORT_NONE = 0, /* no support */
+ TPM2_SUPPORT_FIRMWARE = 1 << 0, /* firmware reports TPM2 was used */
+ TPM2_SUPPORT_DRIVER = 1 << 1, /* the kernel has a driver loaded for it */
+ TPM2_SUPPORT_SYSTEM = 1 << 2, /* we support it ourselves */
+ TPM2_SUPPORT_SUBSYSTEM = 1 << 3, /* the kernel has the tpm subsystem enabled */
+ TPM2_SUPPORT_FULL = TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER|TPM2_SUPPORT_SYSTEM|TPM2_SUPPORT_SUBSYSTEM,
} Tpm2Support;
Tpm2Support tpm2_support(void);

@ -0,0 +1,48 @@
From e0f2dd42fb02aa5767d38714c95ac10fb683ad67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Fri, 11 Mar 2016 17:06:17 -0500
Subject: [PATCH] resolved: create /etc/resolv.conf symlink at runtime
If the symlink doesn't exists, and we are being started, let's
create it to provie name resolution.
If it exists, do nothing. In particular, if it is a broken symlink,
we cannot really know if the administator configured it to point to
a location used by some service that hasn't started yet, so we
don't touch it in that case either.
https://bugzilla.redhat.com/show_bug.cgi?id=1313085
---
src/resolve/resolved.c | 4 ++++
tmpfiles.d/etc.conf.m4 | 3 ---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
index c01e53e9da..f3d96df458 100644
--- a/src/resolve/resolved.c
+++ b/src/resolve/resolved.c
@@ -53,6 +53,10 @@ int main(int argc, char *argv[]) {
/* Drop privileges, but only if we have been started as root. If we are not running as root we assume all
* privileges are already dropped. */
if (getuid() == 0) {
+ r = symlink("../run/systemd/resolve/resolv.conf", "/etc/resolv.conf");
+ if (r < 0 && errno != EEXIST)
+ log_warning_errno(errno,
+ "Could not create /etc/resolv.conf symlink: %m");
/* Drop privileges, but keep three caps. Note that we drop those too, later on (see below) */
r = drop_privileges(uid, gid,
diff --git a/tmpfiles.d/etc.conf.m4 b/tmpfiles.d/etc.conf.m4
index df8d42101c..928105ea8d 100644
--- a/tmpfiles.d/etc.conf.m4
+++ b/tmpfiles.d/etc.conf.m4
@@ -13,9 +13,6 @@ L+ /etc/mtab - - - - ../proc/self/mounts
m4_ifdef(`HAVE_SMACK_RUN_LABEL',
t /etc/mtab - - - - security.SMACK64=_
)m4_dnl
-m4_ifdef(`ENABLE_RESOLVE',
-L! /etc/resolv.conf - - - - ../run/systemd/resolve/stub-resolv.conf
-)m4_dnl
C /etc/nsswitch.conf - - - -
m4_ifdef(`HAVE_PAM',
C /etc/pam.d - - - -

@ -0,0 +1,27 @@
From e615b80f3fda82ac7fe628800a9ff2103788bd05 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Tue, 9 Oct 2018 13:50:55 +0200
Subject: [PATCH] dissect-image: use right comparison function
fstype can be NULL here.
(cherry picked from commit 4db1879acdc0b853e1a7e6e650b6feb917175fac)
Resolves: #1602706
---
src/shared/dissect-image.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index fa1cf26ee1..e076c8e7db 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -230,7 +230,7 @@ int dissect_image(
.node = TAKE_PTR(n),
};
- m->encrypted = streq(fstype, "crypto_LUKS");
+ m->encrypted = streq_ptr(fstype, "crypto_LUKS");
*ret = TAKE_PTR(m);

@ -1,52 +0,0 @@
From f0839034c9910529f368e60262b5653afad58f63 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Mon, 7 Nov 2022 16:39:12 +0100
Subject: [PATCH] semaphore: remove the Semaphore repositories recursively
The list of disabled repositories was recently converted from a single
file into a directory with separate repository files, so let's adjust
the setup script accordingly.
```
$ ls -lR /etc/apt/sources.list.d/
/etc/apt/sources.list.d/:
total 36
-rw-r--r-- 1 root root 76 Nov 3 10:28 azure-cli.list
-rw-r--r-- 1 root root 72 Nov 3 10:22 bazel.list
drwxr-xr-x 2 root root 4096 Nov 3 10:31 disabled
-rw-r--r-- 1 root root 113 Nov 3 10:13 docker-source.list
-rw-r--r-- 1 root root 367 Nov 3 10:28 github_git-lfs.list
-rw-r--r-- 1 root root 111 Nov 3 10:25 google-chrome-source.list
-rw-r--r-- 1 root root 64 Nov 3 10:14 google-cloud-sdk.list
-rw-r--r-- 1 root root 54 Nov 3 10:23 helm-stable-debian.list
-rw-r--r-- 1 root root 89 Nov 3 10:29 yarn-source.list
/etc/apt/sources.list.d/disabled:
total 20
-rw-r--r-- 1 root root 100 Nov 3 10:23 devel_kubic_libcontainers_stable.list
-rw-r--r-- 1 root root 103 Nov 3 10:27 git.list
-rw-r--r-- 1 root root 105 Nov 3 10:22 gradle.list
-rw-r--r-- 1 root root 118 Nov 3 10:13 pypy.list
-rw-r--r-- 1 root root 104 Nov 3 10:13 python.list
```
(cherry picked from commit 610eb3f8260ecbb161db5186a5e27417f3110a68)
Related #2138081
---
.semaphore/semaphore-runner.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.semaphore/semaphore-runner.sh b/.semaphore/semaphore-runner.sh
index 98fd7b4411..b0d32bd136 100755
--- a/.semaphore/semaphore-runner.sh
+++ b/.semaphore/semaphore-runner.sh
@@ -55,7 +55,7 @@ for phase in "${PHASES[@]}"; do
case "$phase" in
SETUP)
# remove semaphore repos, some of them don't work and cause error messages
- sudo rm -f /etc/apt/sources.list.d/*
+ sudo rm -rf /etc/apt/sources.list.d/*
# enable backports for latest LXC
echo "deb http://archive.ubuntu.com/ubuntu $UBUNTU_RELEASE-backports main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list.d/backports.list

@ -1,29 +0,0 @@
From c440081c968c93d527d441f4d106e0acad9540eb Mon Sep 17 00:00:00 2001
From: Antonio Alvarez Feijoo <antonio.feijoo@suse.com>
Date: Mon, 7 Nov 2022 15:25:25 +0100
Subject: [PATCH] kernel-install/90-loaderentry: do not override an existing
systemd.machine_id
If the systemd.machine_id command line option is already set, do not override
it.
(cherry picked from commit 802d9219aa19d759113dd6cd1e91b2bb661fe9ba)
Related #2138081
---
src/kernel-install/90-loaderentry.install | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install
index ea75e1b0d8..41a05534b9 100755
--- a/src/kernel-install/90-loaderentry.install
+++ b/src/kernel-install/90-loaderentry.install
@@ -85,7 +85,7 @@ BOOT_OPTIONS="${BOOT_OPTIONS% }"
# command line with the machine ID we use, so that the machine ID remains
# stable, even during factory reset, in the initrd (where the system's machine
# ID is not directly accessible yet), and if the root file system is volatile.
-if [ "$ENTRY_TOKEN" = "$MACHINE_ID" ] && ! echo "$BOOT_OPTIONS" | grep -q "systemd.machine_id=$MACHINE_ID"; then
+if [ "$ENTRY_TOKEN" = "$MACHINE_ID" ] && ! echo "$BOOT_OPTIONS" | grep -q "systemd.machine_id="; then
BOOT_OPTIONS="$BOOT_OPTIONS systemd.machine_id=$MACHINE_ID"
fi

@ -0,0 +1,60 @@
From 8fdca31b41a6470ceda8e0a84f90a1e5ca28aa5c Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Tue, 9 Oct 2018 17:26:19 +0200
Subject: [PATCH] login: avoid leak of name returned by uid_to_name()
(cherry picked from commit e99742ef3e9d847da04e71fec0eb426063b25068)
Resolves: #1602706
---
src/login/logind-dbus.c | 4 +++-
src/login/logind-utmp.c | 6 +++---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 13298cc855..dca7f4a30f 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2155,6 +2155,7 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
if (cancelled && m->enable_wall_messages) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+ _cleanup_free_ char *username = NULL;
const char *tty = NULL;
uid_t uid = 0;
int r;
@@ -2165,8 +2166,9 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
(void) sd_bus_creds_get_tty(creds, &tty);
}
+ username = uid_to_name(uid);
utmp_wall("The system shutdown has been cancelled",
- uid_to_name(uid), tty, logind_wall_tty_filter, m);
+ username, tty, logind_wall_tty_filter, m);
}
return sd_bus_reply_method_return(message, "b", cancelled);
diff --git a/src/login/logind-utmp.c b/src/login/logind-utmp.c
index 71ebdfcfb1..8bdd4ab6bf 100644
--- a/src/login/logind-utmp.c
+++ b/src/login/logind-utmp.c
@@ -61,7 +61,7 @@ bool logind_wall_tty_filter(const char *tty, void *userdata) {
static int warn_wall(Manager *m, usec_t n) {
char date[FORMAT_TIMESTAMP_MAX] = {};
- _cleanup_free_ char *l = NULL;
+ _cleanup_free_ char *l = NULL, *username = NULL;
usec_t left;
int r;
@@ -83,8 +83,8 @@ static int warn_wall(Manager *m, usec_t n) {
return 0;
}
- utmp_wall(l, uid_to_name(m->scheduled_shutdown_uid),
- m->scheduled_shutdown_tty, logind_wall_tty_filter, m);
+ username = uid_to_name(m->scheduled_shutdown_uid);
+ utmp_wall(l, username, m->scheduled_shutdown_tty, logind_wall_tty_filter, m);
return 1;
}

@ -0,0 +1,36 @@
From fbe394e9166ddfe847dcac0eab0fcbd3c225dc33 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Wed, 10 Oct 2018 09:33:28 +0200
Subject: [PATCH] firewall-util: add an assert that we're not overwriting a
buffer
... like commit f28501279d2c28fdbb31d8273b723e9bf71d3b98 does for
out_interface.
(cherry picked from commit 0b777d20e9a3868b12372ffce8040d1be063cec7)
Resolves: #1602706
---
src/shared/firewall-util.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/shared/firewall-util.c b/src/shared/firewall-util.c
index eb4f5ff616..cba52fb419 100644
--- a/src/shared/firewall-util.c
+++ b/src/shared/firewall-util.c
@@ -50,8 +50,14 @@ static int entry_fill_basics(
entry->ip.proto = protocol;
if (in_interface) {
+ size_t l;
+
+ l = strlen(in_interface);
+ assert(l < sizeof entry->ip.iniface);
+ assert(l < sizeof entry->ip.iniface_mask);
+
strcpy(entry->ip.iniface, in_interface);
- memset(entry->ip.iniface_mask, 0xFF, strlen(in_interface)+1);
+ memset(entry->ip.iniface_mask, 0xFF, l + 1);
}
if (source) {
entry->ip.src = source->in;

@ -1,28 +0,0 @@
From d1abf107c5b4c661886001de996bf03587bb35c1 Mon Sep 17 00:00:00 2001
From: Luca Boccassi <bluca@debian.org>
Date: Mon, 7 Nov 2022 16:28:33 +0000
Subject: [PATCH] kernel-install: skip 50-depmod if depmod is not available
Images might be built without any kernel module, and without
installing depmod as it is not needed. Skip it.
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1023607
(cherry picked from commit cda4d00dfcbcd075cef95341f8a466f0c4ee8e1d)
Related #2138081
---
src/kernel-install/50-depmod.install | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/kernel-install/50-depmod.install b/src/kernel-install/50-depmod.install
index d4b991cfd6..43bd87c7ed 100755
--- a/src/kernel-install/50-depmod.install
+++ b/src/kernel-install/50-depmod.install
@@ -26,6 +26,7 @@ KERNEL_VERSION="${2:?}"
case "$COMMAND" in
add)
[ -d "/lib/modules/$KERNEL_VERSION/kernel" ] || exit 0
+ command -v depmod >/dev/null || exit 0
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "+depmod -a $KERNEL_VERSION"
exec depmod -a "$KERNEL_VERSION"
;;

@ -0,0 +1,29 @@
From ebdb96247433d920b391672e019da9402aabd351 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Wed, 10 Oct 2018 13:56:54 +0200
Subject: [PATCH] journal-file: avoid calling ftruncate with invalid fd
This can happen if journal_file_close is called from the failure
handling code of journal_file_open before f->fd was established.
(cherry picked from commit c52368509f48e556be5a4c7a171361b656a25e02)
Resolves: #1602706
---
src/journal/journal-file.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 62e7f68a13..efc3ee052b 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1846,6 +1846,9 @@ static int journal_file_append_entry_internal(
void journal_file_post_change(JournalFile *f) {
assert(f);
+ if (f->fd < 0)
+ return;
+
/* inotify() does not receive IN_MODIFY events from file
* accesses done via mmap(). After each access we hence
* trigger IN_MODIFY by truncating the journal file to its

@ -1,38 +0,0 @@
From 04cdbacc26c7e38d3bd684235b51c79ab64b6026 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Tue, 8 Nov 2022 11:07:02 +0100
Subject: [PATCH] man: add note that network-generator is not a generator
Also fix indentation.
(cherry picked from commit 2fa6574e835566c2aa5cbf4167ecee316f71bf98)
Related #2138081
---
man/systemd-network-generator.service.xml | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/man/systemd-network-generator.service.xml b/man/systemd-network-generator.service.xml
index 6b7e2564d4..2ddeadfc54 100644
--- a/man/systemd-network-generator.service.xml
+++ b/man/systemd-network-generator.service.xml
@@ -41,10 +41,17 @@
</para>
<para>Files are generated in <filename>/run/systemd/network/</filename>.</para>
+
+ <para>Note: despite the name, this generator executes as a normal systemd service and is
+ <emphasis>not</emphasis> an implementation of the
+ <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ concept.</para>
</refsect1>
- <refsect1><title>Kernel command line options</title>
- <para>This tool understands the following options:</para>
+ <refsect1>
+ <title>Kernel command line options</title>
+
+ <para>This tool understands the following options:</para>
<variablelist class='kernel-commandline-options'>
<varlistentry>

@ -0,0 +1,33 @@
From c232bc1f346a6af9777c216d01f7940898ae1650 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 19 Oct 2018 12:12:33 +0200
Subject: [PATCH] dhcp6: make sure we have enough space for the DHCP6 option
header
Fixes a vulnerability originally discovered by Felix Wilhelm from
Google.
CVE-2018-15688
LP: #1795921
https://bugzilla.redhat.com/show_bug.cgi?id=1639067
(cherry-picked from commit 4dac5eaba4e419b29c97da38a8b1f82336c2c892)
Resolves: #1643363
---
src/libsystemd-network/dhcp6-option.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c
index 18196b1257..0979497299 100644
--- a/src/libsystemd-network/dhcp6-option.c
+++ b/src/libsystemd-network/dhcp6-option.c
@@ -103,7 +103,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
return -EINVAL;
}
- if (*buflen < len)
+ if (*buflen < offsetof(DHCP6Option, data) + len)
return -ENOBUFS;
ia_hdr = *buf;

@ -1,64 +0,0 @@
From 054da791c98fba7e11079e94c9b9fe0b1ca4e8d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Fri, 4 Nov 2022 15:48:50 +0100
Subject: [PATCH] test: fstab-generator: adjust PATH for fsck
fsck(8) is located in /usr/sib/ on Debian sid:
stdout:
*** Running /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-01-dev-nfs.input
*** Running /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-02-dhcp.input
*** Running /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-03-dhcp6.input
*** Running /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-04-nfs.input
*** Running /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-05-nfs4.input
*** Running /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-06-ipv4.input
*** Running /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-07-ipv6.input
*** Running /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-08-implicit-nfs.input
*** Running /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-09-cifs.input
*** Running /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-10-iscsi.input
*** Running /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-11-live.input
*** Running /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-12-dev-sdx.input
--- /dev/fd/63 2022-11-04 15:39:13.131532174 +0100
+++ /dev/fd/62 2022-11-04 15:39:13.131532174 +0100
@@ -6,3 +6,4 @@
initrd-usr-fs.target.requires
initrd-usr-fs.target.requires/sysroot.mount
sysroot.mount
+systemd-fsck-root.service
**** Unexpected output for /home/christian/Coding/workspaces/systemd/test/testdata/test-fstab-generator/test-12-dev-sdx.input
stderr:
Skipping root directory handling, as root on NFS was requested.
Skipping root directory handling, as root on NFS was requested.
Skipping root directory handling, as root on NFS was requested.
Skipping root directory handling, as root on NFS was requested.
Skipping root directory handling, as root on NFS was requested.
Skipping root directory handling, as root on NFS was requested.
Skipping root directory handling, as root on NFS was requested.
Skipping root directory handling, as root on NFS was requested.
Skipping root directory handling, as root on CIFS was requested.
Skipping root directory handling, as root on iSCSI was requested.
Skipping root directory handling, as root on live image was requested.
Found entry what=/dev/sdx1 where=/sysroot type=n/a opts=ro
Checking was requested for /dev/sdx1, but the fsck command does not exist.
(cherry picked from commit a45efc9e4b574a85176610496f2ac7ae769364bb)
Related #2138081
---
test/test-fstab-generator.sh | 3 +++
1 file changed, 3 insertions(+)
diff --git a/test/test-fstab-generator.sh b/test/test-fstab-generator.sh
index 0c977645e3..7c060dfac7 100755
--- a/test/test-fstab-generator.sh
+++ b/test/test-fstab-generator.sh
@@ -14,6 +14,9 @@ fi
src="$(dirname "$0")/testdata/test-fstab-generator"
+# fsck(8) is located in /usr/sbin on Debian
+PATH=$PATH:/usr/sbin
+
for f in "$src"/test-*.input; do
echo "*** Running $f"

@ -0,0 +1,133 @@
From 35a23324975ac6ee0bbd3408394f992007b7a439 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 13 Nov 2018 11:59:06 +0100
Subject: [PATCH] =?UTF-8?q?core:=20rename=20queued=5Fmessage=20=E2=86=92?=
=?UTF-8?q?=20pending=5Freload=5Fmessage?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This field is only used for pending Reload() replies, hence let's rename
it to be more descriptive and precise.
No change in behaviour.
(cherry picked from commit 209de5256b7ba8600c3e73a85a43b86708998d65)
Resolves: #1647359
---
src/core/dbus-manager.c | 4 ++--
src/core/dbus.c | 12 ++++++------
src/core/dbus.h | 2 +-
src/core/manager.c | 6 +++---
src/core/manager.h | 2 +-
5 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 4ed68af1e0..d39c9b28c4 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -1329,8 +1329,8 @@ static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *
* is finished. That way the caller knows when the reload
* finished. */
- assert(!m->queued_message);
- r = sd_bus_message_new_method_return(message, &m->queued_message);
+ assert(!m->pending_reload_message);
+ r = sd_bus_message_new_method_return(message, &m->pending_reload_message);
if (r < 0)
return r;
diff --git a/src/core/dbus.c b/src/core/dbus.c
index bf5917696e..256a410215 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -47,23 +47,23 @@
static void destroy_bus(Manager *m, sd_bus **bus);
-int bus_send_queued_message(Manager *m) {
+int bus_send_pending_reload_message(Manager *m) {
int r;
assert(m);
- if (!m->queued_message)
+ if (!m->pending_reload_message)
return 0;
/* If we cannot get rid of this message we won't dispatch any
* D-Bus messages, so that we won't end up wanting to queue
* another message. */
- r = sd_bus_send(NULL, m->queued_message, NULL);
+ r = sd_bus_send(NULL, m->pending_reload_message, NULL);
if (r < 0)
log_warning_errno(r, "Failed to send queued message: %m");
- m->queued_message = sd_bus_message_unref(m->queued_message);
+ m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message);
return 0;
}
@@ -1079,8 +1079,8 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
u->bus_track = sd_bus_track_unref(u->bus_track);
/* Get rid of queued message on this bus */
- if (m->queued_message && sd_bus_message_get_bus(m->queued_message) == *bus)
- m->queued_message = sd_bus_message_unref(m->queued_message);
+ if (m->pending_reload_message && sd_bus_message_get_bus(m->pending_reload_message) == *bus)
+ m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message);
/* Possibly flush unwritten data, but only if we are
* unprivileged, since we don't want to sync here */
diff --git a/src/core/dbus.h b/src/core/dbus.h
index 382a96da7d..f1c0fa86c0 100644
--- a/src/core/dbus.h
+++ b/src/core/dbus.h
@@ -5,7 +5,7 @@
#include "manager.h"
-int bus_send_queued_message(Manager *m);
+int bus_send_pending_reload_message(Manager *m);
int bus_init_private(Manager *m);
int bus_init_api(Manager *m);
diff --git a/src/core/manager.c b/src/core/manager.c
index 930df4e23a..a24bfcacdf 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -2078,7 +2078,7 @@ static unsigned manager_dispatch_dbus_queue(Manager *m) {
return 0;
/* Anything to do at all? */
- if (!m->dbus_unit_queue && !m->dbus_job_queue && !m->send_reloading_done && !m->queued_message)
+ if (!m->dbus_unit_queue && !m->dbus_job_queue && !m->send_reloading_done && !m->pending_reload_message)
return 0;
/* Do we have overly many messages queued at the moment? If so, let's not enqueue more on top, let's sit this
@@ -2123,8 +2123,8 @@ static unsigned manager_dispatch_dbus_queue(Manager *m) {
n++, budget--;
}
- if (budget > 0 && m->queued_message) {
- bus_send_queued_message(m);
+ if (budget > 0 && m->pending_reload_message) {
+ bus_send_pending_reload_message(m);
n++;
}
diff --git a/src/core/manager.h b/src/core/manager.h
index ea5d425030..c7f4d66ecd 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -215,7 +215,7 @@ struct Manager {
/* This is used during reloading: before the reload we queue
* the reply message here, and afterwards we send it */
- sd_bus_message *queued_message;
+ sd_bus_message *pending_reload_message;
Hashmap *watch_bus; /* D-Bus names => Unit object n:1 */

@ -1,30 +0,0 @@
From ba5d26d85d0c4250b10a46a5c9cd3a3e1f0ce43b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Fri, 4 Nov 2022 19:36:31 +0100
Subject: [PATCH] loop-util: open lock fd read-only
flock(2) works with file descriptors opened with O_RDONLY.
This affects SELinux systems where access to block devices is quite
restricted to avoid bypasses on filesystem objects.
(cherry picked from commit 3e6b7d2626de9c0faf8b34b2629e8d6d8fa85a7d)
Related #2138081
---
src/shared/loop-util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c
index 731ce29112..fb7e80b1b5 100644
--- a/src/shared/loop-util.c
+++ b/src/shared/loop-util.c
@@ -77,7 +77,7 @@ static int open_lock_fd(int primary_fd, int operation) {
assert(primary_fd >= 0);
assert(IN_SET(operation & ~LOCK_NB, LOCK_SH, LOCK_EX));
- lock_fd = fd_reopen(primary_fd, O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+ lock_fd = fd_reopen(primary_fd, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
if (lock_fd < 0)
return lock_fd;

@ -0,0 +1,36 @@
From 52a474cf15bf2b0edb449750eb63eb8cdb9a3780 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 13 Nov 2018 12:00:42 +0100
Subject: [PATCH] core: when we can't send the pending reload message, say we
ignore it in the warning we log
No change in behaviour, just better wording.
(cherry picked from commit 4b66bccab004221b903b43b4c224442bfa3e9ac7)
Resolves: #1647359
---
src/core/dbus.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/core/dbus.c b/src/core/dbus.c
index 256a410215..346a440c5d 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -55,13 +55,12 @@ int bus_send_pending_reload_message(Manager *m) {
if (!m->pending_reload_message)
return 0;
- /* If we cannot get rid of this message we won't dispatch any
- * D-Bus messages, so that we won't end up wanting to queue
- * another message. */
+ /* If we cannot get rid of this message we won't dispatch any D-Bus messages, so that we won't end up wanting
+ * to queue another message. */
r = sd_bus_send(NULL, m->pending_reload_message, NULL);
if (r < 0)
- log_warning_errno(r, "Failed to send queued message: %m");
+ log_warning_errno(r, "Failed to send queued message, ignoring: %m");
m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message);

@ -1,30 +0,0 @@
From ca92c2e035d5702f23f9a8d1cd705425b5605822 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Mon, 7 Nov 2022 11:55:29 +0100
Subject: [PATCH] test: don't ignore non-existent paths in inst_recursive()
The process substitution in the while loop hides errors raised by the
find utility, which might (and did), in turn, hide errors in test setup.
(cherry picked from commit eb5d7730e1b3b1bddecb80be37e5a4c938183f61)
Related #2138081
---
test/test-functions | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/test/test-functions b/test/test-functions
index 16d9da637b..80ce383e64 100644
--- a/test/test-functions
+++ b/test/test-functions
@@ -2773,6 +2773,10 @@ inst_recursive() {
local p item
for p in "$@"; do
+ # Make sure the source exists, as the process substitution below
+ # suppresses errors
+ stat "$p" >/dev/null || return 1
+
while read -r item; do
if [[ -d "$item" ]]; then
inst_dir "$item"

@ -0,0 +1,114 @@
From 0412acb95ffac94d5916ee19991cc7194e55953c Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 13 Nov 2018 12:48:49 +0100
Subject: [PATCH] core: make sure we don't throttle change signal generator
when a reload is pending
Fixes: #10627
(cherry picked from commit b8d381c47776ea0440af175cbe0c02cb743bde08)
Resolves: #1647359
---
src/core/manager.c | 64 ++++++++++++++++++++++++++++------------------
1 file changed, 39 insertions(+), 25 deletions(-)
diff --git a/src/core/manager.c b/src/core/manager.c
index a24bfcacdf..3b2fe11e87 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -2074,56 +2074,70 @@ static unsigned manager_dispatch_dbus_queue(Manager *m) {
assert(m);
+ /* Avoid recursion */
if (m->dispatching_dbus_queue)
return 0;
- /* Anything to do at all? */
- if (!m->dbus_unit_queue && !m->dbus_job_queue && !m->send_reloading_done && !m->pending_reload_message)
- return 0;
+ /* When we are reloading, let's not wait with generating signals, since we need to exit the manager as quickly
+ * as we can. There's no point in throttling generation of signals in that case. */
+ if (MANAGER_IS_RELOADING(m) || m->send_reloading_done || m->pending_reload_message)
+ budget = (unsigned) -1; /* infinite budget in this case */
+ else {
+ /* Anything to do at all? */
+ if (!m->dbus_unit_queue && !m->dbus_job_queue)
+ return 0;
- /* Do we have overly many messages queued at the moment? If so, let's not enqueue more on top, let's sit this
- * cycle out, and process things in a later cycle when the queues got a bit emptier. */
- if (manager_bus_n_queued_write(m) > MANAGER_BUS_BUSY_THRESHOLD)
- return 0;
+ /* Do we have overly many messages queued at the moment? If so, let's not enqueue more on top, let's
+ * sit this cycle out, and process things in a later cycle when the queues got a bit emptier. */
+ if (manager_bus_n_queued_write(m) > MANAGER_BUS_BUSY_THRESHOLD)
+ return 0;
- /* Only process a certain number of units/jobs per event loop iteration. Even if the bus queue wasn't overly
- * full before this call we shouldn't increase it in size too wildly in one step, and we shouldn't monopolize
- * CPU time with generating these messages. Note the difference in counting of this "budget" and the
- * "threshold" above: the "budget" is decreased only once per generated message, regardless how many
- * busses/direct connections it is enqueued on, while the "threshold" is applied to each queued instance of bus
- * message, i.e. if the same message is enqueued to five busses/direct connections it will be counted five
- * times. This difference in counting ("references" vs. "instances") is primarily a result of the fact that
- * it's easier to implement it this way, however it also reflects the thinking that the "threshold" should put
- * a limit on used queue memory, i.e. space, while the "budget" should put a limit on time. Also note that
- * the "threshold" is currently chosen much higher than the "budget". */
- budget = MANAGER_BUS_MESSAGE_BUDGET;
+ /* Only process a certain number of units/jobs per event loop iteration. Even if the bus queue wasn't
+ * overly full before this call we shouldn't increase it in size too wildly in one step, and we
+ * shouldn't monopolize CPU time with generating these messages. Note the difference in counting of
+ * this "budget" and the "threshold" above: the "budget" is decreased only once per generated message,
+ * regardless how many busses/direct connections it is enqueued on, while the "threshold" is applied to
+ * each queued instance of bus message, i.e. if the same message is enqueued to five busses/direct
+ * connections it will be counted five times. This difference in counting ("references"
+ * vs. "instances") is primarily a result of the fact that it's easier to implement it this way,
+ * however it also reflects the thinking that the "threshold" should put a limit on used queue memory,
+ * i.e. space, while the "budget" should put a limit on time. Also note that the "threshold" is
+ * currently chosen much higher than the "budget". */
+ budget = MANAGER_BUS_MESSAGE_BUDGET;
+ }
m->dispatching_dbus_queue = true;
- while (budget > 0 && (u = m->dbus_unit_queue)) {
+ while (budget != 0 && (u = m->dbus_unit_queue)) {
assert(u->in_dbus_queue);
bus_unit_send_change_signal(u);
- n++, budget--;
+ n++;
+
+ if (budget != (unsigned) -1)
+ budget--;
}
- while (budget > 0 && (j = m->dbus_job_queue)) {
+ while (budget != 0 && (j = m->dbus_job_queue)) {
assert(j->in_dbus_queue);
bus_job_send_change_signal(j);
- n++, budget--;
+ n++;
+
+ if (budget != (unsigned) -1)
+ budget--;
}
m->dispatching_dbus_queue = false;
- if (budget > 0 && m->send_reloading_done) {
+ if (m->send_reloading_done) {
m->send_reloading_done = false;
bus_manager_send_reloading(m, false);
- n++, budget--;
+ n++;
}
- if (budget > 0 && m->pending_reload_message) {
+ if (m->pending_reload_message) {
bus_send_pending_reload_message(m);
n++;
}

@ -1,46 +0,0 @@
From ea8b80cdc0dfd0ad92301a0e421df4d3110fe09c Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Mon, 7 Nov 2022 11:57:59 +0100
Subject: [PATCH] test: fix locale installation when locale-gen is used
locale-gen might merge all compiled locales into a simple archive, so we
need to install it as well if necessary.
(cherry picked from commit 0c416ea01bc14adff10f4fc5415a36bd2d48f604)
Related #2138081
---
test/test-functions | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/test/test-functions b/test/test-functions
index 80ce383e64..45ca472916 100644
--- a/test/test-functions
+++ b/test/test-functions
@@ -1988,14 +1988,19 @@ install_locales() {
inst /usr/share/i18n/SUPPORTED || :
inst_recursive /usr/share/i18n/charmaps
inst_recursive /usr/share/i18n/locales
- inst_recursive /usr/share/locale/en
- inst_recursive /usr/share/locale/en_*
+ inst_recursive /usr/share/locale/en*
+ inst_recursive /usr/share/locale/de*
+ image_install /usr/share/locale/locale.alias
+ # locale-gen might either generate each locale separately or merge them
+ # into a single archive
+ if ! (inst_recursive /usr/lib/locale/C.*8 /usr/lib/locale/en_*8 ||
+ image_install /usr/lib/locale/locale-archive); then
+ dfatal "Failed to install required locales"
+ exit 1
+ fi
+ else
+ inst_recursive /usr/lib/locale/C.*8 /usr/lib/locale/en_*8
fi
-
- inst_recursive /usr/lib/locale/C.utf8
- inst_recursive /usr/lib/locale/C.UTF-8
- inst_recursive /usr/lib/locale/en_*.utf8
- inst_recursive /usr/lib/locale/en_*.UTF-8
}
# shellcheck disable=SC2120

@ -0,0 +1,45 @@
From 84b15a8a493424efa8c9eaa9a44a23c3c59742bd Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Thu, 25 Oct 2018 16:21:26 +0200
Subject: [PATCH] proc-cmdline: introduce PROC_CMDLINE_RD_STRICT
Our current set of flags allows an option to be either
use just in initrd or both in initrd and normal system.
This new flag is intended to be used in the case where
you want apply some settings just in initrd or just
in normal system.
(cherry picked from commit ed58820d7669971762dd887dc117d922c23f2543)
Related: #1643429
---
src/basic/proc-cmdline.c | 3 ++-
src/basic/proc-cmdline.h | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c
index add481c2ae..530ac37460 100644
--- a/src/basic/proc-cmdline.c
+++ b/src/basic/proc-cmdline.c
@@ -72,7 +72,8 @@ int proc_cmdline_parse(proc_cmdline_parse_t parse_item, void *data, unsigned fla
if (flags & PROC_CMDLINE_STRIP_RD_PREFIX)
key = q;
- }
+ } else if (in_initrd() && flags & PROC_CMDLINE_RD_STRICT)
+ continue;
value = strchr(key, '=');
if (value)
diff --git a/src/basic/proc-cmdline.h b/src/basic/proc-cmdline.h
index 4a9e6e0f62..140200dbf4 100644
--- a/src/basic/proc-cmdline.h
+++ b/src/basic/proc-cmdline.h
@@ -8,6 +8,7 @@
enum {
PROC_CMDLINE_STRIP_RD_PREFIX = 1,
PROC_CMDLINE_VALUE_OPTIONAL = 2,
+ PROC_CMDLINE_RD_STRICT = 4
};
typedef int (*proc_cmdline_parse_t)(const char *key, const char *value, void *data);

@ -1,71 +0,0 @@
From bec9d65390249d4e88f5095e751283645a2a4c08 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Mon, 7 Nov 2022 12:07:27 +0100
Subject: [PATCH] test: fix keymaps installation on Arch
Where the keymaps live under /usr/share/kbd/keymaps/.
(cherry picked from commit 1edad89399e7cbee230878589ac618103c157ec7)
Related #2138081
---
test/test-functions | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/test/test-functions b/test/test-functions
index 45ca472916..194cd682bb 100644
--- a/test/test-functions
+++ b/test/test-functions
@@ -2007,7 +2007,8 @@ install_locales() {
install_keymaps() {
local i p
local -a prefix=(
- "/usr"
+ "/usr/lib"
+ "/usr/share"
)
dinfo "Install console keymaps"
@@ -2016,7 +2017,7 @@ install_keymaps() {
&& [[ "$(meson configure "${BUILD_DIR:?}" | grep 'split-usr' | awk '{ print $2 }')" == "true" ]] \
|| [[ ! -L /lib ]]; then
prefix+=(
- ""
+ "/lib"
)
fi
@@ -2025,12 +2026,12 @@ install_keymaps() {
# The first three paths may be deprecated.
# It seems now the last three paths are used by many distributions.
for i in \
- "$p"/lib/kbd/keymaps/include/* \
- "$p"/lib/kbd/keymaps/i386/include/* \
- "$p"/lib/kbd/keymaps/i386/qwerty/us.* \
- "$p"/lib/kbd/keymaps/legacy/include/* \
- "$p"/lib/kbd/keymaps/legacy/i386/qwerty/us.* \
- "$p"/lib/kbd/keymaps/xkb/us*; do
+ "$p"/kbd/keymaps/include/* \
+ "$p"/kbd/keymaps/i386/include/* \
+ "$p"/kbd/keymaps/i386/qwerty/us.* \
+ "$p"/kbd/keymaps/legacy/include/* \
+ "$p"/kbd/keymaps/legacy/i386/qwerty/us.* \
+ "$p"/kbd/keymaps/xkb/us*; do
[[ -f "$i" ]] || continue
inst "$i"
done
@@ -2039,10 +2040,10 @@ install_keymaps() {
# When it takes any argument, then install more keymaps.
for p in "${prefix[@]}"; do
for i in \
- "$p"/lib/kbd/keymaps/include/* \
- "$p"/lib/kbd/keymaps/i386/*/* \
- "$p"/lib/kbd/keymaps/legacy/i386/*/* \
- "$p"/lib/kbd/keymaps/xkb/*; do
+ "$p"/kbd/keymaps/include/* \
+ "$p"/kbd/keymaps/i386/*/* \
+ "$p"/kbd/keymaps/legacy/i386/*/* \
+ "$p"/kbd/keymaps/xkb/*; do
[[ -f "$i" ]] || continue
inst "$i"
done

@ -0,0 +1,77 @@
From 55798355455b9255458d6a705f8766c4dbe3ef73 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Thu, 25 Oct 2018 16:34:00 +0200
Subject: [PATCH] debug-generator: introduce rd.* version of all options
(cherry picked from commit a7dd6d04b07f58df5c0294743d76df0be0b4b928)
Resolves: #1643429
---
man/systemd-debug-generator.xml | 27 +++++++++++++++++++--------
src/debug-generator/debug-generator.c | 2 +-
2 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/man/systemd-debug-generator.xml b/man/systemd-debug-generator.xml
index d5cf4109b0..fa88e8ac01 100644
--- a/man/systemd-debug-generator.xml
+++ b/man/systemd-debug-generator.xml
@@ -33,27 +33,38 @@
that reads the kernel command line and understands three
options:</para>
- <para>If the <option>systemd.mask=</option> option is specified
- and followed by a unit name, this unit is masked for the runtime,
- similar to the effect of
+ <para>If the <option>systemd.mask=</option> or <option>rd.systemd.mask=</option>
+ option is specified and followed by a unit name, this unit is
+ masked for the runtime, similar to the effect of
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
<command>mask</command> command. This is useful to boot with
certain units removed from the initial boot transaction for
- debugging system startup. May be specified more than once.</para>
+ debugging system startup. May be specified more than once.
+ <option>rd.systemd.mask=</option> is honored only by initial
+ RAM disk (initrd) while <option>systemd.mask=</option> is
+ honored only in the main system.</para>
- <para>If the <option>systemd.wants=</option> option is specified
+ <para>If the <option>systemd.wants=</option> or
+ <option>rd.systemd.wants=</option> option is specified
and followed by a unit name, a start job for this unit is added to
the initial transaction. This is useful to start one or more
- additional units at boot. May be specified more than once.</para>
+ additional units at boot. May be specified more than once.
+ <option>rd.systemd.wants=</option> is honored only by initial
+ RAM disk (initrd) while <option>systemd.wants=</option> is
+ honored only in the main system.</para>
- <para>If the <option>systemd.debug_shell</option> option is
+ <para>If the <option>systemd.debug_shell</option> or
+ <option>rd.systemd.debug_shell</option> option is
specified, the debug shell service
<literal>debug-shell.service</literal> is pulled into the boot
transaction. It will spawn a debug shell on tty9 during early
system startup. Note that the shell may also be turned on
persistently by enabling it with
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
- <command>enable</command> command.</para>
+ <command>enable</command> command.
+ <option>rd.systemd.debug_shell=</option> is honored only by initial
+ RAM disk (initrd) while <option>systemd.debug_shell</option> is
+ honored only in the main system.</para>
<para><filename>systemd-debug-generator</filename> implements
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c
index dd6ab94fa2..800d31cebe 100644
--- a/src/debug-generator/debug-generator.c
+++ b/src/debug-generator/debug-generator.c
@@ -154,7 +154,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_RD_STRICT | PROC_CMDLINE_STRIP_RD_PREFIX);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");

@ -1,43 +0,0 @@
From d63a1edb6bef959e8d6a481464a809badcc3a2eb Mon Sep 17 00:00:00 2001
From: Torsten Hilbrich <torsten.hilbrich@secunet.com>
Date: Mon, 7 Nov 2022 08:38:58 +0100
Subject: [PATCH] test: compile test-utmp.c only if UTMP is enabled
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When compiling with -D utmp=false the compilation fails with:
../../git/systemd/src/test/test-utmp.c: In function test_dump_run_utmp:
../../git/systemd/src/test/test-utmp.c:21:9: error: cleanup argument not a function
21 | _unused_ _cleanup_(utxent_cleanup) bool utmpx = false;
| ^~~~~~~~
../../git/systemd/src/test/test-utmp.c:23:17: error: implicit declaration of function utxent_start [-Werror=implicit-function-declaration]
23 | utmpx = utxent_start();
| ^~~~~~~~~~~~
any many other errors
Add a conditional to compile test-utmp.c only if ENABLE_UTMP is true.
(cherry picked from commit 41cac2a8b98fc5faebe942c697b17e109822342d)
Related: #2138081
---
src/test/meson.build | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/test/meson.build b/src/test/meson.build
index 86fc1d4fc0..2a4dfe26db 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -622,7 +622,8 @@ tests += [
[files('test-journal-importer.c')],
- [files('test-utmp.c')],
+ [files('test-utmp.c'),
+ [], [], [], 'ENABLE_UTMP'],
[files('test-udev.c'),
[libudevd_core,

@ -1,19 +0,0 @@
From d9328ee5e53d1901af9396ae3e0b2dd05f731781 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 14 Nov 2022 09:25:37 +0100
Subject: [PATCH] Create CNAME
Related: #2138081
---
docs/CNAME | 1 +
1 file changed, 1 insertion(+)
create mode 100644 docs/CNAME
diff --git a/docs/CNAME b/docs/CNAME
new file mode 100644
index 0000000000..cdcf4d9a52
--- /dev/null
+++ b/docs/CNAME
@@ -0,0 +1 @@
+systemd.io
\ No newline at end of file

@ -0,0 +1,213 @@
From 107d75ca9394481bd045385fc45f2ee65b30ad16 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 19 Oct 2018 11:26:59 +0200
Subject: [PATCH] chown-recursive: let's rework the recursive logic to use
O_PATH
That way we can pin a specific inode and analyze it and manipulate it
without it being swapped out beneath our hands.
Fixes a vulnerability originally found by Jann Horn from Google.
CVE-2018-15687
LP: #1796692
https://bugzilla.redhat.com/show_bug.cgi?id=1639076
(cherry-picked from commit 5de6cce58b3e8b79239b6e83653459d91af6e57c)
Resolves: #1643368
---
src/core/chown-recursive.c | 146 ++++++++++++++++++-------------------
1 file changed, 70 insertions(+), 76 deletions(-)
diff --git a/src/core/chown-recursive.c b/src/core/chown-recursive.c
index c4794501c2..27c64489b5 100644
--- a/src/core/chown-recursive.c
+++ b/src/core/chown-recursive.c
@@ -1,17 +1,19 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-#include <sys/types.h>
-#include <sys/stat.h>
#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
-#include "user-util.h"
-#include "macro.h"
-#include "fd-util.h"
-#include "dirent-util.h"
#include "chown-recursive.h"
+#include "dirent-util.h"
+#include "fd-util.h"
+#include "macro.h"
+#include "stdio-util.h"
+#include "strv.h"
+#include "user-util.h"
-static int chown_one(int fd, const char *name, const struct stat *st, uid_t uid, gid_t gid) {
- int r;
+static int chown_one(int fd, const struct stat *st, uid_t uid, gid_t gid) {
+ char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
assert(fd >= 0);
assert(st);
@@ -20,90 +22,82 @@ static int chown_one(int fd, const char *name, const struct stat *st, uid_t uid,
(!gid_is_valid(gid) || st->st_gid == gid))
return 0;
- if (name)
- r = fchownat(fd, name, uid, gid, AT_SYMLINK_NOFOLLOW);
- else
- r = fchown(fd, uid, gid);
- if (r < 0)
- return -errno;
+ /* We change ownership through the /proc/self/fd/%i path, so that we have a stable reference that works with
+ * O_PATH. (Note: fchown() and fchmod() do not work with O_PATH, the kernel refuses that. */
+ xsprintf(procfs_path, "/proc/self/fd/%i", fd);
- /* The linux kernel alters the mode in some cases of chown(). Let's undo this. */
- if (name) {
- if (!S_ISLNK(st->st_mode))
- r = fchmodat(fd, name, st->st_mode, 0);
- else /* There's currently no AT_SYMLINK_NOFOLLOW for fchmodat() */
- r = 0;
- } else
- r = fchmod(fd, st->st_mode);
- if (r < 0)
+ if (chown(procfs_path, uid, gid) < 0)
return -errno;
+ /* The linux kernel alters the mode in some cases of chown(). Let's undo this. We do this only for non-symlinks
+ * however. That's because for symlinks the access mode is ignored anyway and because on some kernels/file
+ * systems trying to change the access mode will succeed but has no effect while on others it actively
+ * fails. */
+ if (!S_ISLNK(st->st_mode))
+ if (chmod(procfs_path, st->st_mode & 07777) < 0)
+ return -errno;
+
return 1;
}
static int chown_recursive_internal(int fd, const struct stat *st, uid_t uid, gid_t gid) {
+ _cleanup_closedir_ DIR *d = NULL;
bool changed = false;
+ struct dirent *de;
int r;
assert(fd >= 0);
assert(st);
- if (S_ISDIR(st->st_mode)) {
- _cleanup_closedir_ DIR *d = NULL;
- struct dirent *de;
-
- d = fdopendir(fd);
- if (!d) {
- r = -errno;
- goto finish;
- }
- fd = -1;
-
- FOREACH_DIRENT_ALL(de, d, r = -errno; goto finish) {
- struct stat fst;
-
- if (dot_or_dot_dot(de->d_name))
- continue;
-
- if (fstatat(dirfd(d), de->d_name, &fst, AT_SYMLINK_NOFOLLOW) < 0) {
- r = -errno;
- goto finish;
- }
-
- if (S_ISDIR(fst.st_mode)) {
- int subdir_fd;
-
- subdir_fd = openat(dirfd(d), de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
- if (subdir_fd < 0) {
- r = -errno;
- goto finish;
- }
-
- r = chown_recursive_internal(subdir_fd, &fst, uid, gid);
- if (r < 0)
- goto finish;
- if (r > 0)
- changed = true;
- } else {
- r = chown_one(dirfd(d), de->d_name, &fst, uid, gid);
- if (r < 0)
- goto finish;
- if (r > 0)
- changed = true;
- }
+ d = fdopendir(fd);
+ if (!d) {
+ safe_close(fd);
+ return -errno;
+ }
+
+ FOREACH_DIRENT_ALL(de, d, return -errno) {
+ _cleanup_close_ int path_fd = -1;
+ struct stat fst;
+
+ if (dot_or_dot_dot(de->d_name))
+ continue;
+
+ /* Let's pin the child inode we want to fix now with an O_PATH fd, so that it cannot be swapped out
+ * while we manipulate it. */
+ path_fd = openat(dirfd(d), de->d_name, O_PATH|O_CLOEXEC|O_NOFOLLOW);
+ if (path_fd < 0)
+ return -errno;
+
+ if (fstat(path_fd, &fst) < 0)
+ return -errno;
+
+ if (S_ISDIR(fst.st_mode)) {
+ int subdir_fd;
+
+ /* Convert it to a "real" (i.e. non-O_PATH) fd now */
+ subdir_fd = fd_reopen(path_fd, O_RDONLY|O_CLOEXEC|O_NOATIME);
+ if (subdir_fd < 0)
+ return subdir_fd;
+
+ r = chown_recursive_internal(subdir_fd, &fst, uid, gid); /* takes possession of subdir_fd even on failure */
+ if (r < 0)
+ return r;
+ if (r > 0)
+ changed = true;
+ } else {
+ r = chown_one(path_fd, &fst, uid, gid);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ changed = true;
}
+ }
- r = chown_one(dirfd(d), NULL, st, uid, gid);
- } else
- r = chown_one(fd, NULL, st, uid, gid);
+ r = chown_one(dirfd(d), st, uid, gid);
if (r < 0)
- goto finish;
+ return r;
- r = r > 0 || changed;
-
-finish:
- safe_close(fd);
- return r;
+ return r > 0 || changed;
}
int path_chown_recursive(const char *path, uid_t uid, gid_t gid) {
@@ -111,7 +105,7 @@ int path_chown_recursive(const char *path, uid_t uid, gid_t gid) {
struct stat st;
int r;
- fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
+ fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
if (fd < 0)
return -errno;

@ -0,0 +1,58 @@
From bbe9ac11d8d4a8511214605509a593fb9f04ffaa Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 19 Oct 2018 11:28:40 +0200
Subject: [PATCH] chown-recursive: also drop ACLs when recursively chown()ing
Let's better be safe than sorry and also drop ACLs.
(cherry-picked from commit f89bc84f3242449cbc308892c87573b131f121df)
Related: #1643368
---
src/core/chown-recursive.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/src/core/chown-recursive.c b/src/core/chown-recursive.c
index 27c64489b5..447b771267 100644
--- a/src/core/chown-recursive.c
+++ b/src/core/chown-recursive.c
@@ -3,6 +3,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/xattr.h>
#include "chown-recursive.h"
#include "dirent-util.h"
@@ -14,6 +15,7 @@
static int chown_one(int fd, const struct stat *st, uid_t uid, gid_t gid) {
char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
+ const char *n;
assert(fd >= 0);
assert(st);
@@ -26,13 +28,19 @@ static int chown_one(int fd, const struct stat *st, uid_t uid, gid_t gid) {
* O_PATH. (Note: fchown() and fchmod() do not work with O_PATH, the kernel refuses that. */
xsprintf(procfs_path, "/proc/self/fd/%i", fd);
+ /* Drop any ACL if there is one */
+ FOREACH_STRING(n, "system.posix_acl_access", "system.posix_acl_default")
+ if (removexattr(procfs_path, n) < 0)
+ if (!IN_SET(errno, ENODATA, EOPNOTSUPP, ENOSYS, ENOTTY))
+ return -errno;
+
if (chown(procfs_path, uid, gid) < 0)
return -errno;
- /* The linux kernel alters the mode in some cases of chown(). Let's undo this. We do this only for non-symlinks
- * however. That's because for symlinks the access mode is ignored anyway and because on some kernels/file
- * systems trying to change the access mode will succeed but has no effect while on others it actively
- * fails. */
+ /* The linux kernel alters the mode in some cases of chown(), as well when we change ACLs. Let's undo this. We
+ * do this only for non-symlinks however. That's because for symlinks the access mode is ignored anyway and
+ * because on some kernels/file systems trying to change the access mode will succeed but has no effect while
+ * on others it actively fails. */
if (!S_ISLNK(st->st_mode))
if (chmod(procfs_path, st->st_mode & 07777) < 0)
return -errno;

@ -1,46 +0,0 @@
From 31f0c1b06bfd90d52009b59b9a4bf26c297790a7 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 14 Nov 2022 17:26:49 +0100
Subject: [PATCH] tpm2-util: force default TCTI to be "device" with parameter
"/dev/tpmrm0"
Apparently some distros default to tss-abmrd. Let's bypass that and
always go to the kernel resource manager.
abmrd cannot really work for us, since we want to access the TPM already
in earliest boot i.e. in environments the abmrd service is not available
in.
Fixes: #25352
(cherry picked from commit 34906680afe60d724ea435b79b9b830a4bf2e7e9)
Related: #2138081
---
src/shared/tpm2-util.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
index 65e8d48347..9d73316146 100644
--- a/src/shared/tpm2-util.c
+++ b/src/shared/tpm2-util.c
@@ -152,8 +152,19 @@ int tpm2_context_init(const char *device, struct tpm2_context *ret) {
if (r < 0)
return log_error_errno(r, "TPM2 support not installed: %m");
- if (!device)
+ if (!device) {
device = secure_getenv("SYSTEMD_TPM2_DEVICE");
+ if (device)
+ /* Setting the env var to an empty string forces tpm2-tss' own device picking
+ * logic to be used. */
+ device = empty_to_null(device);
+ else
+ /* If nothing was specified explicitly, we'll use a hardcoded default: the "device" tcti
+ * driver and the "/dev/tpmrm0" device. We do this since on some distributions the tpm2-abrmd
+ * might be used and we really don't want that, since it is a system service and that creates
+ * various ordering issues/deadlocks during early boot. */
+ device = "device:/dev/tpmrm0";
+ }
if (device) {
const char *param, *driver, *fn;

@ -0,0 +1,34 @@
From c9630164b869e109bf2960968fc583449ccf0875 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 19 Oct 2018 11:42:11 +0200
Subject: [PATCH] chown-recursive: TAKE_FD() is your friend
(cherry-picked from commit cd6b7d50c337b3676a3d5fc2188ff298dcbdb939)
Related: #1643368
---
src/core/chown-recursive.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/src/core/chown-recursive.c b/src/core/chown-recursive.c
index 447b771267..7767301f7d 100644
--- a/src/core/chown-recursive.c
+++ b/src/core/chown-recursive.c
@@ -111,7 +111,6 @@ static int chown_recursive_internal(int fd, const struct stat *st, uid_t uid, gi
int path_chown_recursive(const char *path, uid_t uid, gid_t gid) {
_cleanup_close_ int fd = -1;
struct stat st;
- int r;
fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
if (fd < 0)
@@ -130,8 +129,5 @@ int path_chown_recursive(const char *path, uid_t uid, gid_t gid) {
(!gid_is_valid(gid) || st.st_gid == gid))
return 0;
- r = chown_recursive_internal(fd, &st, uid, gid);
- fd = -1; /* we donated the fd to the call, regardless if it succeeded or failed */
-
- return r;
+ return chown_recursive_internal(TAKE_FD(fd), &st, uid, gid); /* we donate the fd to the call, regardless if it succeeded or failed */
}

@ -1,52 +0,0 @@
From 5b20ba25259da453a2aac5e65978a11bc2d048ed Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 15 Nov 2022 23:01:04 +0100
Subject: [PATCH] tpm2: add some extra validation of device string before using
it
Let's add some extra validation before constructing and using the .so
name to load. This isn't really security sensitive, given that we
used secure_getenv() to get the device string (and it thus should have
been come from a trusted source) but let's better be safe than sorry.
(cherry picked from commit 50a085143fa8f5dd6b6b3cef8a6ea2ec7c53ed0d)
Related: #2138081
---
src/shared/tpm2-util.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
index 9d73316146..4d0df944a9 100644
--- a/src/shared/tpm2-util.c
+++ b/src/shared/tpm2-util.c
@@ -174,15 +174,27 @@ int tpm2_context_init(const char *device, struct tpm2_context *ret) {
param = strchr(device, ':');
if (param) {
+ /* Syntax #1: Pair of driver string and arbitrary parameter */
driver = strndupa_safe(device, param - device);
+ if (isempty(driver))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name is empty, refusing.");
+
param++;
- } else {
+ } else if (path_is_absolute(device) && path_is_valid(device)) {
+ /* Syntax #2: TPM device node */
driver = "device";
param = device;
- }
+ } else
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid TPM2 driver string, refusing.");
+
+ log_debug("Using TPM2 TCTI driver '%s' with device '%s'.", driver, param);
fn = strjoina("libtss2-tcti-", driver, ".so.0");
+ /* Better safe than sorry, let's refuse strings that cannot possibly be valid driver early, before going to disk. */
+ if (!filename_is_valid(fn))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name '%s' not valid, refusing.", driver);
+
dl = dlopen(fn, RTLD_NOW);
if (!dl)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to load %s: %s", fn, dlerror());

@ -1,25 +0,0 @@
From 2fdb15b3053d20282d7f3c20a7a4d2bd96d9a39b Mon Sep 17 00:00:00 2001
From: Jan Janssen <medhefgo@web.de>
Date: Sun, 13 Nov 2022 16:14:17 +0100
Subject: [PATCH] boot: Fix error message
(cherry picked from commit 6ee4aa22140dd8d51b1a18882eb4220629b8dd8f)
Related: #2138081
---
src/boot/efi/boot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index 4150b16ecf..84f4cc11a3 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -2678,7 +2678,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
err = device_path_to_str(loaded_image->FilePath, &loaded_image_path);
if (err != EFI_SUCCESS)
- return log_error_status_stall(err, L"Error getting loaded image path: %m");
+ return log_error_status_stall(err, L"Error getting loaded image path: %r", err);
export_variables(loaded_image, loaded_image_path, init_usec);

@ -0,0 +1,200 @@
From b53f89d56a5b7528735ddf335f8b47ab3e1a947a Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 19 Oct 2018 11:31:37 +0200
Subject: [PATCH] test: add test case for recursive chown()ing
[msekleta: I removed call to log_test_skipped() and replaced it with older construct log_info() + return EXIT_TEST_SKIP]
(cherry-picked from commit cb9e44db36caefcbb8ee7a12e14217305ed69ff2)
Related: #1643368
---
src/test/meson.build | 5 ++
src/test/test-chown-rec.c | 162 ++++++++++++++++++++++++++++++++++++++
2 files changed, 167 insertions(+)
create mode 100644 src/test/test-chown-rec.c
diff --git a/src/test/meson.build b/src/test/meson.build
index 7da7e3a22c..b982251b1f 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -60,6 +60,11 @@ tests += [
libmount,
libblkid]],
+ [['src/test/test-chown-rec.c'],
+ [libcore,
+ libshared],
+ []],
+
[['src/test/test-job-type.c'],
[libcore,
libshared],
diff --git a/src/test/test-chown-rec.c b/src/test/test-chown-rec.c
new file mode 100644
index 0000000000..f16d4d4ba2
--- /dev/null
+++ b/src/test/test-chown-rec.c
@@ -0,0 +1,162 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <sys/xattr.h>
+
+#include "alloc-util.h"
+#include "chown-recursive.h"
+#include "fileio.h"
+#include "log.h"
+#include "rm-rf.h"
+#include "string-util.h"
+#include "tests.h"
+
+static const uint8_t acl[] = {
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x07, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x07, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x10, 0x00, 0x07, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x05, 0x00,
+ 0xff, 0xff, 0xff, 0xff,
+};
+
+static const uint8_t default_acl[] = {
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x07, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x07, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x05, 0x00,
+ 0xff, 0xff, 0xff, 0xff,
+};
+
+static bool has_xattr(const char *p) {
+ char buffer[sizeof(acl) * 4];
+
+ if (lgetxattr(p, "system.posix_acl_access", buffer, sizeof(buffer)) < 0) {
+ if (IN_SET(errno, EOPNOTSUPP, ENOTTY, ENODATA, ENOSYS))
+ return false;
+ }
+
+ return true;
+}
+
+static void test_chown_recursive(void) {
+ _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
+ struct stat st;
+ const char *p;
+
+ umask(022);
+ assert_se(mkdtemp_malloc(NULL, &t) >= 0);
+
+ p = strjoina(t, "/dir");
+ assert_se(mkdir(p, 0777) >= 0);
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISDIR(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 0);
+ assert_se(st.st_gid == 0);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/symlink");
+ assert_se(symlink("../../", p) >= 0);
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISLNK(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0777);
+ assert_se(st.st_uid == 0);
+ assert_se(st.st_gid == 0);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/reg");
+ assert_se(mknod(p, S_IFREG|0777, 0) >= 0);
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISREG(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 0);
+ assert_se(st.st_gid == 0);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/sock");
+ assert_se(mknod(p, S_IFSOCK|0777, 0) >= 0);
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISSOCK(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 0);
+ assert_se(st.st_gid == 0);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/fifo");
+ assert_se(mknod(p, S_IFIFO|0777, 0) >= 0);
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISFIFO(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 0);
+ assert_se(st.st_gid == 0);
+ assert_se(!has_xattr(p));
+
+ /* We now apply an xattr to the dir, and check it again */
+ p = strjoina(t, "/dir");
+ assert_se(setxattr(p, "system.posix_acl_access", acl, sizeof(acl), 0) >= 0);
+ assert_se(setxattr(p, "system.posix_acl_default", default_acl, sizeof(default_acl), 0) >= 0);
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISDIR(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0775); /* acl change changed the mode too */
+ assert_se(st.st_uid == 0);
+ assert_se(st.st_gid == 0);
+ assert_se(has_xattr(p));
+
+ assert_se(path_chown_recursive(t, 1, 2) >= 0);
+
+ p = strjoina(t, "/dir");
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISDIR(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0775);
+ assert_se(st.st_uid == 1);
+ assert_se(st.st_gid == 2);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/symlink");
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISLNK(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0777);
+ assert_se(st.st_uid == 1);
+ assert_se(st.st_gid == 2);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/reg");
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISREG(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 1);
+ assert_se(st.st_gid == 2);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/sock");
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISSOCK(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 1);
+ assert_se(st.st_gid == 2);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/fifo");
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISFIFO(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 1);
+ assert_se(st.st_gid == 2);
+ assert_se(!has_xattr(p));
+}
+
+int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
+ if (geteuid() != 0) {
+ log_info("not running as root");
+ return EXIT_TEST_SKIP;
+ }
+
+ test_chown_recursive();
+
+ return EXIT_SUCCESS;
+}

@ -0,0 +1,32 @@
From 730ce6562f8a5f4a61d1ed3ffb4d65fa27b728fc Mon Sep 17 00:00:00 2001
From: Thomas Hindoe Paaboel Andersen <phomes@gmail.com>
Date: Fri, 17 Aug 2018 21:31:05 +0200
Subject: [PATCH] Revert "sysctl.d: request ECN on both in and outgoing
connections"
Turning on ECN still causes slow or broken network on linux. Our tcp
is not yet ready for wide spread use of ECN.
This reverts commit 919472741dba6ad0a3f6c2b76d390a02d0e2fdc3.
(cherry picked from commit 1e190dfd5bb95036f937ef1dc46f43eb0a146612)
Resolves: #1619790
---
sysctl.d/50-default.conf | 3 ---
1 file changed, 3 deletions(-)
diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf
index b67ae87ca6..e263cf0628 100644
--- a/sysctl.d/50-default.conf
+++ b/sysctl.d/50-default.conf
@@ -33,9 +33,6 @@ net.ipv4.conf.all.promote_secondaries = 1
# Fair Queue CoDel packet scheduler to fight bufferbloat
net.core.default_qdisc = fq_codel
-# Request Explicit Congestion Notification (ECN) on both in and outgoing connections
-net.ipv4.tcp_ecn = 1
-
# Enable hard and soft link protection
fs.protected_hardlinks = 1
fs.protected_symlinks = 1

@ -1,25 +0,0 @@
From 58a3aaaad640bee3cca79a644422489e184b49c1 Mon Sep 17 00:00:00 2001
From: Jan Janssen <medhefgo@web.de>
Date: Mon, 14 Nov 2022 14:18:26 +0100
Subject: [PATCH] boot: Fix memory leak
(cherry picked from commit b7b327f856b3782f28be561d612d66ff406c7789)
Related: #2138081
---
src/boot/efi/boot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index 84f4cc11a3..17d4ec2d09 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -2650,7 +2650,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
EFI_LOADED_IMAGE_PROTOCOL *loaded_image;
_cleanup_(file_closep) EFI_FILE *root_dir = NULL;
_cleanup_(config_free) Config config = {};
- char16_t *loaded_image_path;
+ _cleanup_free_ char16_t *loaded_image_path = NULL;
EFI_STATUS err;
uint64_t init_usec;
bool menu = false;

@ -1,88 +0,0 @@
From 8cbb38625364640f390b2df2cda44ff3877fb16d Mon Sep 17 00:00:00 2001
From: Jan Janssen <medhefgo@web.de>
Date: Mon, 14 Nov 2022 14:37:13 +0100
Subject: [PATCH] boot: Do not require a loaded image path
If the device path to text protocol is not available (looking angrily at
Apple) we would fail to boot because we cannot get the loaded image
path. As this is only used for cosmetic purposes, we can just silently
continue.
Fixes: #25363
(cherry picked from commit af7ef648cddeb96da525de2410565d166f75cc96)
Related: #2138081
---
src/boot/efi/boot.c | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index 17d4ec2d09..b490a1d972 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -471,7 +471,6 @@ static void print_status(Config *config, char16_t *loaded_image_path) {
_cleanup_free_ char16_t *device_part_uuid = NULL;
assert(config);
- assert(loaded_image_path);
clear_screen(COLOR_NORMAL);
console_query_mode(&x_max, &y_max);
@@ -619,7 +618,6 @@ static bool menu_run(
assert(config);
assert(chosen_entry);
- assert(loaded_image_path);
EFI_STATUS err;
UINTN visible_max = 0;
@@ -1478,7 +1476,7 @@ static void config_entry_add_type1(
entry->loader = xstra_to_path(value);
/* do not add an entry for ourselves */
- if (loaded_image_path && strcaseeq16(entry->loader, loaded_image_path)) {
+ if (strcaseeq16(entry->loader, loaded_image_path)) {
entry->type = LOADER_UNDEFINED;
break;
}
@@ -1908,12 +1906,11 @@ static ConfigEntry *config_entry_add_loader_auto(
assert(root_dir);
assert(id);
assert(title);
- assert(loader || loaded_image_path);
if (!config->auto_entries)
return NULL;
- if (loaded_image_path) {
+ if (!loader) {
loader = L"\\EFI\\BOOT\\BOOT" EFI_MACHINE_TYPE_NAME ".efi";
/* We are trying to add the default EFI loader here,
@@ -2562,7 +2559,6 @@ static void export_variables(
char16_t uuid[37];
assert(loaded_image);
- assert(loaded_image_path);
efivar_set_time_usec(LOADER_GUID, L"LoaderTimeInitUSec", init_usec);
efivar_set(LOADER_GUID, L"LoaderInfo", L"systemd-boot " GIT_VERSION, 0);
@@ -2591,7 +2587,6 @@ static void config_load_all_entries(
assert(config);
assert(loaded_image);
- assert(loaded_image_path);
assert(root_dir);
config_load_defaults(config, root_dir);
@@ -2676,9 +2671,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
if (err != EFI_SUCCESS)
return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
- err = device_path_to_str(loaded_image->FilePath, &loaded_image_path);
- if (err != EFI_SUCCESS)
- return log_error_status_stall(err, L"Error getting loaded image path: %r", err);
+ (void) device_path_to_str(loaded_image->FilePath, &loaded_image_path);
export_variables(loaded_image, loaded_image_path, init_usec);

@ -0,0 +1,84 @@
From 886e5b028953404f2d924b561c0689d3e50dbbf4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 13 Sep 2018 09:24:36 +0200
Subject: [PATCH] detect-virt: do not try to read all of /proc/cpuinfo
Quoting https://github.com/systemd/systemd/issues/10074:
> detect_vm_uml() reads /proc/cpuinfo with read_full_file()
> read_full_file() has a file max limit size of READ_FULL_BYTES_MAX=(4U*1024U*1024U)
> Unfortunately, the size of my /proc/cpuinfo is bigger, approximately:
> echo $(( 4* $(cat /proc/cpuinfo | wc -c)))
> 9918072
> This causes read_full_file() to fail and the Condition test fallout.
Let's just read line by line until we find an intersting line. This also
helps if not running under UML, because we avoid reading as much data.
(cherry picked from commit 6058516a14ada1748313af6783f5b4e7e3006654)
Resolves: #1631532
---
src/basic/virt.c | 38 ++++++++++++++++++++++++++++----------
1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/src/basic/virt.c b/src/basic/virt.c
index d347732bb3..e05b3e6d99 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -11,6 +11,7 @@
#include "alloc-util.h"
#include "dirent-util.h"
+#include "def.h"
#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
@@ -259,21 +260,38 @@ static int detect_vm_hypervisor(void) {
}
static int detect_vm_uml(void) {
- _cleanup_free_ char *cpuinfo_contents = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
int r;
/* Detect User-Mode Linux by reading /proc/cpuinfo */
- r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL);
- if (r == -ENOENT) {
- log_debug("/proc/cpuinfo not found, assuming no UML virtualization.");
- return VIRTUALIZATION_NONE;
+ f = fopen("/proc/cpuinfo", "re");
+ if (!f) {
+ if (errno == ENOENT) {
+ log_debug("/proc/cpuinfo not found, assuming no UML virtualization.");
+ return VIRTUALIZATION_NONE;
+ }
+ return -errno;
}
- if (r < 0)
- return r;
- if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n")) {
- log_debug("UML virtualization found in /proc/cpuinfo");
- return VIRTUALIZATION_UML;
+ for (;;) {
+ _cleanup_free_ char *line = NULL;
+ const char *t;
+
+ r = read_line(f, LONG_LINE_MAX, &line);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ t = startswith(line, "vendor_id\t: ");
+ if (t) {
+ if (startswith(t, "User Mode Linux")) {
+ log_debug("UML virtualization found in /proc/cpuinfo");
+ return VIRTUALIZATION_UML;
+ }
+
+ break;
+ }
}
log_debug("UML virtualization not found in /proc/cpuinfo.");

@ -1,75 +0,0 @@
From 806165285b822436023df84ca0a3e5b28a3099d6 Mon Sep 17 00:00:00 2001
From: Jan Janssen <medhefgo@web.de>
Date: Mon, 14 Nov 2022 15:24:32 +0100
Subject: [PATCH] boot: Manually convert filepaths if needed
The conversion of a filepath device path to text is needed for the stub
loader to find credential files.
(cherry picked from commit 679007044fbbcf82c66cf20b99f2f5086b7df6b4)
Related: #2138081
---
src/boot/efi/util.c | 40 ++++++++++++++++++++++++++++++++++++----
1 file changed, 36 insertions(+), 4 deletions(-)
diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c
index 5547d288de..57436dbf0c 100644
--- a/src/boot/efi/util.c
+++ b/src/boot/efi/util.c
@@ -772,19 +772,51 @@ EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DE
EFI_STATUS device_path_to_str(const EFI_DEVICE_PATH *dp, char16_t **ret) {
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *dp_to_text;
EFI_STATUS err;
+ _cleanup_free_ char16_t *str = NULL;
assert(dp);
assert(ret);
err = BS->LocateProtocol(&(EFI_GUID) EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID, NULL, (void **) &dp_to_text);
- if (err != EFI_SUCCESS)
- return err;
+ if (err != EFI_SUCCESS) {
+ /* If the device path to text protocol is not available we can still do a best-effort attempt
+ * to convert it ourselves if we are given filepath-only device path. */
+
+ size_t size = 0;
+ for (const EFI_DEVICE_PATH *node = dp; !IsDevicePathEnd(node);
+ node = NextDevicePathNode(node)) {
+
+ if (DevicePathType(node) != MEDIA_DEVICE_PATH ||
+ DevicePathSubType(node) != MEDIA_FILEPATH_DP)
+ return err;
+
+ size_t path_size = DevicePathNodeLength(node);
+ if (path_size <= offsetof(FILEPATH_DEVICE_PATH, PathName) || path_size % sizeof(char16_t))
+ return EFI_INVALID_PARAMETER;
+ path_size -= offsetof(FILEPATH_DEVICE_PATH, PathName);
+
+ _cleanup_free_ char16_t *old = str;
+ str = xmalloc(size + path_size);
+ if (old) {
+ memcpy(str, old, size);
+ str[size / sizeof(char16_t) - 1] = '\\';
+ }
+
+ memcpy(str + (size / sizeof(char16_t)),
+ ((uint8_t *) node) + offsetof(FILEPATH_DEVICE_PATH, PathName),
+ path_size);
+ size += path_size;
+ }
+
+ *ret = TAKE_PTR(str);
+ return EFI_SUCCESS;
+ }
- char16_t *str = dp_to_text->ConvertDevicePathToText(dp, false, false);
+ str = dp_to_text->ConvertDevicePathToText(dp, false, false);
if (!str)
return EFI_OUT_OF_RESOURCES;
- *ret = str;
+ *ret = TAKE_PTR(str);
return EFI_SUCCESS;
}

@ -0,0 +1,166 @@
From eb141ba81158feb74118da4e7a3f2266b11ffe10 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 9 Jul 2018 08:06:28 +0200
Subject: [PATCH] sd-bus: unify three code-paths which free struct
bus_container
We didn't free one of the fields in two of the places.
$ valgrind --show-leak-kinds=all --leak-check=full \
build/fuzz-bus-message \
test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20
...
==14457== HEAP SUMMARY:
==14457== in use at exit: 3 bytes in 1 blocks
==14457== total heap usage: 509 allocs, 508 frees, 51,016 bytes allocated
==14457==
==14457== 3 bytes in 1 blocks are definitely lost in loss record 1 of 1
==14457== at 0x4C2EBAB: malloc (vg_replace_malloc.c:299)
==14457== by 0x53AFE79: strndup (in /usr/lib64/libc-2.27.so)
==14457== by 0x4F52EB8: free_and_strndup (string-util.c:1039)
==14457== by 0x4F8E1AB: sd_bus_message_peek_type (bus-message.c:4193)
==14457== by 0x4F76CB5: bus_message_dump (bus-dump.c:144)
==14457== by 0x108F12: LLVMFuzzerTestOneInput (fuzz-bus-message.c:24)
==14457== by 0x1090F7: main (fuzz-main.c:34)
==14457==
==14457== LEAK SUMMARY:
==14457== definitely lost: 3 bytes in 1 blocks
(cherry picked from commit 6d1e0f4fcba8d6f425da3dc91805db95399b3c8b)
Resolves: #1635435
---
src/libsystemd/sd-bus/bus-message.c | 64 +++++++++---------
...k-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 | Bin 0 -> 534 bytes
2 files changed, 32 insertions(+), 32 deletions(-)
create mode 100644 test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 7c8bad2bdd..d55cb14843 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -77,19 +77,38 @@ static void message_reset_parts(sd_bus_message *m) {
m->cached_rindex_part_begin = 0;
}
-static void message_reset_containers(sd_bus_message *m) {
- unsigned i;
+static struct bus_container *message_get_container(sd_bus_message *m) {
+ assert(m);
+
+ if (m->n_containers == 0)
+ return &m->root_container;
+
+ assert(m->containers);
+ return m->containers + m->n_containers - 1;
+}
+
+static void message_free_last_container(sd_bus_message *m) {
+ struct bus_container *c;
+
+ c = message_get_container(m);
+
+ free(c->signature);
+ free(c->peeked_signature);
+ free(c->offsets);
+
+ /* Move to previous container, but not if we are on root container */
+ if (m->n_containers > 0)
+ m->n_containers--;
+}
+static void message_reset_containers(sd_bus_message *m) {
assert(m);
- for (i = 0; i < m->n_containers; i++) {
- free(m->containers[i].signature);
- free(m->containers[i].offsets);
- }
+ while (m->n_containers > 0)
+ message_free_last_container(m);
m->containers = mfree(m->containers);
-
- m->n_containers = m->containers_allocated = 0;
+ m->containers_allocated = 0;
m->root_container.index = 0;
}
@@ -112,10 +131,8 @@ static sd_bus_message* message_free(sd_bus_message *m) {
free(m->iovec);
message_reset_containers(m);
- free(m->root_container.signature);
- free(m->root_container.offsets);
-
- free(m->root_container.peeked_signature);
+ assert(m->n_containers == 0);
+ message_free_last_container(m);
bus_creds_done(&m->creds);
return mfree(m);
@@ -1113,16 +1130,6 @@ _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *
return 0;
}
-static struct bus_container *message_get_container(sd_bus_message *m) {
- assert(m);
-
- if (m->n_containers == 0)
- return &m->root_container;
-
- assert(m->containers);
- return m->containers + m->n_containers - 1;
-}
-
struct bus_body_part *message_append_part(sd_bus_message *m) {
struct bus_body_part *part;
@@ -4108,13 +4115,9 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
return -EBUSY;
}
- free(c->signature);
- free(c->peeked_signature);
- free(c->offsets);
- m->n_containers--;
+ message_free_last_container(m);
c = message_get_container(m);
-
saved = c->index;
c->index = c->saved_index;
r = container_next_item(m, c, &m->rindex);
@@ -4132,16 +4135,13 @@ static void message_quit_container(sd_bus_message *m) {
assert(m->sealed);
assert(m->n_containers > 0);
- c = message_get_container(m);
-
/* Undo seeks */
+ c = message_get_container(m);
assert(m->rindex >= c->before);
m->rindex = c->before;
/* Free container */
- free(c->signature);
- free(c->offsets);
- m->n_containers--;
+ message_free_last_container(m);
/* Correct index of new top-level container */
c = message_get_container(m);
diff --git a/test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 b/test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20
new file mode 100644
index 0000000000000000000000000000000000000000..c371824ffb604708619fd0713e8fca609bac18f7
GIT binary patch
literal 534
zcmZ{h!A`?442GSJP20o?A&zJgm*%p<cmZx)c?GB2N~MZabq0zMhzqX`{7ze`LYk$&
z_LnqH{-ic!J`GWMLG(>T#&`l!4rxq{&>8YmwQrOs;B(}I_m11m8`nFp<MR{a3sX`q
z!cs!Q@A35`W+B>`#ek1>oQYVSs`!XH?7Y=}3y9Ye+UliL9^x9s66$8wH+TPdOG`n|
z5Uhx<nM2)KiEdF(J5Ct}Xa*iksL!VNssA<Hq<KDseGAsT^*)9kK$?O39;dyGT&#2v
zLhpD3X)k6@tX`CzbBVV-7e$fy9()CjJ&n(=^)uJCKFB5Xi}-<1ru7po5XlEJ?uByQ
MaEPzRhwknF02{PjtN;K2
literal 0
HcmV?d00001

@ -1,433 +0,0 @@
From 519625977d19b7842d9b2ded8be12ed0aecbaefc Mon Sep 17 00:00:00 2001
From: Jan Janssen <medhefgo@web.de>
Date: Tue, 15 Nov 2022 18:22:38 +0100
Subject: [PATCH] boot: Rework security arch override
This simplifies the caller interface for security arch overrides by only
having to pass a validator and an optional context.
(cherry picked from commit 5489c13bae119dc5f6e65be8d7f241aa7d54c023)
Related: #2138081
---
src/boot/efi/linux.c | 61 ++++++++-------------
src/boot/efi/secure-boot.c | 105 +++++++++++++++++++++++++++++--------
src/boot/efi/secure-boot.h | 28 +++-------
src/boot/efi/shim.c | 104 +++++++++++-------------------------
4 files changed, 146 insertions(+), 152 deletions(-)
diff --git a/src/boot/efi/linux.c b/src/boot/efi/linux.c
index 75b9507709..dd7eb48c8c 100644
--- a/src/boot/efi/linux.c
+++ b/src/boot/efi/linux.c
@@ -20,35 +20,26 @@
#define STUB_PAYLOAD_GUID \
{ 0x55c5d1f8, 0x04cd, 0x46b5, { 0x8a, 0x20, 0xe5, 0x6c, 0xbb, 0x30, 0x52, 0xd0 } }
-static EFIAPI EFI_STATUS security_hook(
- const SecurityOverride *this, uint32_t authentication_status, const EFI_DEVICE_PATH *file) {
+typedef struct {
+ const void *addr;
+ size_t len;
+ const EFI_DEVICE_PATH *device_path;
+} ValidationContext;
- assert(this);
- assert(this->hook == security_hook);
+static bool validate_payload(
+ const void *ctx, const EFI_DEVICE_PATH *device_path, const void *file_buffer, size_t file_size) {
- if (file == this->payload_device_path)
- return EFI_SUCCESS;
+ const ValidationContext *payload = ASSERT_PTR(ctx);
- return this->original_security->FileAuthenticationState(
- this->original_security, authentication_status, file);
-}
-
-static EFIAPI EFI_STATUS security2_hook(
- const SecurityOverride *this,
- const EFI_DEVICE_PATH *device_path,
- void *file_buffer,
- size_t file_size,
- BOOLEAN boot_policy) {
-
- assert(this);
- assert(this->hook == security2_hook);
+ if (device_path != payload->device_path)
+ return false;
- if (file_buffer == this->payload && file_size == this->payload_len &&
- device_path == this->payload_device_path)
- return EFI_SUCCESS;
+ /* Security arch (1) protocol does not provide a file buffer. Instead we are supposed to fetch the payload
+ * ourselves, which is not needed as we already have everything in memory and the device paths match. */
+ if (file_buffer && (file_buffer != payload->addr || file_size != payload->len))
+ return false;
- return this->original_security2->FileAuthentication(
- this->original_security2, device_path, file_buffer, file_size, boot_policy);
+ return true;
}
static EFI_STATUS load_image(EFI_HANDLE parent, const void *source, size_t len, EFI_HANDLE *ret_image) {
@@ -79,19 +70,13 @@ static EFI_STATUS load_image(EFI_HANDLE parent, const void *source, size_t len,
/* We want to support unsigned kernel images as payload, which is safe to do under secure boot
* because it is embedded in this stub loader (and since it is already running it must be trusted). */
- SecurityOverride security_override = {
- .hook = security_hook,
- .payload = source,
- .payload_len = len,
- .payload_device_path = &payload_device_path.payload.Header,
- }, security2_override = {
- .hook = security2_hook,
- .payload = source,
- .payload_len = len,
- .payload_device_path = &payload_device_path.payload.Header,
- };
-
- install_security_override(&security_override, &security2_override);
+ install_security_override(
+ validate_payload,
+ &(ValidationContext) {
+ .addr = source,
+ .len = len,
+ .device_path = &payload_device_path.payload.Header,
+ });
EFI_STATUS ret = BS->LoadImage(
/*BootPolicy=*/false,
@@ -101,7 +86,7 @@ static EFI_STATUS load_image(EFI_HANDLE parent, const void *source, size_t len,
len,
ret_image);
- uninstall_security_override(&security_override, &security2_override);
+ uninstall_security_override();
return ret;
}
diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c
index 171b2c96b3..0e615c55e0 100644
--- a/src/boot/efi/secure-boot.c
+++ b/src/boot/efi/secure-boot.c
@@ -127,10 +127,60 @@ out_deallocate:
return err;
}
-static EFI_STATUS install_security_override_one(EFI_GUID guid, SecurityOverride *override) {
+static struct SecurityOverride {
+ /* Our own security arch instances that we register onto original_handle, thereby replacing the
+ * firmware provided instances. */
+ EFI_SECURITY_ARCH_PROTOCOL override;
+ EFI_SECURITY2_ARCH_PROTOCOL override2;
+
+ /* These are saved so we can uninstall our own instance later. */
+ EFI_HANDLE original_handle, original_handle2;
+ EFI_SECURITY_ARCH_PROTOCOL *original_security;
+ EFI_SECURITY2_ARCH_PROTOCOL *original_security2;
+
+ security_validator_t validator;
+ const void *validator_ctx;
+} security_override;
+
+static EFIAPI EFI_STATUS security_hook(
+ const EFI_SECURITY_ARCH_PROTOCOL *this,
+ uint32_t authentication_status,
+ const EFI_DEVICE_PATH *file) {
+
+ assert(security_override.validator);
+ assert(security_override.original_security);
+
+ if (security_override.validator(security_override.validator_ctx, file, NULL, 0))
+ return EFI_SUCCESS;
+
+ return security_override.original_security->FileAuthenticationState(
+ security_override.original_security, authentication_status, file);
+}
+
+static EFIAPI EFI_STATUS security2_hook(
+ const EFI_SECURITY2_ARCH_PROTOCOL *this,
+ const EFI_DEVICE_PATH *device_path,
+ void *file_buffer,
+ size_t file_size,
+ BOOLEAN boot_policy) {
+
+ assert(security_override.validator);
+ assert(security_override.original_security2);
+
+ if (security_override.validator(security_override.validator_ctx, device_path, file_buffer, file_size))
+ return EFI_SUCCESS;
+
+ return security_override.original_security2->FileAuthentication(
+ security_override.original_security2, device_path, file_buffer, file_size, boot_policy);
+}
+
+static EFI_STATUS install_security_override_one(
+ EFI_GUID guid, void *override, EFI_HANDLE *ret_original_handle, void **ret_original_security) {
EFI_STATUS err;
assert(override);
+ assert(ret_original_handle);
+ assert(ret_original_security);
_cleanup_free_ EFI_HANDLE *handles = NULL;
size_t n_handles = 0;
@@ -152,8 +202,8 @@ static EFI_STATUS install_security_override_one(EFI_GUID guid, SecurityOverride
if (err != EFI_SUCCESS)
return log_error_status_stall(err, u"Error overriding security arch protocol: %r", err);
- override->original = security;
- override->original_handle = handles[0];
+ *ret_original_security = security;
+ *ret_original_handle = handles[0];
return EFI_SUCCESS;
}
@@ -161,35 +211,46 @@ static EFI_STATUS install_security_override_one(EFI_GUID guid, SecurityOverride
* Specification) with the provided override instances. If not running in secure boot or the protocols are
* not available nothing happens. The override instances are provided with the necessary info to undo this
* in uninstall_security_override(). */
-void install_security_override(SecurityOverride *override, SecurityOverride *override2) {
- assert(override);
- assert(override2);
+void install_security_override(security_validator_t validator, const void *validator_ctx) {
+ assert(validator);
if (!secure_boot_enabled())
return;
- (void) install_security_override_one((EFI_GUID) EFI_SECURITY_ARCH_PROTOCOL_GUID, override);
- (void) install_security_override_one((EFI_GUID) EFI_SECURITY2_ARCH_PROTOCOL_GUID, override2);
-}
+ security_override = (struct SecurityOverride) {
+ { .FileAuthenticationState = security_hook, },
+ { .FileAuthentication = security2_hook, },
+ .validator = validator,
+ .validator_ctx = validator_ctx,
+ };
-void uninstall_security_override(SecurityOverride *override, SecurityOverride *override2) {
- assert(override);
- assert(override2);
+ (void) install_security_override_one(
+ (EFI_GUID) EFI_SECURITY_ARCH_PROTOCOL_GUID,
+ &security_override.override,
+ &security_override.original_handle,
+ (void **) &security_override.original_security);
+ (void) install_security_override_one(
+ (EFI_GUID) EFI_SECURITY2_ARCH_PROTOCOL_GUID,
+ &security_override.override2,
+ &security_override.original_handle2,
+ (void **) &security_override.original_security2);
+}
+void uninstall_security_override(void) {
/* We use assert_se here to guarantee the system is not in a weird state in the unlikely case of an
* error restoring the original protocols. */
- if (override->original_handle)
+ if (security_override.original_handle)
assert_se(BS->ReinstallProtocolInterface(
- override->original_handle,
- &(EFI_GUID) EFI_SECURITY_ARCH_PROTOCOL_GUID,
- override,
- override->original) == EFI_SUCCESS);
+ security_override.original_handle,
+ &(EFI_GUID) EFI_SECURITY_ARCH_PROTOCOL_GUID,
+ &security_override.override,
+ security_override.original_security) == EFI_SUCCESS);
- if (override2->original_handle)
+ if (security_override.original_handle2)
assert_se(BS->ReinstallProtocolInterface(
- override2->original_handle,
- &(EFI_GUID) EFI_SECURITY2_ARCH_PROTOCOL_GUID,
- override2,
- override2->original) == EFI_SUCCESS);
+ security_override.original_handle2,
+ &(EFI_GUID) EFI_SECURITY2_ARCH_PROTOCOL_GUID,
+ &security_override.override2,
+ security_override.original_security2) == EFI_SUCCESS);
}
diff --git a/src/boot/efi/secure-boot.h b/src/boot/efi/secure-boot.h
index 91b6770edb..e98de81c2a 100644
--- a/src/boot/efi/secure-boot.h
+++ b/src/boot/efi/secure-boot.h
@@ -17,23 +17,11 @@ SecureBootMode secure_boot_mode(void);
EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path);
-typedef struct {
- void *hook;
-
- /* End of EFI_SECURITY_ARCH(2)_PROTOCOL. The rest is our own protocol instance data. */
-
- EFI_HANDLE original_handle;
- union {
- void *original;
- EFI_SECURITY_ARCH_PROTOCOL *original_security;
- EFI_SECURITY2_ARCH_PROTOCOL *original_security2;
- };
-
- /* Used by the stub to identify the embedded image. */
- const void *payload;
- size_t payload_len;
- const EFI_DEVICE_PATH *payload_device_path;
-} SecurityOverride;
-
-void install_security_override(SecurityOverride *override, SecurityOverride *override2);
-void uninstall_security_override(SecurityOverride *override, SecurityOverride *override2);
+typedef bool (*security_validator_t)(
+ const void *ctx,
+ const EFI_DEVICE_PATH *device_path,
+ const void *file_buffer,
+ size_t file_size);
+
+void install_security_override(security_validator_t validator, const void *validator_ctx);
+void uninstall_security_override(void);
diff --git a/src/boot/efi/shim.c b/src/boot/efi/shim.c
index 3ae058cb84..ac224336bc 100644
--- a/src/boot/efi/shim.c
+++ b/src/boot/efi/shim.c
@@ -23,7 +23,7 @@
#endif
struct ShimLock {
- EFI_STATUS __sysv_abi__ (*shim_verify) (void *buffer, uint32_t size);
+ EFI_STATUS __sysv_abi__ (*shim_verify) (const void *buffer, uint32_t size);
/* context is actually a struct for the PE header, but it isn't needed so void is sufficient just do define the interface
* see shim.c/shim.h and PeHeader.h in the github shim repo */
@@ -41,79 +41,45 @@ bool shim_loaded(void) {
return BS->LocateProtocol((EFI_GUID*) SHIM_LOCK_GUID, NULL, (void**) &shim_lock) == EFI_SUCCESS;
}
-static bool shim_validate(void *data, uint32_t size) {
- struct ShimLock *shim_lock;
-
- if (!data)
- return false;
-
- if (BS->LocateProtocol((EFI_GUID*) SHIM_LOCK_GUID, NULL, (void**) &shim_lock) != EFI_SUCCESS)
- return false;
-
- if (!shim_lock)
- return false;
-
- return shim_lock->shim_verify(data, size) == EFI_SUCCESS;
-}
-
-static EFIAPI EFI_STATUS security2_hook(
- const SecurityOverride *this,
- const EFI_DEVICE_PATH *device_path,
- void *file_buffer,
- UINTN file_size,
- BOOLEAN boot_policy) {
-
- assert(this);
- assert(this->hook == security2_hook);
-
- if (shim_validate(file_buffer, file_size))
- return EFI_SUCCESS;
-
- return this->original_security2->FileAuthentication(
- this->original_security2, device_path, file_buffer, file_size, boot_policy);
-}
-
-static EFIAPI EFI_STATUS security_hook(
- const SecurityOverride *this,
- uint32_t authentication_status,
- const EFI_DEVICE_PATH *device_path) {
+static bool shim_validate(
+ const void *ctx, const EFI_DEVICE_PATH *device_path, const void *file_buffer, size_t file_size) {
EFI_STATUS err;
+ _cleanup_free_ char *file_buffer_owned = NULL;
- assert(this);
- assert(this->hook == security_hook);
+ if (!file_buffer) {
+ if (!device_path)
+ return false;
- if (!device_path)
- return this->original_security->FileAuthenticationState(
- this->original_security, authentication_status, device_path);
+ EFI_HANDLE device_handle;
+ EFI_DEVICE_PATH *file_dp = (EFI_DEVICE_PATH *) device_path;
+ err = BS->LocateDevicePath(&FileSystemProtocol, &file_dp, &device_handle);
+ if (err != EFI_SUCCESS)
+ return false;
- EFI_HANDLE device_handle;
- EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *) device_path;
- err = BS->LocateDevicePath(&FileSystemProtocol, &dp, &device_handle);
- if (err != EFI_SUCCESS)
- return err;
+ _cleanup_(file_closep) EFI_FILE *root = NULL;
+ err = open_volume(device_handle, &root);
+ if (err != EFI_SUCCESS)
+ return false;
- _cleanup_(file_closep) EFI_FILE *root = NULL;
- err = open_volume(device_handle, &root);
- if (err != EFI_SUCCESS)
- return err;
+ _cleanup_free_ char16_t *dp_str = NULL;
+ err = device_path_to_str(file_dp, &dp_str);
+ if (err != EFI_SUCCESS)
+ return false;
- _cleanup_free_ char16_t *dp_str = NULL;
- err = device_path_to_str(dp, &dp_str);
- if (err != EFI_SUCCESS)
- return err;
+ err = file_read(root, dp_str, 0, 0, &file_buffer_owned, &file_size);
+ if (err != EFI_SUCCESS)
+ return false;
- char *file_buffer;
- size_t file_size;
- err = file_read(root, dp_str, 0, 0, &file_buffer, &file_size);
- if (err != EFI_SUCCESS)
- return err;
+ file_buffer = file_buffer_owned;
+ }
- if (shim_validate(file_buffer, file_size))
- return EFI_SUCCESS;
+ struct ShimLock *shim_lock;
+ err = BS->LocateProtocol((EFI_GUID *) SHIM_LOCK_GUID, NULL, (void **) &shim_lock);
+ if (err != EFI_SUCCESS)
+ return false;
- return this->original_security->FileAuthenticationState(
- this->original_security, authentication_status, device_path);
+ return shim_lock->shim_verify(file_buffer, file_size) == EFI_SUCCESS;
}
EFI_STATUS shim_load_image(EFI_HANDLE parent, const EFI_DEVICE_PATH *device_path, EFI_HANDLE *ret_image) {
@@ -122,20 +88,14 @@ EFI_STATUS shim_load_image(EFI_HANDLE parent, const EFI_DEVICE_PATH *device_path
bool have_shim = shim_loaded();
- SecurityOverride security_override = {
- .hook = security_hook,
- }, security2_override = {
- .hook = security2_hook,
- };
-
if (have_shim)
- install_security_override(&security_override, &security2_override);
+ install_security_override(shim_validate, NULL);
EFI_STATUS ret = BS->LoadImage(
/*BootPolicy=*/false, parent, (EFI_DEVICE_PATH *) device_path, NULL, 0, ret_image);
if (have_shim)
- uninstall_security_override(&security_override, &security2_override);
+ uninstall_security_override();
return ret;
}

@ -0,0 +1,27 @@
From 220a60a61a91153fd8e49e58884b9b0b904888f6 Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Wed, 31 Oct 2018 12:50:19 +0100
Subject: [PATCH] sd-bus: properly initialize containers
Fixes a SIGSEGV introduced by commit 38a5315a3a6fab745d8c86ff9e486faaf50b28d1.
The same problem doesn't exist upstream, as the container structure
there is initialized using a compound literal, which is zeroed out by
default.
Related: #1635435
---
src/libsystemd/sd-bus/bus-message.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index d55cb14843..780c8c6185 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -2004,6 +2004,7 @@ _public_ int sd_bus_message_open_container(
w = m->containers + m->n_containers++;
w->enclosing = type;
w->signature = TAKE_PTR(signature);
+ w->peeked_signature = NULL;
w->index = 0;
w->array_size = array_size;
w->before = before;

@ -1,185 +0,0 @@
From 8d0b70887a09b9d4a8b669620579d3b6780f0755 Mon Sep 17 00:00:00 2001
From: Jan Janssen <medhefgo@web.de>
Date: Tue, 15 Nov 2022 18:53:02 +0100
Subject: [PATCH] boot: Replace firmware security hooks directly
For some firmware, replacing their own security arch instance with our
override using ReinstallProtocolInterface() is not enough as they will
not use it. This commit goes back to how this was done before by
directly modifying the security protocols.
Fixes: #25336
(cherry picked from commit 967a868563996e928f1fade5bcafc82a7219742b)
Related: #2138081
---
src/boot/efi/secure-boot.c | 119 +++++++++++++------------------------
1 file changed, 40 insertions(+), 79 deletions(-)
diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c
index 0e615c55e0..65457bf423 100644
--- a/src/boot/efi/secure-boot.c
+++ b/src/boot/efi/secure-boot.c
@@ -128,15 +128,10 @@ out_deallocate:
}
static struct SecurityOverride {
- /* Our own security arch instances that we register onto original_handle, thereby replacing the
- * firmware provided instances. */
- EFI_SECURITY_ARCH_PROTOCOL override;
- EFI_SECURITY2_ARCH_PROTOCOL override2;
-
- /* These are saved so we can uninstall our own instance later. */
- EFI_HANDLE original_handle, original_handle2;
- EFI_SECURITY_ARCH_PROTOCOL *original_security;
- EFI_SECURITY2_ARCH_PROTOCOL *original_security2;
+ EFI_SECURITY_ARCH_PROTOCOL *security;
+ EFI_SECURITY2_ARCH_PROTOCOL *security2;
+ EFI_SECURITY_FILE_AUTHENTICATION_STATE original_hook;
+ EFI_SECURITY2_FILE_AUTHENTICATION original_hook2;
security_validator_t validator;
const void *validator_ctx;
@@ -148,13 +143,13 @@ static EFIAPI EFI_STATUS security_hook(
const EFI_DEVICE_PATH *file) {
assert(security_override.validator);
- assert(security_override.original_security);
+ assert(security_override.security);
+ assert(security_override.original_hook);
if (security_override.validator(security_override.validator_ctx, file, NULL, 0))
return EFI_SUCCESS;
- return security_override.original_security->FileAuthenticationState(
- security_override.original_security, authentication_status, file);
+ return security_override.original_hook(security_override.security, authentication_status, file);
}
static EFIAPI EFI_STATUS security2_hook(
@@ -165,92 +160,58 @@ static EFIAPI EFI_STATUS security2_hook(
BOOLEAN boot_policy) {
assert(security_override.validator);
- assert(security_override.original_security2);
+ assert(security_override.security2);
+ assert(security_override.original_hook2);
if (security_override.validator(security_override.validator_ctx, device_path, file_buffer, file_size))
return EFI_SUCCESS;
- return security_override.original_security2->FileAuthentication(
- security_override.original_security2, device_path, file_buffer, file_size, boot_policy);
+ return security_override.original_hook2(
+ security_override.security2, device_path, file_buffer, file_size, boot_policy);
}
-static EFI_STATUS install_security_override_one(
- EFI_GUID guid, void *override, EFI_HANDLE *ret_original_handle, void **ret_original_security) {
+/* This replaces the platform provided security arch protocols hooks (defined in the UEFI Platform
+ * Initialization Specification) with our own that uses the given validator to decide if a image is to be
+ * trusted. If not running in secure boot or the protocols are not available nothing happens. The override
+ * must be removed with uninstall_security_override() after LoadImage() has been called.
+ *
+ * This is a hack as we do not own the security protocol instances and modifying them is not an official part
+ * of their spec. But there is little else we can do to circumvent secure boot short of implementing our own
+ * PE loader. We could replace the firmware instances with our own instance using
+ * ReinstallProtocolInterface(), but some firmware will still use the old ones. */
+void install_security_override(security_validator_t validator, const void *validator_ctx) {
EFI_STATUS err;
- assert(override);
- assert(ret_original_handle);
- assert(ret_original_security);
-
- _cleanup_free_ EFI_HANDLE *handles = NULL;
- size_t n_handles = 0;
-
- err = BS->LocateHandleBuffer(ByProtocol, &guid, NULL, &n_handles, &handles);
- if (err != EFI_SUCCESS)
- /* No security arch protocol around? */
- return err;
-
- /* There should only ever be one security arch protocol instance, but let's be paranoid here. */
- assert(n_handles == 1);
-
- void *security = NULL;
- err = BS->LocateProtocol(&guid, NULL, &security);
- if (err != EFI_SUCCESS)
- return log_error_status_stall(err, u"Error getting security arch protocol: %r", err);
-
- err = BS->ReinstallProtocolInterface(handles[0], &guid, security, override);
- if (err != EFI_SUCCESS)
- return log_error_status_stall(err, u"Error overriding security arch protocol: %r", err);
-
- *ret_original_security = security;
- *ret_original_handle = handles[0];
- return EFI_SUCCESS;
-}
-
-/* This replaces the platform provided security arch protocols (defined in the UEFI Platform Initialization
- * Specification) with the provided override instances. If not running in secure boot or the protocols are
- * not available nothing happens. The override instances are provided with the necessary info to undo this
- * in uninstall_security_override(). */
-void install_security_override(security_validator_t validator, const void *validator_ctx) {
assert(validator);
if (!secure_boot_enabled())
return;
security_override = (struct SecurityOverride) {
- { .FileAuthenticationState = security_hook, },
- { .FileAuthentication = security2_hook, },
.validator = validator,
.validator_ctx = validator_ctx,
};
- (void) install_security_override_one(
- (EFI_GUID) EFI_SECURITY_ARCH_PROTOCOL_GUID,
- &security_override.override,
- &security_override.original_handle,
- (void **) &security_override.original_security);
- (void) install_security_override_one(
- (EFI_GUID) EFI_SECURITY2_ARCH_PROTOCOL_GUID,
- &security_override.override2,
- &security_override.original_handle2,
- (void **) &security_override.original_security2);
+ EFI_SECURITY_ARCH_PROTOCOL *security = NULL;
+ err = BS->LocateProtocol(&(EFI_GUID) EFI_SECURITY_ARCH_PROTOCOL_GUID, NULL, (void **) &security);
+ if (err == EFI_SUCCESS) {
+ security_override.security = security;
+ security_override.original_hook = security->FileAuthenticationState;
+ security->FileAuthenticationState = security_hook;
+ }
+
+ EFI_SECURITY2_ARCH_PROTOCOL *security2 = NULL;
+ err = BS->LocateProtocol(&(EFI_GUID) EFI_SECURITY2_ARCH_PROTOCOL_GUID, NULL, (void **) &security2);
+ if (err == EFI_SUCCESS) {
+ security_override.security2 = security2;
+ security_override.original_hook2 = security2->FileAuthentication;
+ security2->FileAuthentication = security2_hook;
+ }
}
void uninstall_security_override(void) {
- /* We use assert_se here to guarantee the system is not in a weird state in the unlikely case of an
- * error restoring the original protocols. */
-
- if (security_override.original_handle)
- assert_se(BS->ReinstallProtocolInterface(
- security_override.original_handle,
- &(EFI_GUID) EFI_SECURITY_ARCH_PROTOCOL_GUID,
- &security_override.override,
- security_override.original_security) == EFI_SUCCESS);
-
- if (security_override.original_handle2)
- assert_se(BS->ReinstallProtocolInterface(
- security_override.original_handle2,
- &(EFI_GUID) EFI_SECURITY2_ARCH_PROTOCOL_GUID,
- &security_override.override2,
- security_override.original_security2) == EFI_SUCCESS);
+ if (security_override.original_hook)
+ security_override.security->FileAuthenticationState = security_override.original_hook;
+ if (security_override.original_hook2)
+ security_override.security2->FileAuthentication = security_override.original_hook2;
}

@ -0,0 +1,240 @@
From 0977e6b34fb5f28fc94f1df32261742881fa9bbe Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 30 Aug 2018 08:45:11 +0000
Subject: [PATCH] cryptsetup-generator: introduce basic keydev support
Dracut has a support for unlocking encrypted drives with keyfile stored
on the external drive. This support is included in the generated initrd
only if systemd module is not included.
When systemd is used in initrd then attachment of encrypted drives is
handled by systemd-cryptsetup tools. Our generator has support for
keyfile, however, it didn't support keyfile on the external block
device (keydev).
This commit introduces basic keydev support. Keydev can be specified per
luks.uuid on the kernel command line. Keydev is automatically mounted
during boot and we look for keyfile in the keydev
mountpoint (i.e. keyfile path is prefixed with the keydev mount point
path). After crypt device is attached we automatically unmount
where keyfile resides.
Example:
rd.luks.key=70bc876b-f627-4038-9049-3080d79d2165=/key:LABEL=KEYDEV
(cherry-picked from commit 70f5f48eb891b12e969577b464de61e15a2593da)
Resolves: #1656869
---
man/systemd-cryptsetup-generator.xml | 14 ++++
src/cryptsetup/cryptsetup-generator.c | 105 +++++++++++++++++++++++++-
2 files changed, 115 insertions(+), 4 deletions(-)
diff --git a/man/systemd-cryptsetup-generator.xml b/man/systemd-cryptsetup-generator.xml
index c37ee76b87..e30d69bfe7 100644
--- a/man/systemd-cryptsetup-generator.xml
+++ b/man/systemd-cryptsetup-generator.xml
@@ -144,6 +144,20 @@
to the one specified by <varname>rd.luks.key=</varname> or
<varname>luks.key=</varname> of the corresponding UUID, or the
password file that was specified without a UUID.</para>
+
+ <para>It is also possible to specify an external device which
+ should be mounted before we attempt to unlock the LUKS device.
+ systemd-cryptsetup will use password file stored on that
+ device. Device containing password file is specified by
+ appending colon and a device identifier to the password file
+ path. For example,
+ <varname>rd.luks.uuid=</varname>b40f1abf-2a53-400a-889a-2eccc27eaa40
+ <varname>rd.luks.key=</varname>b40f1abf-2a53-400a-889a-2eccc27eaa40=/keyfile:LABEL=keydev.
+ Hence, in this case, we will attempt to mount file system
+ residing on the block device with label <literal>keydev</literal>.
+ This syntax is for now only supported on a per-device basis,
+ i.e. you have to specify LUKS device UUID.</para>
+
<para><varname>rd.luks.key=</varname>
is honored only by initial RAM disk
(initrd) while
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index f5a81829b9..8c7a76e789 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -24,6 +24,7 @@
typedef struct crypto_device {
char *uuid;
char *keyfile;
+ char *keydev;
char *name;
char *options;
bool create;
@@ -37,14 +38,71 @@ static Hashmap *arg_disks = NULL;
static char *arg_default_options = NULL;
static char *arg_default_keyfile = NULL;
+static int generate_keydev_mount(const char *name, const char *keydev, char **unit, char **mount) {
+ _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ int r;
+
+ assert(name);
+ assert(keydev);
+ assert(unit);
+ assert(mount);
+
+ r = mkdir_parents("/run/systemd/cryptsetup", 0755);
+ if (r < 0)
+ return r;
+
+ r = mkdir("/run/systemd/cryptsetup", 0700);
+ if (r < 0)
+ return r;
+
+ where = strjoin("/run/systemd/cryptsetup/keydev-", name);
+ if (!where)
+ return -ENOMEM;
+
+ r = mkdir(where, 0700);
+ if (r < 0)
+ return r;
+
+ r = unit_name_from_path(where, ".mount", &u);
+ if (r < 0)
+ return r;
+
+ r = generator_open_unit_file(arg_dest, NULL, u, &f);
+ if (r < 0)
+ return r;
+
+ what = fstab_node_to_udev_node(keydev);
+ if (!what)
+ return -ENOMEM;
+
+ fprintf(f,
+ "[Unit]\n"
+ "DefaultDependencies=no\n\n"
+ "[Mount]\n"
+ "What=%s\n"
+ "Where=%s\n"
+ "Options=ro\n", what, where);
+
+ r = fflush_and_check(f);
+ if (r < 0)
+ return r;
+
+ *unit = TAKE_PTR(u);
+ *mount = TAKE_PTR(where);
+
+ return 0;
+}
+
static int create_disk(
const char *name,
const char *device,
+ const char *keydev,
const char *password,
const char *options) {
_cleanup_free_ char *n = NULL, *d = NULL, *u = NULL, *e = NULL,
- *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL;
+ *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL, *keydev_mount = NULL;
_cleanup_fclose_ FILE *f = NULL;
const char *dmname;
bool noauto, nofail, tmp, swap, netdev;
@@ -94,6 +152,9 @@ static int create_disk(
return log_oom();
}
+ if (keydev && !password)
+ return log_error_errno(-EINVAL, "Keydev is specified, but path to the password file is missing: %m");
+
r = generator_open_unit_file(arg_dest, NULL, n, &f);
if (r < 0)
return r;
@@ -109,6 +170,20 @@ static int create_disk(
"After=%s\n",
netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target");
+ if (keydev) {
+ _cleanup_free_ char *unit = NULL, *p = NULL;
+
+ r = generate_keydev_mount(name, keydev, &unit, &keydev_mount);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate keydev mount unit: %m");
+
+ p = prefix_root(keydev_mount, password_escaped);
+ if (!p)
+ return log_oom();
+
+ free_and_replace(password_escaped, p);
+ }
+
if (!nofail)
fprintf(f,
"Before=%s\n",
@@ -186,6 +261,11 @@ static int create_disk(
"ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
name_escaped);
+ if (keydev)
+ fprintf(f,
+ "ExecStartPost=" UMOUNT_PATH " %s\n\n",
+ keydev_mount);
+
r = fflush_and_check(f);
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", n);
@@ -221,6 +301,7 @@ static int create_disk(
static void crypt_device_free(crypto_device *d) {
free(d->uuid);
free(d->keyfile);
+ free(d->keydev);
free(d->name);
free(d->options);
free(d);
@@ -309,11 +390,27 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value);
if (r == 2) {
+ char *c;
+ _cleanup_free_ char *keyfile = NULL, *keydev = NULL;
+
d = get_crypto_device(uuid);
if (!d)
return log_oom();
- free_and_replace(d->keyfile, uuid_value);
+ c = strrchr(uuid_value, ':');
+ if (!c)
+ /* No keydev specified */
+ return free_and_replace(d->keyfile, uuid_value);
+
+ *c = '\0';
+ keyfile = strdup(uuid_value);
+ keydev = strdup(++c);
+
+ if (!keyfile || !keydev)
+ return log_oom();
+
+ free_and_replace(d->keyfile, keyfile);
+ free_and_replace(d->keydev, keydev);
} else if (free_and_strdup(&arg_default_keyfile, value) < 0)
return log_oom();
@@ -394,7 +491,7 @@ static int add_crypttab_devices(void) {
continue;
}
- r = create_disk(name, device, keyfile, (d && d->options) ? d->options : options);
+ r = create_disk(name, device, NULL, keyfile, (d && d->options) ? d->options : options);
if (r < 0)
return r;
@@ -434,7 +531,7 @@ static int add_proc_cmdline_devices(void) {
else
options = "timeout=0";
- r = create_disk(d->name, device, d->keyfile ?: arg_default_keyfile, options);
+ r = create_disk(d->name, device, d->keydev, d->keyfile ?: arg_default_keyfile, options);
if (r < 0)
return r;
}

@ -0,0 +1,33 @@
From 95bfd1d2f52698604e44c17dba2082f61b5f8eab Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 5 Oct 2018 22:37:37 +0200
Subject: [PATCH] cryptsetup: don't use %m if there's no error to show
We are not the ones receiving an error here, but the ones generating it,
hence we shouldn't show it with %m, that's just confusing, as it
suggests we received an error from some other call.
(cherry-picked from commit 2abe64666e544be6499f870618185f8819b4c152)
Related: #1656869
---
src/cryptsetup/cryptsetup-generator.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index 8c7a76e789..52391bd185 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -152,8 +152,10 @@ static int create_disk(
return log_oom();
}
- if (keydev && !password)
- return log_error_errno(-EINVAL, "Keydev is specified, but path to the password file is missing: %m");
+ if (keydev && !password) {
+ log_error("Key device is specified, but path to the password file is missing.");
+ return -EINVAL;
+ }
r = generator_open_unit_file(arg_dest, NULL, n, &f);
if (r < 0)

@ -1,31 +0,0 @@
From a43bf9f897002744610a9ea5ce7bdc91c3e3dc83 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Tue, 8 Nov 2022 12:21:35 -0800
Subject: [PATCH] networkd-ipv4acd.c: Use net/if.h for getting IFF_LOOPBACK
definition
This helps in avoiding compiling errors on musl. Definition of
IFF_LOOPBACK is the reason for including linux/if_arp.h, this however
could be obtained from net/if.h glibc header equally and makes it
portable as well.
(cherry picked from commit 239e4a42a69c31e55e58618d800e0d68c68931d3)
Related: #2138081
---
src/network/networkd-ipv4acd.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/network/networkd-ipv4acd.c b/src/network/networkd-ipv4acd.c
index 4127657ebd..877dee00ec 100644
--- a/src/network/networkd-ipv4acd.c
+++ b/src/network/networkd-ipv4acd.c
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#include <linux/if_arp.h>
+#include <net/if.h> /* IFF_LOOPBACK */
+#include <net/if_arp.h> /* ARPHRD_ETHER */
#include "sd-dhcp-client.h"
#include "sd-ipv4acd.h"

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save