systemd-boot expects being loaded from ESP and is quite unhappy in case
the loaded image device path is something else. When running on qemu
this can easily happen though. Case one is direct kernel boot, i.e.
loading via 'qemu -kernel systemd-bootx64.efi'. Case two is sd-boot
being added to the ovmf firmware image and being loaded from there.
This patch detects both cases and goes inspect all file systems known to
the firmware, trying to find the ESP. When present the
VMMBootOrderNNNN variables are used to inspect the file systems in the
given order.
* Fix reading /etc/machine-id in kernel-install
The kernel-install script has code to read the contents of
/etc/machine-id into the MACHINE_ID variable. Depending
on the variable content kernel-install either logs the
value or creates a new machine id via 'systemd-id128 new'.
In that logic there is one issue. If the file /etc/machine-id
exists but is empty, the script tries to call read on an
empty file which return with an exit code != 0. As the
script code also uses 'set -e', kernel-install will exit at
this point which is unexpected.
The condition of an empty /etc/machine-id file exists for
example when building OS images, which should initialize the
system id on first boot but not staticly inside of the image.
afaik an empty /etc/machine-id is also a common approach
to make systemd indicate that it should create a new system
id. Because of this, the commit makes sure the reading of
/etc/machine-id does not fail in any case such that the
handling of the MACHINE_ID variable takes place.
Let's add some extra validation before constructing and using the .so
name to load. This isn't really security sensitive, given that we
used secure_getenv() to get the device string (and it thus should have
been come from a trusted source) but let's better be safe than sorry.
Apparently some distros default to tss-abmrd. Let's bypass that and
always go to the kernel resource manager.
abmrd cannot really work for us, since we want to access the TPM already
in earliest boot i.e. in environments the abmrd service is not available
in.
Fixes: #25352
When repart is not operating on a block device, if we avoid using
any loop devices at all, it becomes possible to run repart without
needing root privileges.
Note that this also depends on the filesystems in use to support
population without needing root privileges (specifically, squashfs,
ext4 or btrfs).
By forking off a user namespace before running mkfs and ID mapping
the user running repart to root in the user namespace, we can make
sure that files in the generated filesystems are all owned by root
instead of the user running repart.
To make this work we have to make sure that all the files in the
root directory that's passed to the mkfs binary are owned by the
user running repart, so we have to drop the shortcut for only a
single root directory in partition_populate_directory().
Offline encryption can be done without mounting the luks device. For
now we still use loop devices to split out the partition we want to
write to but in a later commit we'll replace this with a regular file.
For offline encryption, we need to keep 2x the luks header size space
free at the end of the partition, so this means our encrypted partitions
will be 16M larger than before.
mkfs.vfat doesn't support specifying a root directory to bootstrap
the filesystem from (see https://github.com/dosfstools/dosfstools/issues/183).
Instead, we can use the mcopy tool from the mtools package to copy
files into the vfat filesystem after creating it without needing to
mount the vfat filesystem.