While a delegated scope waits for the async cgroup chown helper it sits
in SCOPE_START_CHOWN (UNIT_ACTIVATING). unit_start() forwards to
->start() while activating, so scope_start() could be re-entered in
that state and trip assert(s->state == SCOPE_DEAD), aborting PID 1.
Treat SCOPE_START_CHOWN as already-starting instead.
Follow-up for 03860190fe
(cherry picked from commit 62c182f0d5)
(cherry picked from commit ce595a30c1)
do_reexecute() freed the FDSet on the switch-root/soft-reboot fallback
but the caller's copy stayed live, so main() freed it again if every
fallback exec then failed. Donate the fdset instead: pass it with
TAKE_PTR() and take ownership via a _cleanup_ local, freeing it exactly
once on every exit path.
Follow-up for 3c7878f94b
(cherry picked from commit b64a44707d)
(cherry picked from commit 337cc13d8b)
In the systemd-run --scope mode, --no-block has no actual effect and will
be silently ignored. Therefore, this combination is explicitly rejected to
reduce confusion for users when using it.
Fixes: #42806
(cherry picked from commit 48dc1bbd09)
(cherry picked from commit a8d535fb55)
In the unmask path, when install_changes_add() fails the borrowed
*name was not handed back via TAKE_PTR() before returning, so
install_info_clear() freed the caller's strv entry, leaving a dangling
pointer that is double-freed at the caller's strv_free().
Follow-up for f31f10a620
(cherry picked from commit 0a869d3882)
(cherry picked from commit cfeae2790c)
quota_check_mode_from_string() returns -EINVAL on a bad value, storing
it in the global arg_mode. Only change arg_mode on success.
Follow-up for d73691c64e
Follow-up for dba4fe9a60
(cherry picked from commit 61196f5817)
(cherry picked from commit 7d0f473cb9)
unbase64mem() leaves p/sz uninitialized on failure, and the
deserialization doesn't bail out in that case, unlike other cases.
Follow-up for d247f232a8
(cherry picked from commit 7ddb3ead85)
(cherry picked from commit c4fe868f7b)
This test never finishes in Ubuntu autopkgtest with the current values,
and is currently skipped all together on Debian. When running on either,
reduce the number of disks to make the test more reliable.
(cherry picked from commit 2e89b19aa1)
(cherry picked from commit 9836c4ab8c)
journal_file_read_tail_timestamp() is called unconditionally in
next_beyond_location() for every file on every iteration step,
resulting in O(N x files) volatile mmap reads. For large queries
like 'journalctl -n 1000000' this makes the command unusably slow
(~5 minutes on systems with many journal files).
Rather than suppressing the call entirely (which would make the
inotify path fully load-bearing for cross-boot ordering), rate-limit
it to at most once per second per file. This reduces the overhead
from O(N x files) to O(T x files) where T is the iteration time in
seconds, while still providing periodic refresh as a fallback for
any missed inotify events and keeping cross-boot ordering
reasonably fresh.
Embed a RateLimit struct in JournalFile for this purpose.
Measured improvement on a real system: 5:24 -> 2:39 (-51%) for
'journalctl -n 1000000'.
Fixes: #42521
Regression introduced in: #26355 (34af74946e)
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
(cherry picked from commit 8f8ab4bf98)
(cherry picked from commit de01a0f78f)
systemd-run(1) hard-coded "the default" wording for KillUserProcesses=, but the
actual compile-time default is determined by the -Ddefault-kill-user-processes=
meson build option, which distributions set differently at packaging time.
Consistent with logind.conf(5).
Fixes: #42805
Signed-off-by: Shihao Ren <renshihao.rsh@gmail.com>
(cherry picked from commit bbb863a008)
(cherry picked from commit 2db85c4e1c)
The output array is allocated with new() and left uninitialized, but a
bare unset "$VAR" token expands to nothing and writes no terminator.
When such a token leads or is the only word, the returned strv is left
without a trailing NULL.
Follow-up for f331434d13
(cherry picked from commit 1958539136)
(cherry picked from commit 903f1d1dc6)
The CTAP2 HMAC-SECRET output should never be zero length, so enforce
that at both retrieval sites.
Follow-up for 1c0c4a43c6
(cherry picked from commit a3bf0f2f86)
(cherry picked from commit 9d3da650d0)
When setenv("CREDENTIALS_DIRECTORY") fails, log_error_errno() was
called with the stale return value of exec_context_get_credential_directory()
(which is >= 0 on success) instead of errno.
The %m in the format string correctly expands from libc's errno, so
the human-readable log message was unaffected. However, the structured
journal field ERRNO= received an incorrect value (0 or positive),
making automated log analysis and alerting on this failure unreliable.
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
(cherry picked from commit 04ab634776)
(cherry picked from commit a22d428609)
receive_portable_metadata() reads each item into a stack buffer of
PATH_MAX + NAME_MAX + 2 bytes, passes the full sizeof() as the recv
iovec length, and then NUL-terminates with iov_buffer[n] = 0. recvmsg()
can return n equal to the buffer size, so the terminator is written one
byte past the end.
Grow the buffer by one byte and cap the iovec at sizeof - 1, so a full
record is still received and the trailing NUL always fits, matching the
coredump-receive.c reader.
(cherry picked from commit 778c0e3a6c)
(cherry picked from commit d76499f0b4)
Align the documentation with the actual behavior: if $XDG_CONFIG_HOME is
set to an absolute path in the user service manager environment, it takes
precedence over the default ~/.config/ when locating environment.d files.
Also note the bootstrapping limitation that variables defined inside
environment.d files are not yet available when the generator runs.
Fixes: #42777
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
(cherry picked from commit b0d48e096c)
(cherry picked from commit ae34b3441d)
Sources in src/shared need to be licensed LGPL-2.1-or-later, not
GPL-2.0-or-later, which is the license for src/udev. Fix it.
Follow-up for 2f0aa9a804
(cherry picked from commit 2d567f7db8)
(cherry picked from commit 14ec524c1f)
And delete the file before starting, to be safe against reruns
Follow-up for c1566ef0d2
(cherry picked from commit 682a42891f)
(cherry picked from commit cc0c446e10)
The test slept a fixed 4s after starting the service, then read the
child PID from /leakedtestpid. On a loaded host the executor had not
exec'd the script yet:
[ 1571.079978] TEST-07-PID1.sh[17329]: + systemctl start issue14566-repro
[ 1571.079978] TEST-07-PID1.sh[17329]: + sleep 4
[ 1571.079978] TEST-07-PID1.sh[17329]: + systemctl status issue14566-repro
[ 1562.350438] systemd[1]: init.scope: Child 17296 belongs to init.scope.
[ 1571.081084] TEST-07-PID1.sh[17333]: ● issue14566-repro.service - Issue 14566 Repro
[ 1571.081084] TEST-07-PID1.sh[17333]: Loaded: loaded (/usr/lib/systemd/tests/testdata/TEST-07-PID1.units/issue14566-repro.service; static)
[ 1571.081084] TEST-07-PID1.sh[17333]: Drop-In: /usr/lib/systemd/system/service.d
[ 1571.081084] TEST-07-PID1.sh[17333]: └─10-timeout-abort.conf
[ 1571.081084] TEST-07-PID1.sh[17333]: Active: active (running) since Mon 2026-06-29 06:19:07 UTC; 4s ago
[ 1571.081084] TEST-07-PID1.sh[17333]: Invocation: b3356aa5fff24eee85e302250ecb06b1
[ 1571.081084] TEST-07-PID1.sh[17333]: Main PID: 17331 (9)
[ 1571.081084] TEST-07-PID1.sh[17333]: Tasks: 1 (limit: 4468)
[ 1571.081084] TEST-07-PID1.sh[17333]: Memory: 768K (peak: 768K)
[ 1571.081084] TEST-07-PID1.sh[17333]: CPU: 1ms
[ 1571.081084] TEST-07-PID1.sh[17333]: CGroup: /system.slice/issue14566-repro.service
[ 1571.081084] TEST-07-PID1.sh[17333]: └─17331 systemd-executor --deserialize 66 --log-level debug,console:info --log-target journal
[ 1562.350492] systemd[1]: Child 17297 ((sd-close)) died (code=exited, status=0/SUCCESS)
[ 1571.082379] TEST-07-PID1.sh[17334]: ++ cat /leakedtestpid
[ 1571.082379] TEST-07-PID1.sh[17334]: cat: /leakedtestpid: No such file or directory
Make the service Type=notify and notify readiness after writing the PID
file, and wait for the service to go inactive in a timeout loop instead
of fixed sleeps.
Follow-up for c1566ef0d2
(cherry picked from commit e9482b9ebb)
(cherry picked from commit 5827c35fd8)
Every mkosi file/script is LGPL-2.1-or-later, but this one is CC-0,
fix it
Follow-up for 858e59c82c
(cherry picked from commit 14d0b77287)
(cherry picked from commit 5323aefd49)
The zsh completion for timedatectl was missing three commands ('show',
'ntp-servers', 'revert') and five options (--monitor, -p/--property=,
-a/--all, --value, -P) that are already present in the bash completion,
documented in the man page, and implemented in the binary.
Fixes#16507
(cherry picked from commit 104750fd60)
(cherry picked from commit 2bb7b1ae7c)
The debug log after creating a device node passed major(i->mode) and
minor(i->mode) to format the device number, but i->mode holds the
file permission bits (e.g. 0644), not the device number.
The device major:minor is stored in i->major_minor, which is also
what mknodat() receives. Use that field instead so the log correctly
reports the created device number.
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
(cherry picked from commit af02a393f5)
(cherry picked from commit 1fc65de3b4)
SetRebootToBootLoaderEntry on non-EFI systems wrote the boot loader
entry name to /run/systemd/reboot-boot-to-loader-entry (wrong order),
while the getter and unlink both use the correct path
/run/systemd/reboot-to-boot-loader-entry.
The written value was never read back, silently breaking the feature
on non-EFI systems.
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
(cherry picked from commit e0e62a33bb)
(cherry picked from commit dd6c1c63de)
After walking a hash chain, the loop exits with p == 0. The error()
call for a tail_hash_offset mismatch passed p as the file offset,
printing 0000000000000000 instead of the actual last data object.
Pass 'last' instead, which holds the offset of the final chain entry.
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
(cherry picked from commit 99b3bbb4c0)
(cherry picked from commit b8418ff33a)
The CREATE_DIRECTORY, TRUNCATE_DIRECTORY, CREATE_SUBVOLUME,
CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA and
COPY_FILES branches in clean_item() called clean_item_instance()
but discarded its return value, always returning 0.
If dir_cleanup() fails (e.g. cannot stat a subdirectory), the error
is silently swallowed and the caller has no way to detect the failure.
The sibling EMPTY_DIRECTORY/IGNORE_PATH branches already propagate
the error correctly via glob_item().
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
(cherry picked from commit 4393625a1b)
(cherry picked from commit 38d246a627)
Amends 17260a9 (#42524).
Since there is no return path with an incomplete write, the effect of
the memset block was unobservable, so drop it.
(cherry picked from commit 5a03efc9c1)
(cherry picked from commit df9ffa2309)
I couldn't convince vmspawn to start a VM on a Fedora image I just
downloaded, and it was pretty light on any useful details:
$ build/systemd-vmspawn --image ~/Downloads/Fedora-Server-Guest-Generic-Rawhide-20260627.n.0.x86_64.qcow2 --image-format=qcow2 --bind-ro=/tmp/bar; echo $?
░ Spawning VM Fedora-Server-Guest-Generic-Rawhide-20260627.n.0.x8664.qcow2 on /home/mrc0mmand/Downloads/Fedora-Server-Guest-Generic-Rawhide-20260627.n.0.x86_64.qcow2.
░ Press Ctrl-] three times within 1s to kill VM.
1
Turns out that the unix socket path vmspawn generates for the virtiofsd
socket is too long. Let's relay this information to the user as well to
make debugging this a little less painful:
$ build/systemd-vmspawn --image ~/Downloads/Fedora-Server-Guest-Generic-Rawhide-20260627.n.0.x86_64.qcow2 --image-format=qcow2 --bind-ro=/tmp/bar
░ Spawning VM Fedora-Server-Guest-Generic-Rawhide-20260627.n.0.x8664.qcow2 on /home/mrc0mmand/Downloads/Fedora-Server-Guest-Generic-Rawhide-20260627.n.0.x86_64.qcow2.
░ Press Ctrl-] three times within 1s to kill VM.
Failed to prepare unix socket '/run/user/1000/systemd/vmspawn/Fedora-Server-Guest-Generic-Rawhide-20260627.n.0.x8664.qcow2/sock-9594581dcf598992': File name too long
(cherry picked from commit 7804fd182c)
(cherry picked from commit 71fc09c47e)
Observerd on Ubuntu 24.04 with GCC 13 on arm64 architecture.
```
../src/shared/journal-importer.c: In function ‘journal_importer_process_data’:
../src/shared/journal-importer.c:344:30: error: ‘line’ may be used uninitialized [-Werror=maybe-uninitialized]
344 | if (!journal_field_valid(line, n - 1, true)) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/shared/journal-importer.c:295:23: note: ‘line’ was declared here
295 | char *line, *sep;
| ^~~~
cc1: all warnings being treated as errors
```
(cherry picked from commit ee6522d036)
(cherry picked from commit 73b089c099)
If a varlink method takes a struct/object as a parameter, and it’s
marked as `SD_JSON_MANDATORY`, and it has an optional field inside it
which is *not* marked as `SD_JSON_MANDATORY`, we want to not require
that field to be set.
Previously, due to using the `merged_flags` from both the mandatory
struct and the optional field, `SD_JSON_MANDATORY` was effectively
always set on the optional field even if we didn’t want it. This
resulted in an error being emitted if the mandatory struct was provided
in a varlink call, but without the optional field.
Fix that by validating the field’s presence only against its own flags
and not also the flags of its parent.
Adds a unit test to prevent regressions.
(cherry picked from commit 0b3eeb1547)
(cherry picked from commit 6a5feb213e)
The example states that the first /bin/echo invocation (using ${ONE})
receives the argument 'one' (with literal single quotes). However,
Environment=ONE='one' strips the syntactic single quotes during
unquoting — see systemd.syntax(7), "Quotes themselves are removed" —
so ONE holds the value one, and ${ONE} (exact-value substitution,
always a single argument) yields the argument one without quotes.
Fixes#42442
Signed-off-by: Wang Yu <wangyu@uniontech.com>
(cherry picked from commit e61a0705db)
(cherry picked from commit 1e133c189e)
The measurement that systemd-pcrnvdone corresponds to
`src/pcrlock/pcrlock.d/770-nvpcr-separator.pcrlock`, and 770 is supposed to
happen in the initrd (which ends at 800).
(cherry picked from commit 856ab04a29)
The addition of hwdb.d/40-imds.hwdb and hwdb.d/70-debug-appliance.hwdb
are dropped. (Corresponding changes in hwdb_parse.py are kept, they are not a problem.)
When running in a mkosi namespaced env tmpfiles fails to set ACLs:
Running create action for entry a /buildroot/var/log/journal
Setting access ACL u::rwx,g::r-x,g:adm:r-x,m::r-x,o::r-x on /buildroot/var/log/journal
Setting access ACL "u::rwx,g::r-x,g:adm:r-x,m::r-x,o::r-x" on /buildroot/var/log/journal failed: Invalid argument
If EINVAL is returned and we are in a chroot, skip gracefully via
EOPNOTSUPP. The ACLs will be set on first boot.
(cherry picked from commit 3754ceba6f)
(cherry picked from commit 4a28892f49)
event_log_record_extract_firmware_description() walks the device path
of a UEFI_IMAGE_LOAD_EVENT taken from the firmware TPM2 measurement log.
The per-node loop checks the remaining bytes against the node and its
declared length, but never that dp->length covers the 4-byte node header
offsetof(packed_EFI_DEVICE_PATH, path).
For a Media/File-Path node with length 3, the file-name extraction
computes dp->length - offsetof(packed_EFI_DEVICE_PATH, path) == 3 - 4,
which wraps to SIZE_MAX. utf16_to_utf8() treats SIZE_MAX as unbounded
and runs char16_strlen() over dp->path, reading past the log buffer; a
length of 0 also leaves dp non-advancing.
efi_get_boot_option() in src/shared/efi-api.c already rejects such nodes
with "if (dpath->length < 4) break;"; do the same here.
(cherry picked from commit d2a704388f)
(cherry picked from commit 36ed303c49)
Use sd_json_variant_is_blank_array() instead of is_blank_object() for
p.addresses and p.names, which are declared as JSON arrays. The wrong
predicate never triggered, allowing empty arrays to bypass the guards:
for p.names this caused a size_t underflow leading to an out-of-bounds
heap write; for p.addresses it returned success with no addresses.
Add explicit n_addresses == 0 guards after the family-filter loops so
entries with unsupported families also return NOTFOUND rather than
crashing on a NULL dereference.
In gethostbyname3_r (family-specific entry point), return NO_DATA for
all zero-address results — both blank array and all-filtered — since
both mean "name resolved, no record of the requested family". Keep
HOST_NOT_FOUND in gethostbyname4_r (both-families) where a blank or
all-unsupported result genuinely means the name was not found.
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit dc5c09917e)
(cherry picked from commit bc167a8b36)
`systemd-analyze security --user foo.service` currently flags units
without `User=` as running as root. For user manager instances this is
impossible: per systemd.exec(5), switching user identity is not
permitted there, so the service always runs under the calling user's
UID.
Track the runtime scope inside SecurityInfo and short-circuit
security_info_runs_privileged() and assess_user() for
RUNTIME_SCOPE_USER, so that User=/DynamicUser=, SupplementaryGroups=
and RemoveIPC= are no longer marked as if the service ran as root in
both the bus-backed and --offline paths.
Fixes#40292
Signed-off-by: Shihao Ren <renshihao.rsh@bytedance.com>
(cherry picked from commit a38b4c39ff)
(cherry picked from commit 6d16e5a42a)
In home_unlocking_finish(), the success path calls operation_result_unref()
with the local variable r and the uninitialized error object. If either
user_record_good_authentication() or home_save_record() fails (both are
logged as "ignoring"), r is left negative and the D-Bus caller receives
an error reply despite the home having been unlocked successfully.
This causes PAM to reject the session even though the home directory is
mounted and accessible.
Fix by passing 0 and NULL — consistent with every other success path in
the file (home_locking_finish(), home_activation_finish(), etc.).
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
(cherry picked from commit f301d07ac6)
(cherry picked from commit a6db34ebd3)
request_handler() owns the hostname var and passes it by value to
request_meta(), which hands it to source_new(), which stores it in
source->importer.name without copying. If build_accept_encoding()
then fails, the hostname var is freed, and then the caller's
_cleanup_free_ frees it a second time.
Follow-up for 9ff48d0982
(cherry picked from commit 94d49182a0)
(cherry picked from commit 18cbe0659b)
request_reader_entries() negated m->n_skip in signed context before
casting to uint64_t, which is undefined behaviour for
n_skip == INT64_MIN.
Follow-up for 77ad3b93de
Follow-up for a7bfb9f76b
(cherry picked from commit f8891704d3)
(cherry picked from commit 7dd6f39617)
* f7762b7143 sandbox: Preserve net caps across user namespace before unsharing net
* 582eadee34 Revert "Put build history into the output directory"
* 5ef262bc53 action: don't fail if apk cannot be downloaded
* bdd341ff9b Lock the package cache during package manager invocations
* da49fe976c Put build history into the output directory
* 1c392f1918 tests: Use unique machine names
* e4f4026e30 tests: Reduce VM RAM size
* de41a5e03e Don't leak gpg-agent when signing with gpg
* 1bc5d61e1d ci: Pin openSUSE to second-to-last Tumbleweed snapshot
* c4d565a009 test: Use the main build's snapshot for extension builds
* 718b06c866 tests: ignore masked units in check-and-shutdown
* 0dc5ecbc02 ci: enable postmarketOS in integration testing
* d4c6761ad3 action: install apk to /usr/bin
* 9980f31309 mkosi-vm: add systemd-efistub to postmarketOS config
* 5640ace38f mkosi.conf: add grub to postmarketOS
* 6741b440c0 mkosi-initrd: add sulogin, device-mapper to postmarketOS initrd
* c3575c035c mkosi-tools: add missing packages to postmarketOS tools tree
* 0774bc2498 mkosi-tools: add apk-tools to tools trees for Arch and OpenSuSE
| * bb87e48401 curl: Retry on failures
|/
* 41fea1dd8d dnf: Work around librepo rejecting valid repomd signatures cross-distro
* 647e3b610b dnf: Proper repository metadata signature requirement
* 46d907cce2 dnf: Don't skip unavailable repositories during makecache
* a91e89c3b7 run_locale_gen: noop if output_format is confext
* 30329e401b tests: Make integration tests runnable locally
* be549f04db config: Don't propagate $MKOSI_DNF when using a tools tree
* 42ed648981 build(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1
* fd5eedd62b build(deps): bump aws-actions/configure-aws-credentials
* 86733c703d tree: check for root when copying SELinux attributes as well
* de2256f8fe Skip security.ima xattrs when copying tree as non-root
| * 08ebf6d678 vmspawn: Exclude secure-boot unless requested
|/
* 1d3c51e36d obs workflow: do not build aarch64/i586
(cherry picked from commit 45f561bf12)
(cherry picked from commit 44c5ab5d71)
client_context_read_extra_fields() reads a 64-bit field length v from
the per-unit log-extra-fields file. n = sizeof(uint64_t) + v overflows
when v is near UINT64_MAX, so the "left < n" check is bypassed and the
following memchr() scans v bytes past the buffer. Bound v against the
remaining bytes instead, which cannot overflow.
(cherry picked from commit 15bee24d4f)
(cherry picked from commit 610bc323bc)
uid_range_partition() filled the grown entries[] buffer backwards in
place. The backward-fill invariant (the write cursor stays above the
read index) only holds when every source entry contributes at least
one partition; an entry with nr < size contributes zero, so the cursor
stalls while the read index keeps descending. A later multi-part
entry's writes then overwrite the still-live zero-part slot, the
corrupted slot is re-read as a one-part entry, and the next
range->entries[--t] underflows.
Add a forward compaction first pass that drops the zero-part entries
before the backward fill.
Follow-up for 025439faaa
Co-Authored-by: Paul Meyer <katexochen0@gmail.com>
(cherry picked from commit d30e87ea49)
(cherry picked from commit 3a5032f79e)
dhcp6_option_parse_ia_pdprefix() validates the lifetimes but never the
prefixlen byte, so a delegated prefix with prefixlen == 0 or > 128 is
stored in the lease and handed over.
RFC 8415 defines the prefix length as 1 to 128, and the send-side
option_append_pd_prefix() already rejects 0, so reject the out-of-range
values on the receive path too.
Follow-up for f8ad4dd45d
(cherry picked from commit f98629421b)
(cherry picked from commit b242c797a5)
If the user callback set via sd_lldp_rx_set_callback() drops the last
reference to the sd_lldp_rx object, trying to use it later does not go
well. Take a ref to keep the objects alive as long as they are needed.
(cherry picked from commit a762c92a7c)
(cherry picked from commit 21159c6eef)