Daan De Meyer [Wed, 14 May 2025 13:33:36 +0000 (15:33 +0200)]
blockdev-util: Remove dependency on string-util.h
Let's insist on a string literal in SYS_BLOCK_PATH_MAX() so that
we don't accidentally allocate VLAs and let's inline strempty() in
xsprintf_sys_block_path() so we don't need to include string-util.h
in blockdev-util.h
We'll remove the actual string-util.h include as part of #37344.
Daan De Meyer [Wed, 14 May 2025 14:51:10 +0000 (16:51 +0200)]
Introduce forward.h header with forward declarations (#37428)
In preparation for adopting forward declarations to reduce unnecessary
transitive includes across the tree, let's introduce a forward.h header
with forward declarations for all libc, libsystemd, basic and shared
types.
Additionally, this header exports all basic integer types and errno
constants, as well as all macros including assertions macros. These
header files contain types often used in headers and are always included
in every source file one way or another anyway.
To avoid having to include memory-util.h and alloc-util.h in forward.h,
we split off the parts we need from both into cleanup-util.h and only
include cleanup-util.h in forward.h.
To keep this commit self-contained, we include cleanup-fundamental.h and
cleanup-util.h from the headers that originally contained the same
macros. We'll remove these again in a later commit that optimizes the
includes in src/basic and src/fundamental.
validatefs: properly authenticate all subordinate devices of DM devices
Previously, we'd only authenticate "one" of the subordinate devices of a
DM device, and which one was somewhat undefined, it would be what we
find in slaves/ first. This is in particular a problem with dm-verity
which generally has two subordinate devices: the data device and the
hash device.
Let's fix this properly. This means two things:
1. iterate through *all* subordinate devices of a DM device (i.e.
iterate through the sysfs slaves/ subdir), not just
one
2. permit configuring a list of gpt labels and gpt type uuids in the
xattrs of mount points, so that all valid combinations can be listed.
This only updates the validation like this. The generation of xattrs
that carry multiple type uuids/labels in systemd-repart will follow in a
later commit.
This extends the syntax of the two gpt-related xattrs, to allow lists of
things. This is a true extension, without breaking compat (but even if
it was, it wouldn't matter given that validatefs was added post v257,
i.e. is not included in a stable release.
Daan De Meyer [Tue, 13 May 2025 09:50:05 +0000 (11:50 +0200)]
Introduce forward.h header with forward declarations
In preparation for adopting forward declarations to reduce unnecessary
transitive includes across the tree, let's introduce a forward.h header
with forward declarations for all libc, libsystemd, basic and shared types.
Additionally, this header exports all basic integer types and errno constants,
as well as all macros including assertions macros. These header files contain
types often used in headers and are always included in every source file one
way or another anyway.
To avoid having to include memory-util.h and alloc-util.h in forward.h, we
split off the parts we need from both into cleanup-util.h and only include
cleanup-util.h in forward.h.
To keep this commit self-contained, we include cleanup-fundamental.h and
cleanup-util.h from the headers that originally contained the same macros.
We'll remove these again in a later commit that optimizes the includes in
src/basic and src/fundamental.
journald: rename primary object from "Server" to "Manager"
In all our daemons the primary entrypoint object is called "Manager".
But so far there was one exception: in journald it was called "Server".
Let's normalize that, and stick to the same nomenclature everywhere, to
make journald less special.
Mike Yuan [Tue, 13 May 2025 20:58:02 +0000 (22:58 +0200)]
fork-journal: use char* const* for strv input param
This is compatible with char** and is what I originally
asked for in
https://github.com/systemd/systemd/pull/36858#discussion_r2086792739
Someone needs to read better ;-)
Yu Watanabe [Fri, 9 May 2025 07:56:48 +0000 (16:56 +0900)]
integration-tests: adjust priorities
When running with sanitizers:
```
26/95 systemd:integration-tests / TEST-21-DFUZZER OK 1517.75s
40/95 systemd:integration-tests / TEST-85-NETWORK-NetworkdDHCPClientTests OK 779.18s
42/95 systemd:integration-tests / TEST-04-JOURNAL OK 716.17s
```
and without sanitizers:
```
44/95 systemd:integration-tests / TEST-85-NETWORK-NetworkdDHCPClientTests OK 730.33s
29/95 systemd:integration-tests / TEST-64-UDEV-STORAGE-simultaneous_events OK 701.49s
40/95 systemd:integration-tests / TEST-04-JOURNAL OK 348.05s
```
So, let's set higher priorities only on these tests.
Yu Watanabe [Tue, 13 May 2025 14:02:13 +0000 (23:02 +0900)]
login,udev: avoid race between systemd-logind and systemd-udevd in setting ACLs
Previously, both udevd and logind modifies ACLs of a device node. Hence,
there exists a race something like the following:
1. udevd reads an old state file,
2. logind updates the state file, and apply new ACLs,
3. udevd applies ACLs based on the old state file.
This makes logind not update ACLs but trigger uevents for relevant
devices to make ACLs updated by udevd.
Yu Watanabe [Tue, 13 May 2025 14:50:22 +0000 (23:50 +0900)]
login: do not call manager_process_seat_device() more than once per event
When udevd broadcasts an event for e.g. a graphics device with master-of-seat
tag, then previously manager_process_seat_device() was called twice for
the event.
With this commit, the function is called only once even for an event for
such device.
This returns to the original approach proposed in
https://github.com/systemd/systemd/pull/17270. After review, the approach was
changed to use sd_pid_get_owner_uid() instead. Back then, when running in a
typical graphical session, sd_pid_get_owner_uid() would usually return the user
UID, and when running under sudo, geteuid() would return 0, so we'd trigger the
secure path.
sudo may allocate a new session if is invoked outside of a session (depending
on the PAM config). Since nowadays desktop environments usually start the user
shell through user units, the typical shell in a terminal emulator is not part
of a session, and when sudo is invoked, a new session is allocated, and
sd_pid_get_owner_uid() returns 0 too. Technically, the code still works as
documented in the man page, but in the common case, it doesn't do the expected
thing.
$ build/test-sd-login |& rg 'get_(owner_uid|cgroup|session)'
sd_pid_get_session(0) → No data available
sd_pid_get_owner_uid(0) → 1000
sd_pid_get_cgroup(0) → /user.slice/user-1000.slice/user@1000.service/app.slice/app-ghostty-transient-5088.scope/surfaces/556FAF50BA40.scope
I think it's worth checking for sudo because it is a common case used by users.
There obviously are other mechanims, so the man page is extended to say that
only some common mechanisms are supported, and to (again) recommend setting
SYSTEMD_LESSSECURE explicitly. The other option would be to set "secure mode"
by default. But this would create an inconvenience for users doing the right
thing, running systemctl and other tools directly, because then they can't run
privileged commands from the pager, e.g. to save the output to a file. (Or the
user would need to explicitly set SYSTEMD_LESSSECURE. One option would be to
set it always in the environment and to rely on sudo and other tools stripping
it from the environment before running privileged code. But that is also fairly
fragile and it obviously relies on the user doing a complicated setup to
support a fairly common use case. I think this decreases usability of the
system quite a bit. I don't think we should build solutions that work in
priniciple, but are painfully inconvenient in common cases.)
compress: deal with zstd decoder issues gracefully
If zstd frames are corrupted the initial size returned for the current
frame might be wrong. Don#t assert() on that, but handle it gracefully,
as EBADMSG
logs-show: use memory_startswith() rather than startswith()
Let's be strict here: this data is conceptually not NUL terminated,
hence use memory_startswith() rather than startswith() (which implies
NUL termination). All other similar cases in logs-show.c got this right.
Fix the remaining three, too.
journal-upload-journal: handle partially written fields gracefully
With the more efficient sync semantics it's more likely that
journal-upload-journal will try to read a partially written message.
Previously we'd fail then. Let's instead treat this gracefully,
expecting that this is either the end or will be fixed shortly (and
we'll get notified via inotify about it and recheck).
journal-remote: destroy event sources before MHD context
The MHD context owns the fd we watch via our event source, hence when we
destroy the context before the event source the event source might still
reference the fd that is now invalid. Hence swap the order.
journald: make journal Varlink IPC accessible to unpriv clients
The Synchronize() function is just too useful for clients, so that we
can make "systemd-run -v --user" actually useful. Hence let's make the
socket accessible without privs. Deny most method calls however, except
for the Synchronize() call.
Previously, if the Synchronize() varlink call is issued we'd wait for
journald to become idle before returning success. That is problematic
however: on a busy system journald might never become idle. Hence, let's
beef up the logic to ensure that we do not wait longer than necessary:
i.e. we make sure we process any data enqueued before the sync request
was submitted, but not more.
Implementing this isn't trivial unfortunately. To deal with this
reasonably, we need to determine somehow for incoming log messages
whether they are from before or after the point in time where the sync
requested was received.
For AF_UNIX/SOCK_DGRAM we can use SO_TIMESTAMP to directly compare
timestamps of incoming messages with the timestamp of the sync request
(unfortunately only CLOCK_REALTIME).
For AF_UNIX/SOCK_STREAM we can call SIOCINQ at the moment we initiate
the sync, and then continue processing incoming traffic, counting down
the bytes until the SIOCINQ returned bytes have been processed. All
further data must have been enqueued later hence.
With those two mechanisms in place we can relatively reliably
synchronize the journal.
This also adds a boolean argument "offline" to the Synchronize() call,
which controls whether to offline the journal after processing the
pending messages. it defaults to true, for compat with the status quo
ante. But for most cases the offlining is probably not necessary, and is
cheaper to do without, hence allow not to do it.
journald: downgrade event source priority of kmsg to same as native/syslog inputs
So far we schduled kmsg events at higher priority than native/syslog
ones. But that's quite problematic, since it means that kmsg events can
drown out native/syslog log events. And this actually shows up in some
CI tests.
Address that, and schedule all three sources at the same priority, so
that the earlier event always is processed first, regarding which
protocol is used.
journalctl: optionally delay --follow exit for a journal synchronization
Let's optionally issue a Varlink Synchronize() call in --follow mode
when asked to terminate. This is useful so that the tool can be called
and it is guaranteed it processed all messages generated before the
request to exit before it exits.
We want this in "systemd-run -v" in particular, so that we can be sure
we are not missing any log output from the invoked service before it
exits
Allow callers to synchronize on the point in time where the journal file
watches are fully established, in --follow mode.
Tools can invoke journalctl using this, knowing that any log message
happening after the READY=1 is definitely going to be processed by the
journalctl invocation.
sd-netlink: allow configuration of flags parameter when creating message object
We soon want to add for sock_diag(7) netlink sockets. Those reuse the
same message type codes for request and response but with different
message formats. Hence we need to look at NLM_F_REQUEST to determine
which message policy to apply. Hence it is essential to know the flags
parameters right away when creating a message, since we cannot do early
validation otherwise.
This only adds support for setting the flags value right at the moment
of creation of the message object, it does not otherwise add
sock_diag(7) support, that is added in a later message.
This also corrects the flag for synthetic NLMSG_ERROR messages which
should not have the NLM_F_REQUEST flag set (since they are responses,
not requests).