Commit Graph
90662 Commits
Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek 9d8f8d55ed sysinstall: don't ask whether to erase a disk that contains no partitions
When the target disk carried no partitions, the installer still asked:

    Please type 'keep' to install the OS in addition to what the disk
    already contains, or 'erase' to erase all data on the disk:

The question is meaningless in that case: there's nothing on the disk
worth preserving, and both answers lead to the same result.

Modify fsystemd-repart to report in the dry-run reply of
io.systemd.Repart.Run() the number of partitions currently on the disk.
The field is only included if the existing partition table was actually
read, i.e. in the 'refuse' and 'allow' empty modes, and omitted
otherwise.

Make systemd-sysinstall skip the erase question if the reply positively
indicates that there are no partitions, proceeding as if 'keep' was
selected.
2026-07-17 09:18:33 +02:00
Zbigniew Jędrzejewski-Szmek efbc4481cb sysinstall: suppress 'no' prompt to begin installation
The user has to type 'yes', but it doesn't mean that the default of
'no' is ever useful. Suppress it, so the user doesn't have to press
backspace twice.
2026-07-17 09:15:09 +02:00
Zbigniew Jędrzejewski-Szmek 70cc332640 repart: log allocation failure at debug level in Varlink service mode
When systemd-sysinstall probes whether an installation would fit by
calling io.systemd.Repart.Run() in dry-run mode, systemd-repart runs as
a child process sharing sysinstall's stderr. When the requested
partitions didn't fit, context_ponder() logged its failure at LOG_ERR
before vl_method_run() converted it into a structured Varlink error
(InsufficientFreeSpace or DiskTooSmall), which the client then reports
to the user in its own words. The internal message hence appeared
interleaved with the user-facing report:

    Can't fit requested partitions into available free space (1.9G), refusing.
    The selected disk is not large enough for an OS installation.
    The size of the selected disk is 0B, but a minimal size of 15.7G is required.

Log at LOG_DEBUG when running as a Varlink service, and keep LOG_ERR
for CLI invocations, where this message is the primary error report
shown to the user.
2026-07-16 13:59:18 +02:00
Zbigniew Jędrzejewski-Szmek 588275f426 repart: report the actual block device size in currentSizeBytes
The io.systemd.Repart interface documents the currentSizeBytes field as
the size of the selected block device, both in the Run() method's
dry-run reply and in the InsufficientFreeSpace and DiskTooSmall errors.
The implementation however filled it in from the "current size"
computed by determine_auto_size(), which means something else entirely:
the size of the image as it currently exists, i.e. the GPT metadata
overhead plus the sizes of all existing partitions — a metric designed
for growing image files with --size=auto. For a disk that is being
partitioned from scratch (i.e. carries no partition table yet) that
value is 0.

As a result, when systemd-sysinstall was pointed at a blank 2G disk
that is too small for the OS installation, it reported:

    The selected disk is not large enough for an OS installation.
    The size of the selected disk is 0B, but a minimal size of 15.7G is required.

Report context->total instead, i.e. the actual size of the block
device, which is also the value the DiskTooSmall check compares the
required size against. Do this in all three places that send
currentSizeBytes, matching the documented semantics of the field.
2026-07-16 13:58:55 +02:00
Daan De Meyer 5a12005c83 copy: drop COPY_REFLINK
Reflinking is a safe optimization whenever the source and destination are
regular, seekable files on a filesystem that supports cloning. Requiring each
caller to opt in through COPY_REFLINK adds flag plumbing without changing the
necessary fallback behavior.

Drop COPY_REFLINK, renumber the remaining flags, and have copy_bytes_full()
unconditionally try FICLONE or FICLONERANGE before entering its normal copy
loop. Isolate the clone attempt and its file-offset bookkeeping in a helper so
copy_bytes_full() only has to handle its cloned, unavailable, and error results.
A successful clone therefore completes in one operation, while an unsupported
or rejected clone falls back to progress-limited copy_file_range(), sendfile(),
or buffered copying. Keep the public reflink helpers for operations that
specifically require clone semantics.

Existing test-copy coverage exercises both bounded and unbounded regular-file
copies through copy_bytes_full().

Signed-off-by: Daan De Meyer <daan@amutable.com>
2026-07-15 12:12:40 +02:00
Daan De Meyer 28b1e4ea16 repart: make COW behavior configurable
systemd-repart currently forces newly created image files into NOCOW mode.
That prevents files from being reflinked into the image, making image builds
slower and increasing their disk usage on filesystems that support cloning.

Add a tristate --cow= option. By default, leave the filesystem or parent
directory COW policy unchanged. With --cow=yes, explicitly enable COW; with
--cow=no, retain the previous behavior of forcing NOCOW. Add XO_COW as the
counterpart to XO_NOCOW so xopenat_full() applies either policy while retaining
its normal creation-error cleanup.

Document the new option and extend TEST-58-REPART to verify inherited COW and
NOCOW policies as well as explicit COW and NOCOW overrides. Compare the unset
behavior with the filesystem default so the test also works on nodatacow
mounts, and skip it when the inode attribute is unsupported.

Signed-off-by: Daan De Meyer <daan@amutable.com>
2026-07-15 09:22:58 +02:00
Jason Yang d153b49473 rules: install 60-persistent-media-controller.rules
Commit 04f19d6735 ("udev: Add /dev/media/by-path symlinks for media
controllers") added the rule file and the feature was announced in the
v256 NEWS, but the file was never added to the rules.d/meson.build
install list, so no build has ever shipped it and the advertised
/dev/media/by-path/ symlinks are never created.

Add it to the unconditionally installed rules.
2026-07-15 09:22:17 +02:00
hanjinpeng 90739ac251 sd-dhcp-relay: fix off-by-one when discarding BOOTREQUEST messages by hops count
According to RFC specifications
```
RFC 1542 section 4.1.1 states:
The relay agent MUST silently discard BOOTREQUEST messages whose 'hops'
   field exceeds the value 16."
```

"Exceeds the value 16" means hops > 16, i.e. a message that arrives with
hops == 16 is still valid and must be relayed (after which its hops field
becomes 17). The code used ">= 16", which silently dropped a valid message
that had legitimately traversed exactly 16 relay agents, one hop too early.

This matches the wording of the adjacent comment, which already says
"exceeds the value 16".
2026-07-15 08:44:31 +09:00
Yu Watanabe 5d6f9cc669 dlopen-note: drop unnecessary header
It unexpectedly snuck in there.

Follow-up for a74b3e1778.
2026-07-15 08:38:56 +09:00
Luca Boccassi bd612520e4 bcd, id128, sysupdate: tighten edge-case handling (#43018) 2026-07-15 00:03:03 +01:00
Luca Boccassi ed178351b2 Assorted udev hardening fixes flagged by kres (#42903) 2026-07-14 23:21:53 +01:00
Lennart Poettering e6acf0bab7 resolved: fix spurious BrowseServices add/remove flapping with ifindex=0 (#42982)
## Problem
A `BrowseServices` subscription with `"ifindex":0` (browse all
interfaces) receives a continuous flap of `added`/`removed` events for a
service that is still present — within a second, and with no goodbye
packet involved.

## Root cause
For `ifindex==0`, `mdns_browser_revisit_cache()` looked up each mDNS
scope's cache separately and called `mdns_manage_services_answer()`
**once per scope**. That function derives `removed` events by diffing
the browser's *global* discovered-service list (all interfaces, filtered
only by owner family) against the single answer it's handed. So with ≥2
mDNS-relevant interfaces of the same family, a service present on
interface A isn't in interface B's answer and is spuriously removed
while B is reconciled, then re-added on the next revisit tick.

## Fix
Accumulate the pruned cache answers from every matching mDNS scope into
one combined `DnsAnswer` and reconcile **once**, so removals diff the
global list against the union across interfaces. Items are merged with
`dns_answer_add_full()` (not `dns_answer_extend()`, which defaults each
item's `until` to `USEC_INFINITY` and would skew the RFC 6762 §5.2
TTL-maintenance schedule). The single-interface (`ifindex>0`) path is
unchanged.

## Test
`TEST-89-RESOLVED-MDNS.sh` gains `testcase_browse_ifindex_zero_no_flap`:
it adds a service-less dummy mDNS link to guarantee ≥2 same-family
scopes (the flap precondition), browses `ifindex=0`, waits for
discovery, then asserts **zero** `removed` events while every publisher
stays up. The subscription uses `varlinkctl --timeout=infinity`, since
it sits idle after discovery and the default 45s idle timeout would
sever it (and the assertion) mid-observation.

## Testing status
Builds clean; `shellcheck -x` clean. First CI round: `TEST-89`
(including this testcase) passed on all mkosi platforms; the failing
jobs all traced to unrelated flakes/infra.
2026-07-14 23:58:34 +02:00
Lennart Poettering d26de063cd version_is_valid() tweaks (#43025)
We have two validators, and neither really makes sense. Let's unify and
clean things up.
2026-07-14 23:46:40 +02:00
Aswin Murugan 9d925ad44e boot: downgrade EFI_MEMORY_ATTRIBUTE_PROTOCOL warning
U-Boot currently does not implement EFI_MEMORY_ATTRIBUTE_PROTOCOL
even when reporting EFI version >= 2.10. Consequently, systemd-boot
emits a warning on every boot when running on U-Boot firmware.

The absence of EFI_MEMORY_ATTRIBUTE_PROTOCOL is a current
U-Boot limitation and not a condition users can remedy.
Furthermore, the EFI specification does not require all
firmware advertising EFI 2.10 or newer to implement the
protocol. As a result, the warning provides little value on
U-Boot systems while causing log_wait() to impose a 2.5-second
boot delay.

Downgrade the message to LOG_DEBUG, this keeps the diagnostic
available for debugging purposes without penalizing normal
boot time.

Signed-off-by: Aswin Murugan <aswin.murugan@oss.qualcomm.com>
2026-07-14 22:43:19 +01:00
Lennart Poettering 231cde8089 Assorted basic/shared/home/import hardening fixes flagged by kres (#42950) 2026-07-14 23:31:53 +02:00
Lennart Poettering 64a3846ced sysupdate: Add ListFeatures() and ListTargets() varlink methods (#42900)
Following on from adding the basic varlink scaffolding to sysupdate,
let’s varlinkify a couple of the D-Bus methods. Because varlink doesn’t
have a concept of object paths, the D-Bus path structure which allows a
target to be selected has been squashed down to a target argument for
each relevant method.

Varlinkify the way to list targets, and also the way to list features
because that was simple to do at the same time.

More methods need varlinkifying in the future, but let’s do it in small
and manageable chunks.
2026-07-14 23:14:22 +02:00
Lennart Poettering e0142a76ac test: extend version_is_valid() testcase a bit 2026-07-14 22:32:27 +02:00
Lennart Poettering 8814cc9f1e bootspec: log about invalid version strings 2026-07-14 22:32:27 +02:00
Lennart Poettering 5051def45c man: update version formatting requirements in os-release
Allow full UAPI.10 version strings, i.e. "+", "_", "~" and "^" too, to
match the recent reworking.

These version strings are generally distro-managed, hence use the more
liberal alphabet.

Fixes: #32785
2026-07-14 22:32:27 +02:00
Lennart Poettering 093cac3fe8 string-util: replace version_is_valid()/version_is_valid_version_spec() by a common call
Let's take inspiration from string_is_safe() and take a flags field that
allows fine tuning the validation.

Then port over all current users of either function to the new logic.
Note that this *does* change behaviour in various cases:

1. Generally: we'll now always accept the full UAPI.10 alphabet,
   including the "~" and "^" characters. As far as I can see there's no
   downside to this liberalization as none of the current consumers of
   the two functions uses these characters for anything else.

2. systemd-analyze compare-version will now accept version strings with
   "_" and "+" without complaining. I see no downside here, it just
   normalizes these debugging tools, to make them accept what most our
   other tools accept.

3. "bootctl link" will not accept empty version strings anymore
   Which is a bugfix I guess.

4. vpick will now refuse "_" and "+" in version strings. It kinda
   already did, because when parsing versions from filenames it uses "_"
   and "+" as name, architecture and attempt counter separators. We now
   systematically refuse it everywhere else in vpick too. This is hence
   a clean-up.

Fixes: #28906
Replaces: #42815 #41937
2026-07-14 22:32:27 +02:00
Lennart Poettering d9b2960d4d string-util: reorder characters in version charset
Let's bring the version string character set into a systematic order,
matching the order in which they appear and are defined in the UAPI.10
specification text.

This makes it easier to compare the relevant functions.
2026-07-14 22:32:27 +02:00
Lennart Poettering 6acae8d17d string-util: do not accept ',' in version strings
Allowing this apparently has been cargo-culted from my initial sysupdate
PR, but Claude and me could not find a single other software package
that uses "," as a character within version strings. Hence, let's remove
this, even though this is a compat breakage of a kind, in the hope
nobody notices. We can easily restore this if this later shows to be an
issue for people.
2026-07-14 22:32:27 +02:00
Lennart Poettering b14e60c983 sysupdate: use strverscmp_improved() like everywhere else
At one location we accidentally called strverscmp() instead of
strverscmp_improved()
2026-07-14 22:32:27 +02:00
lzwind 2dcdbae4dd timedatectl: display RTCTimeUSec in UTC format
Fixes #39930

The RTCTimeUSec property was being displayed in local time format
when using 'timedatectl show', while 'timedatectl status' correctly
displayed it in UTC format. This inconsistency was due to the
bus_print_all_properties() function using TIMESTAMP_PRETTY style
for all timestamps, which formats in local time.

This fix adds special handling for RTCTimeUSec to use TIMESTAMP_UTC
style, ensuring consistent UTC display across both commands.
2026-07-14 18:29:21 +01:00
Yu Watanabe 01e1303f9c Rename basic-forward.h, sd-forward.h, and shared-forward.h to forward.h
Follow-up for 74d392ed1b.
2026-07-15 02:18:05 +09:00
Zbigniew Jędrzejewski-Szmek 0e6fe7f51f network: do not use assert() on a call with side effects
Fixes bf943a9d49.
2026-07-14 19:05:48 +02:00
Luca Boccassi e6f6ced729 dissect-image: don't assert() on partition geometry from blkid
The per-partition loop in dissect_image() reads the start and size (in
512-byte sectors) of each partition from libblkid and guards the
following byte conversions with assert(). Images sizes are input,
rather than programming, so return an error instead of asserting.

Follow-up for 88b3300fdc
2026-07-14 16:57:14 +01:00
Luca Boccassi 41fc062c49 homework-luks: add new key slots before destroying old ones
home_passwd_luks() rotates the LUKS key slots with a single loop that
destroys slot i before adding its replacement at the same index. If
adding the replacement fails (e.g.: argon2 OOMs), slot i is left
destroyed with no replacement and no rollback. If the user has only
one password, its only key slot is now gone and the home directory can
no longer be unlocked.

Rotate in two passes instead: first add every new password into a free
slot (CRYPT_ANY_SLOT), and only once all adds succeed, destroy the old
slots. If an add fails, roll back the slots added so far and return
with the pre-existing slots untouched, so at least one valid key slot
always remains for each password the user holds.

Follow-up for 70a5db5822
2026-07-14 16:57:14 +01:00
Luca Boccassi 39fa094b0d pull-oci: switch assert() to assert_se() for set_remove() call
This has obvious side effects so switch it over

Follow-up for a9f6ba0496
2026-07-14 16:57:14 +01:00
Luca Boccassi ea44ee4e8a copy: avoid following fifo/node chmod target
Use AT_SYMLINK_NOFOLLOW when applying copied FIFO and device
node modes, matching the adjacent ownership and timestamp updates.

Follow-up for e69cc9eb36
2026-07-14 16:57:14 +01:00
Luca Boccassi f5e35f72cf log: add upper bound to journal iovec accounting
Use checked arithmetic before clamping the journal iovec length.
Stop copying input iovecs once the fixed journal vector is full.

Follow-up for e69cc9eb36
2026-07-14 16:43:28 +01:00
Luca Boccassi 66600e15c9 string-util: add upper bound to ellipsize_mem UTF-8 walks
Validate UTF-8 characters against the caller-provided byte slice.
This stops truncated sequences from borrowing bytes past old_length.

Follow-up for e69cc9eb36
2026-07-14 16:43:28 +01:00
Philip Withnall 75a247d4de sysupdate: Allow multiple documentation URLs for a feature
Change the varlink API for Feature structs to allow multiple
documentation URLs for them, to match what systemd already does for
units etc.

This is a deviation from what the sysupdated D-Bus API allows and, for
the moment, from what’s supported internally by sysupdate. Internally it
continues to support 0-1 URLs for now.

But by defining the API as a strv, multiple URLs can be supported in
future without API breaks.
2026-07-14 15:03:35 +01:00
Philip Withnall a8a88fc3ba sysupdate: Run ListFeatures in offline mode
Historically, the ListFeatures API (in both D-Bus and now varlink) was
run without an `--offline` flag. This appears like it’s an oversight, but
actually `verb_features()` always unconditionally loaded in offline
mode.

In any case, there doesn’t appear to be a reason for the context to be
online (i.e. for it to check sources for available updates). Features are
defined in local config files and are loaded by `read_features()`, which
is called in both offline and online mode.

When the varlink ListFeatures API was added, it was put into online mode
in order to match the lack of `--offline` argument in the existing D-Bus
API implementation. Change both of them to be explicitly in offline mode.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2026-07-14 14:58:02 +01:00
Philip Withnall f6cd126137 test: Remove a redundant exit call
`[[ blah ]] || exit 1` is equivalent to `[[ blah ]]`.

Fixes: b0ca987cd9
2026-07-14 14:57:39 +01:00
Philip Withnall 8c166bc35e sysupdate: Downgrade an info to a debug log message
Since we now enumerate all targets on a varlink call (to validate the
requested target), this message gets printed multiple times in the log.
It’s not really necessary, so downgrade it to a debug message.
2026-07-14 14:57:35 +01:00
Philip Withnall 8cb7531390 sysupdate: Add varlink ListTargets() method
And add integration tests for it using `jq`.
2026-07-14 14:57:31 +01:00
Philip Withnall 3e34ccf6df sysupdate: Add varlink ListFeatures() method
And add integration tests for it using `jq`.
2026-07-14 14:57:13 +01:00
Philip Withnall 8085a05f86 sysupdate: Factor out core of features verb
This will be used in the following commit to add a varlink interface for
it.

This introduces no functional changes.
2026-07-14 14:57:00 +01:00
CrtlTom 9ac37aa0c7 man: update gpt-auto-generator ESP mounting behavior
Remove the stipulation that /boot/ must exist for the ESP to be mounted
there to reflect the change in #34550.
2026-07-14 14:05:57 +02:00
Yu Watanabe 944e1d3d81 meson: speed up building standalone binaries
Previously, files listed in 'sources' were built twice:
once when building the main binary, and again when building the
statically linked one.

This change ensures that all object files from the main binary are
reused when building the static binary. Hence, the only step now
necessary for the static binary is linking the object files.

Follow-up for 39d00e1d20.
2026-07-14 13:51:03 +02:00
Jonas Dreßler 04e3d8933b repart: Properly pre-calculate auto size of images
When passing --size=auto to repart, it will pre-calculate the image size and
resize the image to that size before partitioning. Currently, that fails when
passing a large grain size, complaining that the auto-sized image is too small
to fit the data.

The reason for this is that the current code simply assumes the GPT metadata
size taken away from the usable size by fdisk is static (1044KiB), when it
actually is more complicated than that:

There's two ranges of GPT metadata: One at the beginning of the image, and one
at the end of the image. And there's the first usable block that is defined by
fdisk when creating the partition table.

The static value of 1044KiB usually works, because fdisk sets the first usable
block to 1MiB (so 1024KiB), leaving 20KiB of leeway for the secondary GPT at
the end of the image.

Now as soon as the first partition starts at an offset higher than 1024KiB, we
lose the 20KiB leeway for the secondary GPT, and the partitions will no longer
fit.

What we should do, is first of all round up to the grain size instead of 4096
(as that's the minimum offset our first partition will start at), and second of
all properly subtract the secondary GPT at the end.

Also confirm we don't regress on this anymore by adding a test that uses a 2MiB
grain size, breaking the old code.
2026-07-14 12:46:50 +01:00
Luca Boccassi 321a321787 Assorted resolved hardening fixes flagged by kres (#43011) 2026-07-14 12:24:01 +01:00
Philip Withnall f8f92584db sysupdate: Improve empty table when printing features
Rather than just printing out the table header and then exiting, print
“No features” similarly to what `loginctl` or `storagectl` do.
2026-07-14 12:09:23 +01:00
dongshengyuan 9ed8392a3c sysupdate: print version details once
list VERSION printed the version status header twice in plain output.

Keep the complete later header and add a regression check.

Follow-up for: 42c0b689a8.
2026-07-14 18:52:52 +08:00
dongshengyuan e72d9b0d70 id128: honor json output for single ids
JSON mode was accepted by single-ID verbs but still printed bare IDs.

Print JSON objects for those verbs and reject ambiguous JSON combinations.

Follow-up for: a50666e376.
2026-07-14 18:52:26 +08:00
dongshengyuan 231857cfe8 boot: allow BCD fields to end at buffer limit
Allow offset + len == max; the range ends exactly at the buffer boundary.

Keep the overflow-safe bounds check and cover the edge case in test-bcd.

Follow-up for: aa1d0f2587.
2026-07-14 18:52:04 +08:00
Luca Boccassi bd7c113e24 boot: honour "read-only" vfat flag on random seed file (#43012)
Inspired by #42979
2026-07-14 11:51:43 +01:00
Luca Boccassi a5ac81ae4c systemd-run: reject unsupported option combinations (#43003)
Boundary tests were conducted on the "run" command tool, and the
identified issues were resolved.
2026-07-14 11:29:11 +01:00
Lennart Poettering 89025e8f86 repart: Fix growing the partition preceding a FreeArea from leftover space (#42969)
The "Donate to preceding partition" logic is dead code since commit

https://github.com/jonas2515/systemd/commit/19903a433507897449c086b72abb5e133e431336
("repart: split out context_grow_partition_one()").
context_grow_partition_one() gets passed a free area and a partition,
and it has
an early-return check to ensure the partition it got passed belongs to
the free
area it got passed. That means we compare the FreeArea a to the FreeArea
a->after->allocated_to_area, which always yields FALSE.

Fix the behavior of donating any left over space to the preceding
partition
by adding that partition to the loop below (and relying on the
partitions list
being ordered according to physical partition offsets).

Since this behavior is not that easy to trigger, mention how to trigger
it in a
comment, and add a test for it as well.
2026-07-14 11:27:57 +02:00