This may be useful for decompressing data straight into a file
descriptor, without allocating a large in-memory buffer for the
entire decompressed payload.
Only type/length/revision are the generic performance record header; the
pointer is specific to the Firmware Basic Boot Performance Table Pointer
Record. Check that the record fits into the table where its length is
validated against the expected size, so rec->ptr is never read past the
end of the buffer.
The man page mmap(2) states the following:
> The fd argument is ignored; however, some implementations require
> fd to be -1 if MAP_ANONYMOUS (or MAP_ANON) is specified, and
> portable applications should ensure this.
Fixes the following failure:
```
$ sudo valgrind --leak-check=full ./test-fiber
==1070213== Memcheck, a memory error detector
==1070213== Copyright (C) 2002-2026, and GNU GPL'd, by Julian Seward et al.
==1070213== Using Valgrind-3.27.1 and LibVEX; rerun with -h for copyright info
==1070213== Command: ./test-fiber
==1070213==
/* test_fiber_simple */
valgrind: m_debuginfo/debuginfo.c:1168 (vgPlain_di_notify_mmap): Assertion 'use_fd >= -1' failed.
host stacktrace:
==1070213== at 0x58053B1F: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==1070213== by 0x5804FC83: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==1070213== by 0x5804FE9B: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==1070213== by 0x58082A00: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==1070213== by 0x580C8BF2: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==1070213== by 0x580ABE14: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==1070213== by 0x580B74B6: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==1070213== by 0x58113907: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable syscall 9 (lwpid 1070213)
==1070213== at 0x519387C: mmap (in /usr/lib64/libc.so.6)
==1070213== by 0x4D277AB: fiber_allocate_stack (fiber.c:122)
==1070213== by 0x4D29B0E: sd_fiber_new (fiber.c:727)
==1070213== by 0x402B3A: test_fiber_simple (test-fiber.c:32)
==1070213== by 0x4B628CD: run_test_table (tests.c:410)
==1070213== by 0x423E31: main (test-fiber.c:2861)
client stack range: [0x1FFEFFE000 0x1FFF000FFF] client SP: 0x1FFEFFFD70
valgrind stack range: [0x1002BAA000 0x1002CA9FFF] top usage: 9960 of 1048576
Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.
If that doesn't help, please report this bug to: www.valgrind.org
In the bug report, send all the above text, the valgrind
version, and what OS and version you are using. Thanks.
```
In some cases it might make sense to provide
features/transfers/components in a more dynamic fashion. Let's add a
concept of "sysupdate provider" backends, that can provide such
definitions at runtime.
Fixes: #33351Fixes: #30695
This utilizes the `mkdir_foreign_at` helper function to create
foreign-owned directories. I extended it to `mkdir_foreign_at_full` to
allow for creating btrfs subvolumes too (thanks for merging #43869 to
enable this).
When a read-only directory is requested, the system instance can create
a read-only mount and return a file descriptor to that.
The unprivileged user instance can't do that, so it just returns the
directory file descriptor. An alternative would be to not allow for
read-only requests, but its not like we're consulting polkit for user
session requests.
When asked to shut down, nspawn sends KillSignal= to the container's
PID 1, but logged the signal it received instead, e.g. "Trying to halt
container by sending TERM to container PID 1" for a booted container,
which actually gets SIGRTMIN+3.
Use mkdir_foreign_at_full() to create directory volumes from the user
instance. Unlike the system instance, read-only directories can't be
enforced by the storage instance, but are still supported.
Initial deployment experience indicates that if tags are short strings,
chaos ensues. Change "berlin" to "company.location=berlin" and "webserver"
to "company.role=webserver", where "company." is described as a identifier
for the organization. This way, people get to arrange their own mess in
their namespace as they wish, and we have some hope that we can combine
tags from different sources.
We had two implementations that very slightly differed in interpretation
of what is valid. Let's just reuse the same underlying logic in both
places. The tests are adjusted appropriately.
This additional advantage is that the O(n²) implementation is replaced by
O(n).
When duplicates were present, the existing code picked the
lexicographically earliest entry. This is strange, no other code
that combines list in systemd behaves in this way. This really looks
like an accident of implementation.
In graceful mode, rework the parsing to take the key=value pair that is
specified last. Also, rework the code to use a hashmap. This allows the
graceful and non-graceful paths to be unified into a single pass.
In graceful mode a conflicting tag is replaced by the entry specified
later, in strict mode refused. Every valid tag counts towards
MACHINE_TAGS_MAX.
(The O(n²) complexity in sorting of the tags wasn't great. The tag list is
bounded to 1024 items, so this wasn't _too_ bad, but the approach with the
hashmap is not much more complicated and has better computational
complexity, now the dominant part is O(n×log n) sort that happens later.)
For systemd-firstboot this means that a conflicting tag repeated in
--machine-tags= or in the firstboot.machine-tags credential is now an
error. The duplicated description of tag syntax in systemd-firstboot man
page is replaced by a reference. It was already inaccurate previously,
after not having been adjust for key=value.
The F4 key on modern MSI Stealth 14 laptops (such as the Stealth 14 Studio A13VF)
emits the Windows Precision Touchpad combination (Ctrl + Super + scancode 0x76).
Mapping scancode 0x76 to touchpad_toggle allows desktop environments (like GNOME)
to toggle the touchpad on/off.
Add the DMI match for MSI Stealth 14 laptops to match the existing Prestige and Modern rules.
Verified on MSI Stealth 14 Studio A13VF (MS-14K1).
Signed-off-by: Mahdi Shariat <mahdishariat@proton.me>
If the user doesn't set the node parameter, determine the node backing
/var/. This is usefull for installers or any UI that want to operated on
the
current system.
The HP Pavilion Gaming Laptop 15-dk0xxx embedded controller emits atkbd
scancodes d7/d8 on lid cycles. The generic HP block maps d7 to KEY_WLAN,
so every lid cycle soft-blocks the radios through rfkill (airplane mode);
d8 is likewise grabbed by the Pavilion block as a touchpad toggle.
The sibling 15-dk1* chassis already carries the d7/d8=unknown override
("# Pavilion gaming 15-dk1* (lid keys)") for exactly this reason, but
15-dk0xxx does not match it and falls through to the generic HP d7=wlan
mapping. Add a matching entry for 15-dk0xxx.
Verified on HP Pavilion Gaming 15-dk0xxx (Insyde F.67): without the
override `systemd-hwdb query` resolves KEYBOARD_KEY_d7=wlan and a lid
cycle soft-blocks phy0; with it, d7/d8 are unknown and lid cycles leave
both radios enabled. evtest on the AT keyboard (event3) shows d8 on lid
close and d7 on lid open.
Currently we only look at the "validatefs" xattrs when mounting
partitions at system boot. Let's also validate them when processing
DDIs, in order to lock things down further a bit.
Given that we default to AddValidateFS= anyway in repart, let's add the
other side too for all DDIs we activate during runtime.
ListImages() is implemented on org.freedesktop.import1.Manager
(manager_vtable), but 5b7bfe0637 added its allow rule under
org.freedesktop.import1.Transfer, so unprivileged callers are denied by
the bus even though the method is marked SD_BUS_VTABLE_UNPRIVILEGED.
Since systemd-pull now understands "provider:[/path/to/socket]/name"
URLs, allow them in the Path= setting of url-file and url-tar sources,
wherever HTTP/HTTPS URLs are accepted. Manifests and payloads are then
acquired from the specified io.systemd.ResourceProvider service, with
the same verification as for web servers. Document the scheme, and how
component providers can use it to serve their own resources.
Fixes: #33351
Teach systemd-pull to acquire resources via "provider:[/path/to/socket]/name"
URLs: connect to the specified AF_UNIX socket, invoke
io.systemd.ResourceProvider.AcquireResource() with a protocol upgrade,
and read the raw resource data from the upgraded connection. Everything
below the transport – compression detection and decompression, size
and checksum verification, the SHA256SUMS/.sha256/signature lookups
with their not-found fallbacks, --direct, --offset= and --sync= – works
unchanged, since the data is fed through the same code as with curl.
The transport is fully asynchronous, driven by the same event loop as
the curl jobs, using sd_varlink_invoke_and_upgrade().
importctl and systemd-importd accept such URLs too.
Factor the parts of PullJob that don't depend on the transport out of
the curl callbacks: feeding downloaded data into compression detection
and decompression, finalizing a completed download (size and checksum
verification, finishing the target file), and progress reporting. Also
add an accessor for the event loop a CurlGlue is attached to.
This prepares for adding a second transport. No behaviour change.
A generic interface for acquiring the contents of named resources from a
local service: AcquireResource() is called with the "upgrade" flag, and
after the reply the connection carries the raw resource data until the
provider closes it. It is addressed via "provider:[/path/to/socket]/name"
URLs.
Introduce a URL scheme for acquiring resources from local Varlink
services: "provider:[/path/to/socket]/resource" names a resource offered
by the service listening on the specified AF_UNIX socket. Add parsing
and validation helpers, and teach the import URL path manipulation
helpers to skip bracketed host components, since the socket path may
contain slashes, so that sibling resources such as SHA256SUMS files are
derived from provider URLs the same way as from HTTP URLs.
Describe the io.systemd.SysUpdate.Provider interface, the socket
directory, the precedence rules and the resulting restrictions in
sysupdate.components(5), and reference it from the other sysupdate man
pages..
Teach systemd-sysupdate to consult the component providers in
/run/systemd/sysupdate/provider/ in addition to the file system, when
operating on the host (i.e. neither --root=, --image= nor --definitions=
are used):
* The list of components is the union of the components defined in
the file system and those offered by any provider. Components defined
in the file system always win; among providers the one whose socket
name sorts first wins.
* When the file system defines nothing for a named component, i.e.
neither a .component file nor any feature or transfer definition
could be loaded for it, its definition (metadata, features,
transfers) is acquired via DescribeTarget() instead.
* enable-component/disable-component and enable-feature/disable-feature
refuse to operate on provider-backed components, since their
definitions do not live in the file system. In the --component-all
and --component-suggested modes such components are skipped.
* If not all providers could be asked, a component that is not found is
not treated as removed, so that "cleanup" and "update --cleanup=yes"
don't delete installed files just because a provider is down.
The "components --json" output gains a "providers" map naming the
provider of each component whose definition came from a provider.
Inspired-by: #33351
get_component_list() so far only considered sysupdate.<name>.d/
directories when enumerating components. A sysupdate.<name>.component
file is a definition of the component as well, hence pick those up too,
so that a component that (so far) only has a metadata file is listed.
Add the client side of io.systemd.SysUpdate.Provider: connect to all
sockets in /run/systemd/sysupdate/provider/ in parallel, collect the
replies and process them sorted by provider name, so that the provider
whose socket name sorts first wins if several claim the same component.
When asking for the definition of a component, distinguish "no provider
offers it" from "not all providers could be asked": the latter must not
be mistaken for the former by callers that clean up after components
that went away.
Add component_from_json(), feature_from_json() and transfer_from_json(),
which fill in the respective objects from JSON objects shaped like the
types of the io.systemd.SysUpdate.Provider interface, i.e. mirroring the
settings of the configuration files one to one. The transfer constructor
shares the validation and completion logic with the file parser via
transfer_finalize(). In contrast to the configuration files no specifier
expansion takes place.
Move the part of transfer_read_definition() that validates and completes
a transfer definition into transfer_finalize(), and factor the semantic
bits of the MatchPattern=, Path= and InstancesMax= parsers into helpers
that don't depend on the config file parser. Also add a
context_add_transfer() helper that sorts a transfer into the enabled or
disabled list of a context.
This prepares for building transfer definitions from other sources than
configuration files. No behaviour change.
Define the interface component providers implement to feed
systemd-sysupdate with component definitions: ListTargets() returns the
components a provider offers as targets of class 'component', in the
same format as ListTargets() of the io.systemd.SysUpdate interface, and
DescribeTarget() the full definition of one of them, i.e. its target
object, features and transfers. The types mirror
sysupdate.components(5), sysupdate.features(5) and sysupdate.d(5) one
to one, reusing the Target type of the io.systemd.SysUpdate interface.
Also define the directory systemd-sysupdate will look for provider
sockets in.
Extend the Target type of the io.systemd.SysUpdate interface with the
metadata settings of sysupdate.components(5): ListTargets() now fills
them in for targets of class 'component', with the effective enablement
and suggestion state, and leaves them unset for other classes. The
"components --json" output gains a matching "details" array, generated
by the same serializer.
Allow the version bounds and protected versions to be specified once for
a whole component in its .component file. The effective settings of a
component are determined by component_min_version(),
component_max_version() and component_version_is_protected(), which
combine the component's own settings with those of all its enabled
transfers: the more restrictive bound wins, and a version is protected
if the component or any of its enabled transfers lists it.
The two parsers are moved to sysupdate-config.c so both the transfer and
the component tables can share them.
Add a MaxVersion= setting to the [Transfer] section, complementing the
existing MinVersion=. Versions newer than it are flagged "too new": they
are never selected as update candidate, and an explicit request to
install one is refused. Otherwise they are treated like any other
version, i.e. they remain subject to vacuuming and cleanup, and an
already installed too-new version is not removed.
Since the newest available version may now be ineligible while an older
one is fine, candidate selection no longer requires the "newest" bit but
picks the first eligible available version in newest-to-oldest order.
The selected candidate is flagged explicitly, so that the assessment
shown by "list" reflects it even if it isn't the newest version.
Expose the new state in the "list" output, the JSON output ("tooNew",
"candidate") and updatectl.
Fixes: #30695
update_set_flags_to_string() so far listed every valid combination of
update set flags in one giant switch. That doesn't scale when adding
further flag bits. Replace it by a function that composes the string from
a base assessment plus suffixes into a caller-provided buffer, exposed via
a FORMAT_UPDATE_SET_FLAGS() convenience macro, and pin the produced
strings down with a unit test.
No behaviour change for the combinations that were handled before.
The [Component] section data (description, documentation, enablement,
suggestion state) so far lived as loose fields directly in the Context
object. Move it into a dedicated Component structure with its own reader
and suggestion check, in preparation for teaching it further settings and
for building it from sources other than .component files.
No behaviour change.