The hook that enforces the review deadline used bash's [[ test, but hook
commands run under /bin/sh, which is dash on the runners. Every tool call was
denied with "[[: not found", so all six lenses returned empty findings and
the run reported a clean review in 73 seconds. Use a POSIX test.
An empty result from an agent that never got a tool call through looks exactly
like a clean review, so require at least one successful tool call before a lens
counts as completed. A run like that now fails every lens, which also stops it
from raising the review count.
The "Pull Request Labeler" workflow read the full label set of a pull
request and wrote it back with setLabels(), which is a full replace. Other
workflows label the same pull request at the same time: claude-review.yml
adds the claude-review label on the pull_request_target "opened" event,
which is the very same event that starts the labeler. Whenever that add
landed between the labeler's listLabelsOnIssue() and its setLabels(), the
label was dropped again and the review never ran.
Only ever add or remove the individual labels the labeler owns, so
concurrent changes by other workflows survive. removeLabel() returns 404
when the label is already gone, which is exactly what a racing run causes,
so swallow that status.
sd_fiber_await() returned the target future's result on completion and an error
on interruption, so a negative value could mean either that the target future
resolved with an error or that the wait never finished. Most callers had to check
the target future's state afterwards to tell the two apart. Even worse, a target
resolving with -ECANCELED was indistinguishable from a cancelled wait.
Let's return 0 once the target future has resolved and a negative error only when
the wait itself did not complete. The target future's outcome stays available through
sd_future_result(), which callers have to additionally inspect now.
terminal_fix_size() queries the terminal for its dimensions with CSI 18
and DSR. On a virtual console that is pointless: the kernel renders the
screen itself, so TIOCGWINSZ is already authoritative.
It is also slow. PID 1 queries /dev/console from console_setup(), and
writes there go through redirected_tty_write(), so while plymouth holds a
TIOCCONS redirect the query never reaches the VT and no reply is ever
generated. Each query then waits out CONSOLE_ANSI_SEQUENCE_TIMEOUT_USEC.
Previously the write failed immediately with EAGAIN — the kernel forces
O_NONBLOCK on /dev/console — so the query was abandoned at no cost; since
ba10d789a8 it is retried until the timeout instead. On a Steam Deck
booting with console=tty1 and plymouth the two queries cost 667ms, about a
quarter of userspace boot time, and no log level shows it because main()
runs console_setup() between log_close() and log_open().
So skip the query on a virtual console and keep the dimensions the kernel
gave us, reporting success rather than an error: declining to ask is not a
failure, and the "dimensions already match" path below returns 0 for the
same reason.
Note this also skips the query on a /dev/ttyN that would have answered,
and does not help a serial console behind a TIOCCONS redirect.
Fixes: ba10d789a8
Fixes: d91a184509
The integration tests are started with the absolute path of the test
unit as $0, so run_subtests() derives absolute paths for the subtests
and the summary prints them in full. Show just the script name, the
directory is the same for every entry and only adds noise.
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
Not all channels used for credential transport in systemd are trusted
on SNP: while cmdline and initrd are measured and should be used,
smbios and fwcfg are untrusted and the guest should ignore creds from
those delivery paths.
Implement an offensive credential test that tries to inject credentials
via those untrusted channels and check the guest won't consume those
credentials.
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
Check that credentials passed via systemd-vmspawn --set-credential and
on the command line via systemd.set_credential= are successfully
delivered on a SNP coco guest.
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
Grow TEST-94-COCO from a single inline check into the reusable structure
that can be used by multiple future subtests:
- lib.sh: code shared between subtests on the host side.
- guest-test.sh: the testcase_coco_* checks.
- guest-test-runner.sh: runs each testcase_coco_* check, ships guest
side testcase results over vsock.
Helpers live under test/units/TEST-94-COCO/. The vsock records are
best-effort detail, the aggregate exit status stays the authoritative
pass/fail.
Split the test into subtests per platform/boot flow.
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
Reviewers ignored the tool call budget in their prompt, and the budget was a
poor stand-in for what matters anyway: per-call latency varied from 25 to
85 seconds between lenses, so the same count meant 7 minutes for one and 20
for another. Two lenses hit the timeout and lost everything they had found.
Enforce the deadline itself. run_claude exports it per invocation and a
PreToolUse hook denies further tool calls once it has passed, telling the
model to return what it has. The structured output call stays allowed, so
a slow lens still produces findings. The timeout, three minutes later, only
catches a hang. Give reviewers 22 minutes and the validator 12.
The Surface Go 3 is a tablet with a detachable Type Cover keyboard,
but its firmware reports SMBIOS chassis type 9 (Laptop), so hostnamed
reports "laptop". Override it to "convertible", which is what hostnamed
already uses for SMBIOS chassis type 0x20 (Detachable).
Tested on a Surface Go 3 with the DMI modalias
dmi:bvnMicrosoftCorporation:...:svnMicrosoftCorporation:pnSurfaceGo3:...
The existing limit for the reports was a global METRICS_MAX cap.
However on systems with a verbose socket or with many sockets
that is easily hit and because sockets are contacted in parallel
random parts of the following report generators are skipped.
It seems better to instead make the limit per-source so that one
that is overly verbose cannot starve the others. Because we already
have METRICS_LINKS_MAX this does not add a global limit - we could add
one but it would have the same problem as METRICS_MAX before, some
report would be cut that might be important (or we need to be explicit
about ordering but even then its problematic if we have two
"important" ones and one is buggy and generates too much data).
Note that this keeps the METRICS_PER_SOURCE_MAX at 4096 because
io.systemd.Manager reports a lot, on my idle test VM already
~3k.
We also now report any issue with the metric instead of just the
first one in verb_metrics.
In preparation for adding a varlink interface for key management, add
support for signing reports with multiple TPM2 keys. During signing,
this iterates over all *.key files in /var/lib/systemd/report.sign.tpm2,
generating a TPM signature with each one. It also looks for the
corresponding *.voucher file, containing some credential that is used to
prove that the signing key is authentic, and which is added to the
signature if it exists.
If no signing keys exist when a signature is requested, a default
signing key is still created as default.key.
Classical DNSSEC algorithms such as RSA and ECDSA are vulnerable to
quantum computers. Add support for post-quantum ML-DSA-44, DNSSEC
algorithm 18.
Verify pure ML-DSA through OpenSSL. Report the algorithm as unsupported
only when it is unavailable. Treat key import and verification failures
as hard errors.
Add the draft test vector and negative tests.
https://datatracker.ietf.org/doc/draft-westerbaan-dnssec-mldsa/
Signed-off-by: Ayoub Zaki <ayoub.zaki@embetrix.com>
This renames BLOCKDEV_LIST_IGNORE_ZRAM to BLOCKDEV_LIST_IGNORE_RAMDISK,
and make it ignores both /dev/ramX and /dev/zramX.
Note, linux-stable by Alpine/postmarketOS has CONFIG_BLK_DEV_RAM=y,
hence the kernel creates /dev/ramX by default. Without this change,
the test case added by 236e7d8a4c fails,
as io.systemd.Repart.ListCandidateDevices varlink method lists the
ramdisks.
An AF_UNIX stream receive can combine a message without file descriptors
with a following SCM_RIGHTS-bearing message. This associates the received
descriptors with the earlier message even when the sender uses separate
sendmsg() calls.
Use the existing boundary-limited read path whenever FD input is enabled
on stream sockets, not only for protocol upgrades. Include the buffered
delimiter suffix in the peek search so a split CRLF delimiter cannot
over-read into the next message either.
Record the input socket type when attaching the descriptors so the new
FD-triggered limit does not truncate packet sockets. Explicit bounded
reads retain their existing semantics.
Add regressions for a oneway request followed by an FD-bearing request,
a continued reply followed by an FD-bearing terminal reply, a split CRLF
delimiter followed by an FD-bearing message, and batched messages on
SOCK_SEQPACKET and SOCK_DGRAM.
Fixes#43823
Previously in CI:
../src/test/fsprg.c:18:1: error: included header gcrypt-util.h is not used directly [misc-include-cleaner,-warnings-as-errors]
18 | #include "gcrypt-util.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~
19 | #include "memory-util.h"
../src/test/fsprg.c:19:1: error: included header memory-util.h is not used directly [misc-include-cleaner,-warnings-as-errors]
19 | #include "memory-util.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~
20 |
2 warnings treated as errors
AI agents prepend a notice to README.md that the author removes once they
have reviewed the changes. Until that happens nobody else should look at
the PR: convert it to a draft, don't add the please-review label, and
don't start a Claude review. The labeler and the review workflow check
README.md at the PR head for the notice. Marking the PR ready for review
after removing the notice triggers the normal labeling again.
This function constructs the NDisc Encrypted DNS option (RFC 9463).
`poff` is initialized to `off + sizeof(uint16_t)` - pointing past the 2
bytes SvcParam length field. After all SvcParams are written the length
is set at line 1541. `LESS_BY(poff, off) = poff - off` includes the 2
bytes length field itself. The correct value is `poff - off -
sizeof(uint16_t)`.
gcc does not inline sipround() at -O2: its size estimate lands just over
the default max-inline-insns-auto budget, so nm on libsystemd-shared.so
shows a local sipround symbol and each of the ten call sites pays a
call/ret plus a reload and store of the state through the pointer, around
six rounds of ~14 ALU ops. clang inlines it on its own, and gcc does too
at -O3 or with --param max-inline-insns-auto=30, so this is not a missed
optimization to report upstream but the inliner's size heuristic doing
what it is designed to do. The documented way to overrule it for one
function is always_inline.
The SipHash reference implementation this file is derived from inlines
the round manually, by writing it as a SIPROUND macro.
AMD Ryzen AI 7 350, gcc 16.2.1, -O2 -fstack-protector-strong
-fno-strict-aliasing, median of five runs:
input before after speedup
8 B 61.3 ns 9.3 ns 6.63x
16 B 54.6 ns 10.7 ns 5.11x
24 B 50.0 ns 12.6 ns 3.98x
40 B 49.4 ns 16.4 ns 3.01x
64 B 53.2 ns 22.1 ns 2.41x
128 B 67.8 ns 36.9 ns 1.84x
512 B 157.7 ns 128.1 ns 1.23x
4096 B 992.5 ns 964.5 ns 1.03x
The win is concentrated on short inputs because the bulk loop in
siphash24_compress() was the one place gcc did inline the round; the
prologue, the tail and all six rounds of siphash24_finalize() were not.
Short inputs are also what we overwhelmingly hash: hashmap and set keys,
unit names, paths, journal field names and data objects, bus match
strings. clang is unaffected.
Resulting hash values are unchanged; verified identical over every input
length from 0 to 128 bytes, and test-siphash24, test-hash-funcs,
test-hashmap and test-set pass.
When generating a session audit digest, the algorithm isn't included in
the attestation. The algorithm is the auth digest algorithm that the TPM
session is created with, which is currently hardcoded as SHA-256.
This might not always be the case though, and verifiers shouldn't have
to guess what the digest algorithm is, so include the algorithm in the
report signature component.
This uses a random high-entropy ID for reports, making it useful
when hashing the report for passing it to the Time Stamping
Authority. Reports are therefore guaranteed to be distinct from
one another.
So far BLOCKDEV_LIST_IGNORE_VIRTUAL filtered out everything below
/sys/devices/virtual/, which includes loopback devices. Loopback devices
are frequently used as stand-ins for real disks though (in tests, and
when installing to disk images), hence it's useful to be able to control
them independently of the other virtual devices (dm, md, zram, …).
Introduce a separate BLOCKDEV_LIST_IGNORE_LOOP flag for loopback
devices, and make BLOCKDEV_LIST_IGNORE_VIRTUAL only cover the non-loop
virtual devices. The only existing user (systemd-report) is updated to
pass both flags, so that its behaviour stays unchanged.
We want users to use a recovery-key generated by systemd. Therefore
expose a method that let's clients generate a key that can be given to
the Enroll method. This way the key can be displayed before enrolling
it.