the ISO9660 date range and the "struct tm" range are quite different,
let's add extra paranoia checks that we can always convert the dates
without issues or fail cleanly.
This enables deriving the minimum size of the `Verity=hash` partition
using the `Verity=` logic when the size of the `Verity=data` partition
is bigger than the `CopyBlocks=` target.
This enables using `Minimize=true` for an "installer image" and later
using sd-repart to install to a system with reserve space for future
updates by specifying `Size{Min,Max}Bytes=` only in the `Verity=data`
partition, without needing to hardcode the corresponding size for the
`Verity=hash` partition.
While not strictly necessary for `Verity=signature` partitions (since
they have a fixed size) there isn't too much reason to not support it,
since then you can still specify `VerityMatchKey=` to indicate that the
partition is logically still part of that group of partitions.
---
Alternative to: https://github.com/systemd/systemd/pull/41156
Fixes https://github.com/systemd/systemd/issues/40995
This enables deriving the minimum size of the `Verity=hash` partition
using the `Verity=` logic when the size of the `Verity=data` partition
is bigger than the `CopyBlocks=` target.
This enables using `Minimize=true` for an "installer image" and later
using sd-repart to install to a system with reserve space for future
updates by specifying `Size{Min,Max}Bytes=` only in the `Verity=data`
partition, without needing to hardcode the corresponding size for the
`Verity=hash` partition.
While not strictly necessary for `Verity=signature` partitions (since
they have a fixed size) there isn't too much reason to not support it,
since then you can still specify `VerityMatchKey=` to indicate that
the partition is logically still part of that group of partitions.
We ensure that if one of the hash uses `CopyBlocks=` that the data
partition does so as well. Similarly if the signature partition does it
checks that the hash and data partition do so as well. This is to
minimize the chance of accidental misconfiguration of mixing
`CopyBlocks=auto` and `CopyBlocks=<path>` and of manually populating
partitions while hash/sig partitions are copied from existing sources.
When `Format=empty` is set we need to check for `NoAuto` support for
the partition type, else we print a warning later in the build.
Followup for 381304a
Coverity flags a->after->offset + a->after->current_size as a
potential overflow. Both values are validated as not UINT64_MAX
by existing asserts, add an explicit overflow check to document
the invariant for static analyzers.
CID#1548063
Follow-up for e594a3b154
The restriction requiring --empty= to be require, force, or create
when using --el-torito= is unnecessary.
context_verify_eltorito_overlap() already validates that the ISO 9660
blocks don't collide with GPT partition entries or the first usable
LBA, which is sufficient to guarantee safety regardless of the empty
mode.
This is needed for two-stage image builds where the first stage creates
the usr and verity partitions, and the second stage adds --el-torito=
to produce a bootable ISO with a UKI containing usrhash= derived from
the verity hash of the first stage. In the second stage, repart runs
with --empty=allow since the image already exists.
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
This only points the firmware to the ESP. The ISO9660 is empty.
The initramfs should create a loop device to change block size
and enable GPT partitions.
This was tested using OVMF on qemu, with:
`-drive if=pflash,file=OVMF_CODE.fd,readonly=on,format=raw -drive if=pflash,file=OVMF_VARS.fd,format=raw -drive if=none,id=live-disk,file=dick.iso,media=cdrom,format=raw,readonly=on -device virtio-scsi-pci,id=scsi -device scsi-cd,drive=live-disk`
And a simple definition:
```
[Partition]
Type=esp
Format=vfat
CopyFiles=/usr/lib/systemd/boot/efi/systemd-bootx64.efi:/EFI/BOOT/BOOTX64.EFI
```
I tried to implement a varlink service using sd-varlink, and
not being able to use the approach with sentinel is exteremely
painful. This is useful internally and likewise externally.
AllowDiscards= will set allow-discards in the persistent flags which will make
activating the device automatically activate with that option. This is
useful for devices discovered through gpt-auto-generator without
needing to use some kernel command line to set the option.
The fix in 8f1751a111 made me wonder if we could automatically detect
when pointers are accessed but when this might not be safe. Systemd
is already using a lot of `assert(dst)` and this change now forces
us to use them.
So this commit (ab)uses coccinelle to flag any pointer parameter
dereference not preceded by assert(param), ASSERT_PTR(param), or an
explicit NULL check. It adds integration into meson as a new "coccinelle"
test suite (just like clang-tidy) and is run in CI. The check is not
perfect but seems a reasonable heuristic.
For this RFC commit it is scoped to a subset, it excludes 25 dirs right
now and includes around 100. About 300 warnings left. Busywork that I am
happy to do if there is agreement that it is worth it.
With this in place we would have caught the bug from 8f1751a111 in CI:
```
FAIL: check-pointer-deref.cocci found issues in systemd/src/boot:
diff -u -p systemd/src/boot/measure.c /tmp/nothing/measure.c
--- systemd/src/boot/measure.c
+++ /tmp/nothing/measure.c
@@ -312,7 +312,6 @@ EFI_STATUS tpm_log_tagged_event(
if (err != EFI_SUCCESS)
return err;
- *ret_measured = true;
return EFI_SUCCESS;
}
```
This also adds a new POINTER_MAY_BE_NULL() for the cases when the
called function will do the NULL check (like `iovec_is_set()`).
Add a --grain-size= CLI option to override the default 4 KiB partition
alignment grain. Setting --grain-size=1M matches the alignment used by
fdisk/parted and fixes misaligned partitions after small fixed-size
partitions like the 16 KiB verity-sig partition.
Also fix context_place_partitions() to re-align the start offset after
each partition, not just once per free area. Without this, a small
partition would cause all subsequent partitions in the same free area
to start at an unaligned offset.
Report DiskTooSmall only if partitions managed by repart don't fit the
disk. Because if the disk is already full with forigin partitions we
would always report DiskTooSmall instead of InsufficentFreeSpace.
To decide whether the disk is to small or has insufficient free space we
need to know how much of the disk is filled with foreign partitions.
The calculated size is used in a future commit.
When working on disks the disk may have a total size bigger then the
actual allocated size, therefore sum up the current partitions to
calculate the current disk size instead of asuming that the entire disk
is currently allocated.
The default image policy for the verity sig partition expects
the r/o flag to be set, but repart so far did not add it by
default if unset, like it does for the verity partition
The indirect discard in mkfs.btrfs on the loop device mapped to the
region on disk can hang and fail the first-boot creation of the rootfs.
Since there already is a discard done we anyway don't need to do it
twice. This might help for most cases to avoid the failure in
mkfs.btrfs.
Keep track if the direct discard worked and then skip the mkfs.btrfs
discard if it did. This still leaves the case where mkfs.btrfs can hang
when the direct discard couldn't succeed and mkfs.btrfs tries again but
since the conditions are rather the same it might be that this case is
not easy to trigger. If the problem still shows up and the kernel won't
be fixed soon we can still disable the mkfs discard for at least btrfs.
Commit 15b1c33 ("repart: Generate fstab and crypttab late") moved
fstab/crypttab generation to the late stage but this introduced a regression:
it may be necessary to include fstab and crypttab into the generated partition
(e.g. with CopyFiles=). This is incompatible with 'fixate-volume-key' option as
it is impossible to capture LUKS volume key before it gets created but all the
rest should work fine.
Generate crypttab twice: early and late to capture possible changes. There's no
need to do the same for fstab for now, so keep the status quo.
get_block_device_harder_fd() currently only traverses one level of
device mapper stacking when looking for the underlying block device.
This causes issues with nested DM setups like dm-crypt on top of
dm-integrity, where we don't traverse enough to get the actual physical
device.
Fix this by iterating through all DM layers until we reach a device with
no underlying device. And while we're at it also make cgroups use the
same logic.
Fixes: #40419
This is useful in tools such as system-repart where we show the
definition file paths a lot in our output, but if prefixed with the root
path we'd show a temporary mount dir when operating on a image file.
Hence, let's drop the prefix here, and show only the path within the
image.
Let's make sure we can safely load configuration files based on a root
fd, including XAT_FDROOT.
(While we are at it, always pass path to root fs before fd to root fs,
following our recently updated CODING_STYLE)
Originating device lookups currently use separate entry points and
callers must decide between the single-step helper and manual looping.
Add a recursive flag to block_device_get_originating() and
block_get_originating(), and update callers to pass an explicit value.
The immediate need for the change is to allow to capture the expected
LUKS volume key hash and record it to the generated crypttab but it
also seems to make sense to not generate crypttab/fstab before we know
that partition creation succeeded as fstab/crypttab entries are bogus
otherwise.
Major distributions already have cryptsetup newer than 2.4.0.
Let's bump the minimal required version.
Note, cryptsetup 2.4.0 was released on 2021-08-18.
See also #38608.
So far we compiled the normal and standalone versions completely
independently. Let's use the 'extract' template pattern to avoid any
additional compilation and only require an single link to produce the
.standalone variants.
Unfortunately, as designed, the 'extract' framework only allows one set of
object files to be extracted. Since we need all the files for the
.standalone version, we cannot use 'extract' for other purposes. Thus, in
the two cases where 'extract' was used for the test binaries, this is now
changed to compile the files a second time. But the number of files in that
list is small, so this seems like a better option.
(If we weren't using the template system, we could easily extract just the
objects we need. But with the current system, at the point of the
definition, the binaries are not defined yet. We'd need to handle all of
this through sets of dictionaries, and that just seems like too much
trouble to avoid double compilation of a few small files.)
If we ever want to add it back, it should be with -DSTANDALONE=0|1, so
that #if instead of #ifdef can be used. We generally converted our internal
defines to that form.
Authenticated disk encryption is experimentally supported by cryptsetup since
v2.0.0 and allows for automatic dm-integrity setup for LUKS devices. Add
support for the mode to systemd-repart. Currently, the option can only be used
in 'online' mode as libcryptsetup does not support creating integrity data
without the use of in-kernel dm-integrity infrastructure.
Integrity=/IntegrityAlgorithm= are added in the anticipation of other integrity
protection options, e.g. enabling dm-integrity for a plain unencrypted
partition.