Daan De Meyer [Tue, 25 Nov 2025 15:46:04 +0000 (16:46 +0100)]
tree-wide: Fix constness issues with newer glibc
Latest glibc uses _Generic to have strstr() and other functions return
const char* or char* based on whether the input is a const char* or a
char*. This causes build failures as we previously always expected a char*.
Let's fix the compilation failures and add our own macros similar to glibc's
to have string functions that return a mutable or const pointer depending on
the input.
Some of the functions were ignoring failure in cleanup, others weren't. If we
got a reply, it's better to use it, so ignore failures in cleanup everywhere.
basic/terminal-util: operate on one fd in get_default_background_color()
This moves the open call earlier, so that we do any state-changing operations
if we actually managed to open the nonblocking fd. The code is easier to follow
this way and might be more robust.
Suprisingly, this fixes https://github.com/systemd/systemd/issues/39055: it
seems that run0 chowns /dev/stdin (in my case /dev/pts/0) to root:root, and the
second run0 can read and write stdin/stdout throught the already-open fds,
but fd_reopen fails.
```
==19541== 8 bytes in 1 blocks are still reachable in loss record 1 of 3
==19541== at 0x4841744: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19541== by 0x50125C9: strdup (strdup.c:42)
==19541== by 0x4C55925: getusername_malloc (user-util.c:154)
==19541== by 0x1121D6: parse_argv_sudo_mode (run.c:1098)
==19541== by 0x123B13: run (run.c:3032)
==19541== by 0x124198: main (run.c:3100)
==19541==
==19541== 11 bytes in 1 blocks are still reachable in loss record 2 of 3
==19541== at 0x4841744: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19541== by 0x50125C9: strdup (strdup.c:42)
==19541== by 0x112A9C: parse_argv_sudo_mode (run.c:1182)
==19541== by 0x123B13: run (run.c:3032)
==19541== by 0x124198: main (run.c:3100)
```
Daan De Meyer [Mon, 24 Nov 2025 14:33:26 +0000 (15:33 +0100)]
core: Make libmount optional
Instead of skipping libcore entirely when libmount is not available,
let's only compile out the pieces that need libmount. This makes the
meson logic much less complex and allows systemd-analyze to be built
when libmount is not available.
Daan De Meyer [Mon, 24 Nov 2025 13:05:29 +0000 (14:05 +0100)]
meson: Still build libshared even if libmount is disabled (#39871)
Currently, if the libmount feature is disabled, we don't build libshared
and as a result skip building every other executable as well. Among
other things, this makes our nodeps CI builds kind of pointless since
hardly any code will be compiled.
Let's improve on the situation by making libmount properly optional in
libshared. Then, we only skip building the executables that actually
need libmount.
Daan De Meyer [Mon, 24 Nov 2025 09:57:58 +0000 (10:57 +0100)]
meson: Still build libshared even if libmount is disabled
Currently, if the libmount feature is disabled, we don't build
libshared and as a result skip building every other executable as
well. Among other things, this makes our nodeps CI builds kind of
pointless since hardly any code will be compiled.
Let's improve on the situation by making libmount properly optional
in libshared. Then, we only skip building the executables that
actually need libmount.
Daan De Meyer [Mon, 24 Nov 2025 12:07:39 +0000 (13:07 +0100)]
tests: Assume we're running in a chroot if check fails
running_in_chroot() will fail when a test is executed as a non-root
user without CAP_DAC_READ_SEARCH as it won't be able to access
/proc/1/root.
Let's make things more robust by skipping tests if we can't detect
if we're in a chroot or not, since if we can't even detect if we're
in a chroot or not, chances are we're missing the required privileges
to execute the test anyway.
dlfcn-util: let's make our dlopen() code fail if we enter a container namespace
Now that we dlopen() so many deps, it might happen by accident that we
end up dlopen()ening stuff when we entered a container, which we should
really avoid, to not mix host and container libraries.
Let's add a global variable we can set when we want to block dlopen() to
ever succeed. This is then checked primarily in
dlopen_many_sym_or_warn(), where we'll generate EPERM plus a log
message.
There are a couple of other places we invoke dlopen(), without going
through dlopen_many_sym_or_warn(). This adds the same check there.
Craig McLure [Mon, 24 Nov 2025 06:02:10 +0000 (06:02 +0000)]
hwdb: Add alternative mode for Beacn Mic (#39868)
The Beacn Mic's alt-mode behaves identically to it's primary mode from a
communication perspective, it just presents a different channel
configuration to ALSA.
Luca Boccassi [Sat, 22 Nov 2025 00:25:21 +0000 (00:25 +0000)]
boot: ensure profile IDs do not get leaked and overwritten when there are tries suffixes
boot_entry_parse_tries() replaces the id, which means the id
with the profile appended is lost (leaked) and replaced by a plain filename
in case there are tries suffixes. This means the wrong order is used in
displaying the entries in the menu, as the main profile is always last
given id_without_profile has the tries suffixes and sorts higher,
while the main profile has no id_without_profile and the id sorts lower
since it does not have the tries suffix.
The previous commit fixes all remaining violations of the check for
a very specific setup (Fedora Rawhide with as many dependencies as
possible installed). The linter job in CI runs that specific setup
so we enable the check in the clang-tidy config but do not yet enable
the clang-tidy test suite in meson by default as it will very likely
still fail in different setups than the one in CI.
Daan De Meyer [Tue, 20 May 2025 10:28:15 +0000 (12:28 +0200)]
clang-tidy: Enable misc-include-cleaner check
The previous commit fixes all remaining violations of the check for
a very specific setup (Fedora Rawhide with as many dependencies as
possible installed). The linter job in CI runs that specific setup
so we enable the check in the clang-tidy config but do not yet enable
the clang-tidy test suite in meson by default as it will very likely
still fail in different setups than the one in CI.
Yu Watanabe [Fri, 21 Nov 2025 00:23:11 +0000 (09:23 +0900)]
pam-systemd: various fixlets for logging
- Do not use '%m' when errno is not set.
- Do not use pam_syslog_errno() when errno is not set.
- Use pam_debug_syslog_errno() rather than log_debug_errno().
- Use 0 rather than PAM_SUCCESS in the function that returns negative
errno, though PAM_SUCCESS == 0, hence that does not change any
behavior.
- Append missing full stop in the log message.
Yu Watanabe [Fri, 21 Nov 2025 00:21:25 +0000 (09:21 +0900)]
pam-util: make pam_debug_syslog_errno() returns pam error
Currently, the result of pam_debug_syslog_errno() is unused, hence this
does not change anything and may be slightly redundant. But let's follow
our usual coding style.
Yu Watanabe [Fri, 21 Nov 2025 00:11:34 +0000 (09:11 +0900)]
pam-util: use correct errno
- pam_log_oom() passes ENOMEM rather than -ENOMEM, hence previously
pam_log_oom() did not return PAM_BUF_ERR.
- We may (mistakenly) pass SYNTHETIC_ERRNO(). Let's gracefully handle that.
- Introduce errno_to_pam_error() helper function.
Nick Rosbrook [Fri, 21 Nov 2025 17:49:37 +0000 (12:49 -0500)]
test: skip test-reread-partition-table if missing privileges
Right now, this test runs inside unprivileged chroots, despite the
running_in_chroot() check. This is because running_in_chroot() fails
with -EACCES, which is ignored.
Hence, check for privileges before calling running_in_chroot(),
otherwise call is inconclusive. Note, the test will fail later on if
running without privileges anyways.
Chris Down [Fri, 21 Nov 2025 15:42:23 +0000 (23:42 +0800)]
nspawn: Fix broken host links for container journals (#39727)
Commit 88252ca changed nspawn to always run from a temporary mount
directory (e.g., /tmp/nspawn-root-XXXXXX). This was a good
simplification for mount logic, but it unintentionally broke the
--link-journal feature.
The setup_journal() helper was subsequently passed this ephemeral path
instead of the persistent machine path (from --directory= or --image=).
This caused the host to create broken symlinks pointing to a temporary
directory that would soon be gone.
Fix this by storing the original path and plumbing it through to
setup_journal().
All other mount-related logic in outer_child() continues to use the
temporary `directory` variable.
Chris Down [Fri, 14 Nov 2025 08:44:49 +0000 (16:44 +0800)]
nspawn: Fix broken host links for container journals
Commit 88252ca changed nspawn to always run from a temporary mount
directory (e.g., /tmp/nspawn-root-XXXXXX). This was a good
simplification for mount logic, but it unintentionally broke the
--link-journal feature.
The setup_journal() helper was subsequently passed this ephemeral path
instead of the persistent machine path (from --directory= or --image=).
This caused the host to create broken symlinks pointing to a temporary
directory that would soon be gone.
Fix this by storing the original path and plumbing it through to
setup_journal().
All other mount-related logic in outer_child() continues to use the
temporary `directory` variable.
Daan De Meyer [Thu, 13 Nov 2025 20:59:18 +0000 (21:59 +0100)]
sd-bus: Exit event loop with error code instead of EXIT_FAILURE
Instead of failing the event loop with a generic EXIT_FAILURE
error code when exit-on-disconnect is used, let's propagate the
error code instead of swallowing it.
Whereas previously sd_event_loop() would always fail with exit code
'1' when exit-on-disconnect is used with an sd-bus instance registered
with the event loop that encounters a failure, now we'll correctly
propagate the error to sd_event_loop() that caused sd-bus to fail and
exit the event loop. Additionally, the error is now also properly
propagated to outstanding reply callbacks for async dbus calls started
with sd_bus_call_async() and friends, whereas before we always used
ETIMEDOUT for these calls which is extremely confusing for users.
Why is this confusing? We always start sd-bus instances asynchronously,
in other words, sd_bus_start() will not actually wait until the bus instance
is connected, but it'll happen in the background, either driven by the first
sd_bus_call() when there is no event loop or by sd-event when there is an
event loop attached to the sd-bus instance. Assuming an event loop is attached,
when we fail to connect to the bus, the sd-bus instance will close down and the
first async method call we queued will fail with ETIMEDOUT. Nowhere in this process
do we inform the user that we failed to connect to the bus because of e.g. a permission
error, except for a debug log message.
By propagating the error to sd_event_exit() if exit-on-disconnect is enabled
and always propagating it to outstanding reply callbacks, debugging failures
becomes much easier as users will now get the actual error code causing the
bus instance to close down instead of ETIMEDOUT and 1 respectively.
Matteo Croce [Mon, 17 Nov 2025 16:30:34 +0000 (17:30 +0100)]
oomd: check if a cgroup can be killed before attempting to kill it
On OOM event, oomd tries to kill a cgroup until it succeedes.
The kill can fail with EPERM in case a pid is not killed, this leaves
the cgroup with only half of the processed killed.
This is unlikely but theoretically possible in a user namespace,
where systemd run as root inside the container and tries to kill a
cgroup with some PID from the host namespace.
To address this, send the SIG0 signal to all the processes to check
that we have privileges to kill them.
basic/terminal-util: operate on one fd in terminal_get_size_by_dsr()
This moves the open call earlier, so that we do any state-changing operations
if we actually managed to open the nonblocking fd. This makes the code more
robust because if the fdreopen call fails, we won't make modifications to the
state of the terminal.
val4oss [Wed, 19 Nov 2025 09:18:30 +0000 (10:18 +0100)]
pam_systemd: fix OSC write failure message appearing in error logs
Create and use new function pam_debug_syslog_errno() instead to ensure the
message only appears when debug mode is enabled. Pass the debug flag to
open_osc_context() and close_osc_context() to support this change.
val4oss [Wed, 19 Nov 2025 09:18:41 +0000 (10:18 +0100)]
pam-util: fix pam_syslog_errno() ignoring the level parameter
The function accepts a level parameter but was always logging at
LOG_ERR. Fix by passing the level parameter to sym_pam_vsyslog()
instead of hardcoding LOG_ERR.
This caused debug and warning messages to incorrectly appear in error
logs.
Make “effect” plural to indicate that BindsTo= also includes the other effects
of Requires= (like starting the listed units).
The documentation of Requires= already describes that the configuring unit is
stopped/restarted if any of the list units is explicitly stopped/restarted.
This made the previous wording “in addition to the effect of Requires, it
declares that if the unit bound to is stopped, this unit will be stopped too.”
ambiguous – this is no in addition, Requires= already does that, at least for
some (namely the explicit) cases.
Resolve this by making it clear what the actual difference to Requires= is and
further mention that this also includes failed units.
Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
Frantisek Sumsal [Wed, 19 Nov 2025 13:44:13 +0000 (14:44 +0100)]
timer: rebase last_trigger timestamp if needed
After bdb8e584f4509de0daebbe2357d23156160c3a90 we stopped rebasing the
next elapse timestamp unconditionally and the only case where we'd do
that was when both last trigger and last inactive timestamps were empty.
This covered timer units during boot just fine, since they would have
neither of those timestamps set. However, persistent timers
(Persistent=yes) store their last trigger timestamp on a persistent
storage and load it back after reboot, so the rebasing was skipped in
this case.
To mitigate this, check the last_trigger timestamp is older than the
current machine boot - if so, that means that it came from a stamp file
of a persistent timer unit and we need to rebase it to make
RandomizedDelaySec= work properly.
Yu Watanabe [Thu, 20 Nov 2025 04:23:51 +0000 (13:23 +0900)]
core: SMACK label to Unix socket path and FD (#39772)
Currently, when a socket unit specifies SmackLabel=,
the label is not applied to the underlying Unix socket file or its file
descriptor.
This change ensures that the SMACK label is applied both to the
Unix socket path on the filesystem and to all associated socket FDs
when the socket is created.
Testing:
- Tested on Fedora 43 with kernel 6.17.7 with SMACK enabled.
- Created a systemd socket unit:
In all cases, everything that we list in 'extract', we also list in
'sources'. We can simplify things by automatically appending the first
list to the second.
In the listings, move 'extract' key right below 'sources', since now
they are both "sources", just with slightly different meanings.
socket-label: apply SMACK label to socket and its file descriptor
When a socket unit specifies SmackLabel=, the label was previously
not applied to the underlying Unix socket file or its file descriptor.
This change ensures that the SMACK label is applied both to the
socket path on the filesystem and to the opened socket FD.