On musl, O_ACCMODE is defined as (03|O_SEARCH), unlike glibc which
defines it as (O_RDONLY|O_WRONLY|O_RDWR). Additionally, O_SEARCH is
simply defined as O_PATH.
This causes problems for systemd on musl, as it changes the
behaviour of open_mkdir_at_full() to return -EINVAL if O_PATH is
included in flags due to the fact that O_ACCMODE includes O_SEARCH
(i.e. O_PATH). Consequently, this makes the test-fs-util test fail.
Upstream musl seems content with this behaviour and doesn't seem
interested in matching glibc's behaviour due to that defining it this
way allows for O_SEARCH to match POSIX better by allowing it to open
directories where read permission is missing. Apparently musl does some
emulation in other places to make this work more consistently as well.
Initially I took the approach of working around this by redefining
O_SEARCH as O_RDONLY if O_SEARCH == O_PATH. This fixes the test and is
the approach taken by both XZ[1] and Gzip[2][3], but was not taken as
redefining system headers potentially could be problematic.
Instead, introduce O_ACCMODE_STRICT which just is a copy of glibc's
O_ACCMODE and use it everywhere. This way we don't have to deal with
unusual definitions of O_ACCMODE from C standard libraries other than
glibc.
[1]: https://git.tukaani.org/?p=xz.git;a=blob;f=src/xz/file_io.c;h=8c83269b13fa31284f7ea5f3627a1dfbce7d6e14;hb=HEAD#l72
[2]: https://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/fcntl.in.h
(lines 380 and 396, commit d7f551b30f3f2a0fa57c1b10c12f4eea41a9b89e)
[3]: https://lists.gnu.org/archive/html/bug-gzip/2025-01/msg00000.html
These variables are assigned with set_put_strv(), hence
string_hash_ops_free is used.
This also drops unnecessary call of set_ensure_allocated() with wrong
hash ops.
The PidRefs are in all cases owned by Unit.pids, and gets removed
from Manager.watch_pids(_more) when the unit is destructed, via
unit_unwatch_pidref(). This hasn't caused any issue because
manager_clear_jobs_and_units() is called before destroying
Manager.watch_pids(_more), but let's get this right.
We might have resolved the tty to something else if it was set to
/dev/console, so let's always go via stdin in setup_pam(). This also
means we won't set the pam tty if only stdout or stderr are connected
to a tty, which seems like a sensible thing to do.
If /dev/console is connected to stdin there's a possibility that
the unit might try to start a logind session from within the unit.
Let's make sure that any such sessions are started on the tty that
/dev/console points to and not on /dev/console itself.
Currently, for units whose CGRuntime is not allocated just yet, e.g.
inactive ones, MemoryAvailable fails to account for their MemoryMax/High
settings. Let's remove the CGRuntime check hence. The call to
unit_get_memory_accounting() would certainly fail, but it doesn't matter,
since 'current' is initially set to 0 anyways.
DDIs may contain multiple versions of the same OS, or even multiple
OSes. Hence it makes sense to not just pick the "newest", whatever that
might be, but only partitions associated with specific images, or in a
specific version.
Let's a concept for such filtering: a per-designator glob expression
that can be applied to the partition label string, and can be used for
such filtering.
Usecase: when picking UKI belonging to OS image X in version Y, make
sure we only pick a /usr/ partition belonging to X in version Y, and a
root and home partition belonging to X in any version.
This only adds the basic infrastructure, but doesn't actually expose it
anywhere.
When dissecting an image, let's make use of the Verity data even if we
got told no root hash explicitly: we can simply determine it by
concatenating the data partition uuid with the verity partition uuid.
Of course, on first thought this doesn't really add much: if the root
hash is not pinned from somewhere, this does not guarantee trust in
the image.
However, this is very useful for attestation: if we have the root hash
we can measure it before mounting things, even if we don't actually
authenticate it.
Hence, at best this helps us with attestation, at worst it doesn't improve
security but certainly doesn't hurt it.
Adjustments to match our current coding style, in particular ensures we
always print log messages for unexpected errors.
This changes our code assume mac_selinux_get_create_label_from_exe()
returns a valid label on success. I checked libselinux, this is
guaranteed, and is otherwise relied on in our tree, hence don't do the
pointless check here.
We'd previously return what was already set. Let's instead return a
clear ENOEXEC in this case, to make clear what is going on: preset logic
doesn't apply to units which lag a fragment path.
"-1" is not a valid enum value. Use a better one. All code using this
considers negative values error codes anyway, hence the old code was
just a weird way to write -EPERM. Let's clean this up.