Commit Graph
91765 Commits
Author SHA1 Message Date
Yu Watanabe e677674522 resolve: use custom hash_ops for Manager.dnssd_registered_services 2026-09-23 11:38:15 +09:00
Yu Watanabe 3959ccbd32 resolve: drop unused argument t from mdns_service_update() 2026-09-23 11:38:15 +09:00
Yu Watanabe 923146d951 resolve: make several functions static 2026-09-23 11:38:15 +09:00
Yu Watanabe 02f65ebead resolve: stop timer event source and detach from browser when a dnssd service is removed
Otherwise, if the timer event source is enabled, a new query may be
invoked by the already removed service.

This also renames dns_remove_service() to dnssd_discovered_service_detach(),
and drops unused DnssdDiscoveredService.query.
2026-09-23 11:38:14 +09:00
Yu Watanabe 219abd95ae resolve: detach DnsServiceBrowser object from Manager when freed or disconnected
When a DnsServiceBrowser object is detached from the manager,
all queries, event sources, and then the reference to Manager should be
dropped. Otherwise, spurious query may be triggered for already
disconnected varlink.
2026-09-23 11:38:14 +09:00
Birk Skyum ef3e0ff7bb shutdown: preserve console graphics mode across the exitrd handoff
make_console_stdio() forces KD_TEXT while reopening /dev/console. When
systemd-shutdown enters the exitrd, this can expose the text console over
a retained graphical shutdown splash.

Let callers choose whether to switch to text mode, and preserve the mode
for the exitrd handoff. Keep the existing text-mode behavior for manager
reexecution and the crash shell. Restore text mode if executing /shutdown
fails and before reporting a fatal error and freezing.

Add an unsafe, nonparallel virtual-console regression test requiring
explicit opt-in and an already-owned inactive VT in a disposable VM.
Check graphics preservation and text restoration through a private
/dev/console bind mount, retain stderr diagnostics, and restore the saved
mode in the parent even if the child fails.
2026-09-23 11:36:55 +09:00
Yu Watanabe 137ce9b975 resolved: split oversized mDNS announcements across MTU-sized packets (#43667)
Split out of https://github.com/systemd/systemd/pull/42983

## Problem
`dns_scope_announce()` put the entire zone into a single reply packet —
for DNS-SD that is every PTR/SRV/TXT record of every published service.
With a few hundred services that grows far past the interface MTU, and
past what RFC 6762 section 17 allows: a Multicast DNS packet larger than
the MTU is sent using fragments, and such a packet "MUST NOT contain
more than one resource record".

## Fix
Pack an announcement into as many MTU-sized packets as needed. A record
that does not fit the MTU on its own is emitted alone in an oversized
packet relying on IP fragmentation — the case section 17 explicitly
allows — bounded by its hard 9000-byte ceiling including headers, which
also caps jumbo-frame links.

Without a usable interface MTU (no link on the scope, or `IFLA_MTU` not
read yet) packets are cut to the largest datagram a host of the family
must accept unfragmented — RFC 791's 576 bytes for IPv4, RFC 8200
section 5's 1280-byte minimum link MTU for IPv6 — rather than to that
ceiling, so an announcement is never fragmented merely because the MTU
was not known yet, and the lone-oversized-record path stays reachable.

A record that cannot be encoded at any size (an rdata past 64KiB, a
character string past 255 bytes) is skipped like one too large for the
ceiling rather than failing the whole announcement:
`dns_packet_append_rr()` rolls the packet back on every failure, so its
neighbours are unaffected either way.

The packing lives in `resolved-mdns.c` as
`mdns_announcement_packetize()`, taking an answer and the two size
bounds and returning finalized packets, so it is testable without a
scope, a link or a socket. Emission is best effort per packet — a failed
send no longer withholds the rest — and each pass logs the packet and
record counts it actually put on the wire.
2026-09-23 11:36:09 +09:00
Yu Watanabe 35e0a8be96 fstab-generator: support for x-systemd.onfailure (#42440)
1. test-fstab-generator: fix inverted /mnt symlink guard

   The test-18-options.fstab.input scenario was guarded by a check
   that was always true on a normal system, so it was silently
   skipped and its fixtures had drifted out of sync with actual
   generator output. This commit fixes the guard and repairs the
   stale fixtures it exposed.

2. fstab-generator: support for x-systemd.onfailure

   Add support for the x-systemd.onfailure= fstab option in
   systemd-fstab-generator. This allows configuring OnFailure=
   dependencies for generated mount units directly through /etc/fstab.

   For example:
/dev/sda1 /data ext4 defaults,x-systemd.onfailure=emergency.target 0 2

   results in the generated mount unit containing:
   [Unit]
   OnFailure=emergency.target

   This makes it possible to attach recovery targets or services to
   mount failures directly from fstab configuration.

   Add documentation and generator tests.
2026-09-23 09:08:24 +09:00
Chris Coulson fc5875d137 report: Don't create TPM2 attestation key with adminWithPolicy
The default attestation key for the TPM2 report signer is currently
created with an empty policy but with the adminWithPolicy attribute set.
This makes it impossible to authorize use of the key for the ADMIN role,
which is required by TPM2_Certify.

This drops the adminWithPolicy attribute so that it can be authorized
using its (empty) authorization value. This is appropriate for local
style attestation keys ("LAKs"). I've been working on an interface for
managing attestation keys which will support creating an IAK, and this
will have both the adminWithPolicy attribute set and a policy defined as
specified in the TCG "TPM 2.0 Keys for Device Identity and Attestation"
spec.
2026-09-23 09:05:00 +09:00
Yu Watanabe 21561b5838 util: add ansi-seq-parser helper (#43661)
This is split out of #43058, but makes sense on its own: and makes
strip_tab_ansi() a lore more complete and correct.

ptybroker is going to use for the ansi sequence parser for other
purposes too, but making strip_tab_ansi() work better is enough of a
reason to have this I think.
2026-09-23 08:58:16 +09:00
Yu Watanabe 8e910fcaf1 dissect: optionally allow attaching images that do not qualify as DDIs with --attach (#43583)
It's nice to use --attach since it validates our images. So far, it
strictly insisted on checking that the image was a DDI however, which
limits its use for certain usecases.

Add "--relax" to address this limitation.

Fixes: #43605
2026-09-23 08:54:29 +09:00
Yu Watanabe e3ffb98da2 core: open more fields up to StartTransientUnit via Varlink (#43516)
This is split out of #43058 but makes a ton of sense on its own.
2026-09-23 08:50:36 +09:00
Yu Watanabe 0eb31f9fc7 Add more debugging to pam_systemd (#43763)
Figuring out what goes wrong when something doesn't work in the PAM
stack can be quite difficult. Add detailed debug messages to help.
2026-09-23 08:41:37 +09:00
Yu Watanabe 2f08761be4 utf8,format-table: make the console width helpers agree with the UTF-8 validators (#43653)
systemd has two UTF-8 decoders, and the console width path uses the
permissive one.

`utf8_encoded_to_unichar()` performs no overlong check, no
`unichar_is_valid()` check, and still accepts the obsolete five and six
byte forms. Those checks live in the wrapper
`utf8_encoded_valid_unichar()`, which is what `utf8_is_valid()` and
`ellipsize_mem()` use. `utf8_char_console_width()` called the bare
decoder directly.

Checking both against `utf8_is_valid_n()` over all 4,244,897,280 NUL
free byte strings of length one to four, which is the entire UTF-8
encoding space:

| decoder | disagreements with `utf8_is_valid_n()` |
| --- | --- |
| `utf8_encoded_valid_unichar()` | 0 |
| `utf8_encoded_to_unichar()` | 8,835,838, always more permissive |

So `utf8_console_width()` returned a finite width for strings
`utf8_is_valid()` rejects. `format-table.c` measures a cell with
`utf8_console_width()` and, when it does not fit, hands it to
`ellipsize()`, which validates strictly and returns NULL. That is
reported as `-ENOMEM`:

```
lead surrogate    valid_utf8=0  utf8_console_width=25  ellipsize=NULL
                    -> table_format FAILS: Cannot allocate memory
```

A surrogate, overlong, noncharacter or five byte sequence in any cell
failed the whole table with a bogus out of memory error, and only once
that column was narrow enough to need truncation, so whether it happened
depended on the width of the user's terminal. At other widths the
invalid sequence was printed to the terminal instead. Invalid cells are
now refused consistently with `-EINVAL`, which is what the sequences
`utf8_encoded_to_unichar()` already rejected always produced.

The second commit fixes a related disagreement. `ellipsize_mem()` and
`align_string_mem()` open coded character width as `unichar_iswide(c) ?
2 : 1`, while `unichar_console_width()` counts a tab as eight cells.
`format-table.c` uses both: it finds a field too wide with
`utf8_console_width()`, then asks `ellipsize()` to fit that many
columns, and `ellipsize()` thought a tab was one cell, so the result
still overflowed the column that the measurement had just asked it to
fit. A table pinned to `table_set_width(20)` emitted lines of 25, 44 and
39 columns. This uses `unichar_console_width()`, which was split out for
exactly this purpose in 5c0d4b5061.

Both commits add tests that fail before the change and pass after. The
full unit suite is otherwise unaffected.
2026-09-23 08:39:10 +09:00
Roman Perehonchuk 407358d9c3 systemctl: avoid parsing properties twice for show
Pass the GetAll reply directly to the property printer for non-debug
show operations, reducing client CPU by approximately 21%.
2026-09-23 08:37:08 +09:00
Christian Glombek b3896afea2 test: add unit coverage for mDNS announcement packetization
Cover the size derivation and the packing decisions that the integration
test cannot reach: its veth MTU exceeds every record TEST-89 publishes,
so neither the oversized-record fallback nor the drop of a record beyond
the RFC 6762 section 17 ceiling is ever exercised there.

The cases pin the two size bounds for both families (including the
fallback for an MTU not known yet and the jumbo-frame cap), the split
at max_size, the lone oversized record in a fragmented packet, the
drop of a record that fits nowhere, the skip of a record that cannot be
encoded at all, that
answer-item flags reach the wire (a goodbye must keep TTL 0 and its
cache-flush bit), and that name compression stays within a packet --
the property the split exists for, since every DNS-SD name shares a
suffix and a compression pointer may not cross a packet boundary.
2026-09-23 00:30:03 +02:00
Christian Glombek d96c288ed4 resolved: split oversized mDNS announcements across MTU-sized packets
dns_scope_announce() put the entire zone -- for DNS-SD every PTR/SRV/TXT
record of every published service -- into a single reply packet. With a
few hundred published services that grows far beyond the interface MTU,
and beyond what RFC 6762 section 17 permits: a packet larger than the
MTU is sent using fragments, and such a packet "MUST NOT contain more
than one resource record".

Pack the announcement into as many MTU-sized packets as needed instead.
A single record that does not fit the MTU by itself is emitted alone in
an oversized packet, relying on IP fragmentation, which the same section
explicitly allows for that case -- bounded by its hard 9000-byte
ceiling, headers included, which also caps jumbo-frame links. While the
interface MTU is not known yet, packets are cut to the datagram size
every host of the family must be able to accept -- RFC 791 section
3.1's 576 octets for IPv4, whole or reassembled, and RFC 8200 section
5's 1280-byte minimum link MTU for IPv6, which no link fragments --
rather than to that ceiling, so an announcement is not packed for
deliberate fragmentation merely because the MTU was not read yet.

A record that cannot be encoded at any size -- a character string past
255 bytes, say -- is skipped like one too large for the ceiling, rather
than failing the whole announcement: dns_packet_append_rr() rolls the
packet back on every failure, so its neighbours are unaffected either
way. The packetizer returns how many it dropped and the scope warns on
it, since nothing else would distinguish an announcement that carried
everything from one that did not -- and for a withdrawal that matters:
the caller drops the records from the zone either way, so one skipped
here is never withdrawn at all and peers keep it for its full TTL.

The packing itself lives in resolved-mdns.c as mdns_announcement_packetize(),
taking an answer and the two size bounds and returning finalized packets,
so it can be tested without a scope, a link or a socket.
Emission is best effort per packet -- a failed send no longer withholds
the announcement's remaining packets -- and each pass logs the packet and
record counts it actually put on the wire. Each packet takes its own
token from the scope's multicast rate limit: that limit bounds datagrams
on the wire, and an announcement that would exhaust its burst is the
very flood it exists to cap.

dns_scope_send_goodbye(), the other unsolicited-response emitter, goes
through the same packetizer: a withdrawal of many records had the same
oversized-packet problem, and a single record failing to append
abandoned the whole withdrawal. Its return value follows the emitter's
now, so a withdrawal split across packets reports an error when any one
of them fails to go out.
2026-09-23 00:30:03 +02:00
Nandakumar Raghavan c99af7968e repart: add EncryptAddToken= to register custom LUKS2 tokens at provisioning time
Adds EncryptAddToken=<type>[:<source>:<value>] to repart.d partition
files, registering one or more LUKS2 token objects in the partition
header after the keyslot is created. This allows custom token plugins
(e.g. a TDX KBS plugin) to be wired up at provisioning time without a
separate cryptsetup token import step.

The type name is always explicit and extra token fields can be supplied as
a JSON file (:file:/path) or base64-encoded JSON (:data:<base64>). The
type and keyslots fields are always injected by repart. The option is
repeatable; an empty value clears all tokens for the partition.

Supported with Encrypt=key-file, tpm2, and key-file+tpm2.
2026-09-22 21:26:20 +02:00
Luca Boccassi 06c2dfa73c bless-boot: skip gracefully on kexec
If KExecsCount > 0 then do not attempt to mark a UKI, as the stub (and also
any addon and the bootloader) will not have been exercised, so there's no
guaranteed a full reboot with the same image will actually work.

Fixes https://github.com/systemd/systemd/issues/43738
2026-09-22 21:25:20 +02:00
Daan De Meyer f0f521c147 ci: only count line-anchored code fences in review comments
A triple backtick inside prose made the fence count odd, so a body with an
inline marker plus a valid suggestion block got cut at the block's closing
fence and left it open. Only fences at the start of a line delimit blocks,
so count and strip those alone.
2026-09-22 18:56:37 +02:00
nikhilnrr b7041b73cf fstab-generator: support for x-systemd.onfailure
Add support for the x-systemd.onfailure fstab option in fstab-generator.

This allows generated mount units to include the systemd OnFailure=
dependency specified through /etc/fstab.

x-systemd.onfailure= is handled by generalizing the existing
write_dependency() helper (already used for After=/Before=/Requires=/
Wants=) to take an optional unit-name suffix. When no suffix is given,
unit names are mangled without forcing a ".mount" suffix, since
OnFailure= targets are not necessarily mount units. write_on_failure()
is now a thin wrapper around write_dependency().

Example:

/dev/sda1 /data ext4 defaults,x-systemd.onfailure=emergency.target 0 2

generates:

OnFailure=emergency.target

This makes it possible to attach recovery targets or services to mount
failures directly from fstab configuration.

Add documentation and generator tests.
2026-09-22 18:48:23 +02:00
nikhilnrr 9d27286214 test-fstab-generator: fix inverted /mnt symlink guard
The test-18-options.fstab.input scenario was guarded by
"$(readlink /mnt)" != "/mnt", which is true on any normal system
since readlink prints nothing for a plain directory. This meant the
scenario was always skipped, and its fixtures were never actually
compared against generator output.

Fix the guard to check whether /mnt is a symlink directly, and repair
the pre-existing fixtures that had drifted while the scenario was
dead:

  - mnt-wantedby-automount.mount had a stale Where= value and was
    missing the escaping the generator emits for the hyphen in
    /mnt/wantedby-automount.
  - mnt-requires.mount had Requires=/After= in the wrong order.

Also extend the backslash-stripping workaround loop (used because the
.deb packager dislikes files named with a backslash) to cover
.automount units in addition to .mount/.swap, and fix an ordering bug
where -f was checked before -L, which could leave a dangling symlink
when both a unit and its drop-in symlink needed stripping.
2026-09-22 18:48:23 +02:00
Zbigniew Jędrzejewski-Szmek ab88bb2f38 pam_systemd: even more debug messages
This level of debugging might be over the top, so I kept this commit
separate. If reviewers think that it's too much, let's drop it.

It turns out that SELinux defeats getenv_secure(), so the expected
variables are not read, c.f.
https://bugzilla.redhat.com/show_bug.cgi?id=2533000#c8.
2026-09-22 18:46:41 +02:00
Zbigniew Jędrzejewski-Szmek 06997170f3 pam_systemd: add debug messages
Let's actually print out how we're called.
2026-09-22 18:46:41 +02:00
Zbigniew Jędrzejewski-Szmek a415aeb1d2 docs: fix typo 2026-09-22 18:46:41 +02:00
Georg Müller 0827be05dd kbd-util: allow kmap as a valid suffix
debian is using kmap suffix in console-data and kbd accepts this too.
2026-09-22 16:43:50 +02:00
Daan De Meyer c549d00e9f ci: let the workflow drive the Claude review instead of a coordinator agent
Reviews keep hitting the 50 minute timeout. The coordinator agent that was
supposed to launch reviewers, watch the clock, stop stragglers, validate and
write the result does none of that reliably: reviewers get stopped and lose
their findings, foreground validators can't be stopped, deadlines get
overshot by minutes, and one leftover agent keeps the process alive until
the job fails. Piling more rules into its prompt hasn't helped.

Do the orchestration in the shell instead. Run one bounded claude invocation
per review lens in parallel under timeout(1), each returning its findings as
structured output, merge them with jq and run one bounded validator over the
candidates. A lens that times out is just reported as failed. The post job
builds the tracking comment from what it actually posted, so the model no
longer authors the summary or the review bookkeeping. Agents run from an
empty directory with all inputs outside it, so the sandbox keeps both the
checkout and the inputs read-only.
2026-09-22 16:22:13 +02:00
Luca Boccassi 9bf36a72b1 test-journal: Expand coverage of reader and storage edge cases (#43835)
Let's make sure that we have wider regression coverage:

1. Verify duplicate, empty, binary, and repeated fields are stored and
enumerated correctly
2. Exercise reader position invalidation after seeking and changing
matches
3. Check cursor, data, unique-field, and field-enumeration lifetime
semantics
4. Test journal opening and following across invalid files, file
descriptor ownership, renames, unlinks, polling, immutable files, forked
readers, etc, etc
2026-09-22 16:12:20 +02:00
Lennart Poettering b8ee13613c dissect: make --detach work when passed the backing block device of a loopback device
When systemd-loop@.service is instantiated for a block device (e.g. a
CD-ROM drive, which is the primary usecase now that --relax is used),
%f resolves to the backing block device rather than to the loopback
block device that was attached on top of it. In that case ExecStop=
hence invoked --detach on a block device that is not a loopback device
at all, which made loop_device_set_autoclear() a silent no-op, leaking
the attachment.

Hence, if --detach is passed a block device that is not a loopback
block device itself, search for the loopback block device backed by it,
the same way we already do for regular files. The kernel reports the
backing inode for block device nodes too, so the same inode matching
logic applies.
2026-09-22 16:04:26 +02:00
Lennart Poettering 6a16394cd6 units: use --relax in systemd-loop@.service
Our primary usecase for this service is to deal with sector issues
around CDROMs. For that insisting on proper DDI layout and a root
partition is overkill. Let's hence relax the logic for this.

Fixes: #43605
2026-09-22 16:04:26 +02:00
Lennart Poettering b0edc60661 dissect: optionally allow attaching images that do not qualify as DDIs with --attach
It's nice to use --attach since it validates our images. So far, it
strictly insisted on checking that the image was a DDI however, which
limits its use for certain usecases.

Add "--relax" to address this limitation.
2026-09-22 16:04:26 +02:00
Lennart Poettering 937b244237 core: extend ExecStart= varlink support for StartTransientUnit() to accept execution flags 2026-09-22 16:02:44 +02:00
Lennart Poettering 214ca71682 core: open more fields up to StartTransientUnit via Varlink 2026-09-22 16:02:44 +02:00
Lennart Poettering c64cb914ac core: add exec_output_is_file() helper
The set of file based output types is open-coded in three places (and a
fourth one is about to be added), let's define it once, next to the
other ExecInput/ExecOutput predicates.
2026-09-22 16:02:44 +02:00
Armaan Sandhu 7cc0257ba8 strv: measure rebroken lines with utf8_char_console_width() too
strv_rebreak_lines() was the last place left that decoded with the permissive
utf8_encoded_to_unichar() and then asked unichar_console_width() how wide the
result is, so it accepted and measured overlong encodings, surrogates,
noncharacters and the obsolete five and six byte forms that utf8_console_width()
now refuses.

That matters because callers mix the two within a single width computation.
sd-varlink-idl.c sizes its indent with utf8_console_width() and then breaks the
body with strv_rebreak_lines(); verbs.c does the same. One half of the sum
refused a sequence that the other half happily assigned a width to.

Use utf8_char_console_width(), which does the validation and the width in one
step, and advance with utf8_next_char() rather than the decoded length. The
function already refused invalid UTF-8, so the only change is which sequences
count as invalid; it now matches utf8_is_valid(), as everywhere else.
2026-09-22 15:58:57 +02:00
Armaan Sandhu 0834378fb9 string-util,format-table: measure console width with unichar_console_width()
ellipsize_mem() and align_string_mem() open coded the width of a character as
unichar_iswide(c) ? 2 : 1, but unichar_console_width() counts a tab as eight
cells. The two disagreed, and format-table.c uses both: it decides a field is too
wide with utf8_console_width(), then asks ellipsize() to fit it into that many
columns, and ellipsize() believed a tab was one cell. The ellipsized cell then
still overflowed the column, measured by the very function that had just asked
for it to be truncated. A table pinned to table_set_width(20) emitted lines of
25, 44 and 39 columns. align_string_mem() undercounted the same way and so padded
already overlong cells further.

Use unichar_console_width(), split out for this purpose in 5c0d4b5061. While at
it, let align_string_mem() decode with utf8_char_console_width() as well, so that
the second pass shares both the width model and the validity check with the
measuring pass, instead of keeping a more permissive decoder of its own around
for the next caller to trip over. Its "count invalid chars as 1" fallback now
skips the whole rejected sequence rather than one byte, so that the continuation
bytes are not charged a cell each of their own; the branch should be unreachable
anyway, since our caller only gets there after utf8_console_width() succeeded on
the same string.

Note that unichar_console_width() charges a tab a flat eight cells, while a
terminal advances to the next multiple of eight, so this is deliberately an upper
bound: the two agree only when the tab itself starts on a multiple of eight. A
per character helper cannot do better, because a tab's width is a function of the
column it starts in, and neither ellipsize_mem() nor align_string_mem() is told
what column its string starts at. Overestimating is the safe direction: it can
leave a column padded short, but it cannot overflow one.

ascii_ellipsize_mem() equates bytes with character cells, which holds for ASCII
except for the tab, so keep tabs off that fast path. Like the ANSI sequence case
just above it, such strings now take the generic path, which means they get the
Unicode ellipsis and one reserved cell rather than "..." and three, even in a non
UTF-8 locale.
2026-09-22 15:58:57 +02:00
Armaan Sandhu cd51add717 utf8: make utf8_char_console_width() reject what utf8_is_valid() rejects
utf8_char_console_width() decoded with utf8_encoded_to_unichar(), which does not
check for overlong encodings, does not check unichar_is_valid(), and still
accepts the obsolete five and six byte forms. Those checks live in the wrapper
utf8_encoded_valid_unichar(), which is what utf8_is_valid() and ellipsize_mem()
use. Over all 4244897280 NUL free byte strings of length one to four, that is the
whole UTF-8 encoding space, the wrapper agrees with utf8_is_valid_n() everywhere,
while the bare decoder disagrees on 8835838 of them, always by accepting more.

So utf8_console_width() assigned a finite width to strings that utf8_is_valid()
refuses. format-table.c measures a cell with utf8_console_width() and, if it does
not fit, hands it to ellipsize(), which validates strictly, returns NULL, and is
reported as -ENOMEM. A surrogate, overlong, noncharacter or five byte sequence in
any cell therefore failed the whole table with a bogus out of memory error, and
only once the column happened to be narrow enough to require truncation, so
whether it happened at all depended on the width of the user's terminal. At other
widths the invalid sequence was printed to the terminal instead.

Decode with utf8_encoded_valid_unichar() so that how wide we think a string is
agrees with whether we consider it valid UTF-8 in the first place. Invalid cells
are now refused consistently with -EINVAL, the way the sequences that
utf8_encoded_to_unichar() already rejected always were.

Note that for tables this makes the refusal total rather than per field:
table_data_requested_width_height() turns a SIZE_MAX width into -EINVAL, which
table_format() propagates, so a cell in one of the newly rejected encodings now
fails the whole table at every width. systemd-dissect and repart --dry-run put
GPT partition names read straight off the image into cells without filtering
them, so a crafted partition name suppresses the whole listing where before it
cost one field, and only at some terminal widths. That is the intended trade:
the alternative is to keep emitting raw invalid bytes to the terminal at
whichever widths happen not to need truncation. Should degrading the cell rather
than the table turn out to be preferable, the place for it is where the text
enters the table, via utf8_escape_invalid() and friends, not in a helper whose
job is to say how wide a string is.

This also makes the assert(w >= 0) in utf8_escape_non_printable_full() hold by
construction rather than by the accident that its own validation was stricter
than the width helper's.
2026-09-22 15:58:57 +02:00
Lennart Poettering 2779ecaca3 string-util: port strip_tab_ansi() to AnsiSeqParser
So far strip_tab_ansi() was very superficial: it only focussed on OSC
and CSI sequences, and left the other ANSI sequences in touch.

Let's make it more powerful and port it to the more complete
AnsiSeqParser logic, and strip *all* ANSI sequences.

For the relevant usecases this seems like the better, safer choice,
since it's good to strip too much rather than too little, when
stripping ANSI sequences.
2026-09-22 15:57:58 +02:00
Lennart Poettering b8da2dc98e basic: add simple ansi sequence parser
This tries to generalize ANSI sequence handling a bit, and will track
and capture ANSI sequences in a more comprehensive fashion.
2026-09-22 15:57:58 +02:00
Frantisek Sumsal efa16c7f31 dns-packet: limit the number of jumps during packet decompression
So far we didn't limit the number of jumps when decompressing a DNS
packet. This can lead to some extra work with specially crafted packets
that send a staircase of thousands of descending compression pointers,
which can then be amplified by referencing such staircase from thousands
of names.

Given that legitimate DNS packets need only a handful of jumps in the
compression chains, let's limit the number of jumps per a single name to
256 (the same limit as, for example, Unbound currently has).

Reported by opensec-intelligence (OpenSec).
2026-09-22 15:55:13 +02:00
Luca Boccassi 726cc309b4 NEWS: open new changelog 2026-09-22 15:12:10 +02:00
Luca Boccassi af6469a83c meson: switch version to 263~devel 2026-09-22 15:12:10 +02:00
Luca Boccassi 8cc40e0c5e Finalize meson.version for v262 2026-09-22 15:12:10 +02:00
Luca Boccassi b9979c1e1a NEWS: finalize 2026-09-22 15:12:10 +02:00
Luca Boccassi 2972f1f047 NEWS: update contributors list 2026-09-22 15:12:10 +02:00
Luca Boccassi 6859ecd916 hwdb: update rules 2026-09-22 15:12:10 +02:00
Zbigniew Jędrzejewski-Szmek 541b1335f5 Rename KExecsCount to KExecCount 2026-09-22 14:38:02 +02:00
Daan De Meyer cfd2f7c73e namespace-util: fail if we cannot become root when entering a userns
namespace_enter() tried to become root after joining a user namespace
but ignored failures, so if root wasn't mapped we'd just carry on with
our original UID/GID. Let's make that an error instead.

Dropping supplementary groups stays best effort, as setgroups() might
be denied (e.g. by the nsresourced BPF LSM) even when root is mapped.

Some callers do need to enter namespaces without root, so add
NAMESPACE_ENTER_KEEP_UID_GID_IF_ROOT_UNMAPPED for those. It's used by
systemd-analyze unit-shell and by the credential refresh in the user
manager. Everything else enters containers or namespaces we allocated
ourselves, where root is always mapped.
2026-09-22 13:48:24 +02:00
Zbigniew Jędrzejewski-Szmek 63a7cf844d NEWS: some tweaks before release
Introspection is implemented for everything that has a command-line
parser, not only for select binaries.

Standarize on "rate-limit" as the spelling in docs.

Various other smaller tweaks and clarifications.
2026-09-22 12:47:54 +02:00
Yu Watanabe 6a131b32e0 include: fix limits.h override
This is especially necessary since GCC 16.x.

=====
$ gcc --version
gcc (GCC) 16.2.1 20260819 (Red Hat 16.2.1-2)
Copyright (C) 2026 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
=====

Without this change, /usr/include/limits.h is not included, hence POSIX
constants are not defined:
=====
$ echo '#include <limits.h>' | gcc -E -H -isystem ~/git/systemd/src/include/musl - 2>&1 >/dev/null | grep '^\..*limit'
. /home/watanabe/git/systemd/src/include/musl/limits.h
.. /usr/lib/gcc/x86_64-redhat-linux/16/include/limits.h
... /usr/lib/gcc/x86_64-redhat-linux/16/include/syslimits.h
=====

With this change, /usr/include/limits.h is included, thus POSIX
constants are defined:
=====
$ echo '#include <limits.h>' | gcc -E -H -isystem ~/git/systemd/src/include/musl - 2>&1 >/dev/null | grep '^\..*limit'
. /home/watanabe/git/systemd/src/include/musl/limits.h
.. /usr/lib/gcc/x86_64-redhat-linux/16/include/limits.h
... /usr/include/limits.h
...... /usr/include/linux/limits.h
.. /usr/lib/gcc/x86_64-redhat-linux/16/include/limits.h
=====

Replaces #43824.
2026-09-22 18:14:12 +09:00