diff mbox series

[isar-cip-core,RFC,1/2] wic(ebg): add support to add verity env to cmdline

Message ID 20250214122329.2766449-1-felix.moessbauer@siemens.com (mailing list archive)
State New
Headers show
Series [isar-cip-core,RFC,1/2] wic(ebg): add support to add verity env to cmdline | expand

Commit Message

MOESSBAUER, Felix Feb. 14, 2025, 12:23 p.m. UTC
Passing the verity data via the initrd has proven problematic, as this
requires to rebuild the initrd on each (bitwise) change of the verity
container. For use cases with not bit-by-bit reproducible rootfs this
can lead to verity hash inconsistencies as the bitbake state diverges
from the file state in case some task artifacts are taken from the
SState cache. Further, the build time is prolonged as on every rootfs
change also the initfs needs to be rebuild (also polluting the SState
cache with not-reusable entries).

We now change this by adding the verity data to the kernel cmdline
(similar to how systemd envisions this). The ebg-boot wic plugin
already adds information about the imaged partitions to the kernel
cmdline of the UKI (or config). We now add support to add the verity
environment by setting the source parameter "verity_root=y". The
environment is read from the images *.verity.env file, converted
into the systemd-veritysetup-generator syntax and added to the
command line. As we currently do not use the systemd integration, we
use the parameter "cip.verity_root_options" instead. Later on this
can be replaced by "systemd.verity_root_options".

Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
---
 .../wic/plugins/source/efibootguard-boot.py   | 29 +++++++++++++++++++
 1 file changed, 29 insertions(+)

Comments

MOESSBAUER, Felix Feb. 14, 2025, 12:46 p.m. UTC | #1
On Fri, 2025-02-14 at 13:30 +0100, Jan Kiszka wrote:
> On 14.02.25 13:23, Felix Moessbauer wrote:
> > Passing the verity data via the initrd has proven problematic, as
> > this
> > requires to rebuild the initrd on each (bitwise) change of the
> > verity
> > container. For use cases with not bit-by-bit reproducible rootfs
> > this
> > can lead to verity hash inconsistencies as the bitbake state
> > diverges
> > from the file state in case some task artifacts are taken from the
> > SState cache. Further, the build time is prolonged as on every
> > rootfs
> > change also the initfs needs to be rebuild (also polluting the
> > SState
> > cache with not-reusable entries).
> 
> Then let's fix the reproducibility issues. This change here destroys
> a
> pattern we are also using for abrootfs. I'm not a fan of doing things
> differently only for verify.

I prefer to fix it for A/B rootfs as well (actually I was not aware of
this). Also systemd envisions to not have any hard-coded rootfs data in
the initrd.

As of today, we cannot assume that all downstream layers have a bit-by-
bit reproducible rootfs.

Felix

> 
> Jan
>
diff mbox series

Patch

diff --git a/scripts/lib/wic/plugins/source/efibootguard-boot.py b/scripts/lib/wic/plugins/source/efibootguard-boot.py
index 8b1097f..aa093e2 100644
--- a/scripts/lib/wic/plugins/source/efibootguard-boot.py
+++ b/scripts/lib/wic/plugins/source/efibootguard-boot.py
@@ -87,6 +87,10 @@  class EfibootguardBootPlugin(SourcePlugin):
         boot_files = source_params.get("files", "").split(' ')
         unified_kernel = source_params.get("unified-kernel") or 'y'
         cmdline = bootloader.append or ''
+        # the verity cmdline format is identical to systemd.verity_root_options
+        if source_params.get("verity_root") == 'y':
+            cmdline += " cip.verity_root_options=panic-on-corruption,%s" \
+                % cls._get_verity_opts()
         if unified_kernel == 'y':
             boot_image = cls._create_unified_kernel_image(rootfs_dir,
                                                           cr_workdir,
@@ -143,6 +147,31 @@  class EfibootguardBootPlugin(SourcePlugin):
         cls._create_img(part_rootfs_dir, part, cr_workdir,
                         native_sysroot, oe_builddir)
 
+    @classmethod
+    def _get_verity_opts(cls):
+        verity_sd_keys = ["data-block-size", "hash-block-size", "data-blocks",
+                          "hash-offset", "salt", "uuid", "hash"]
+        opts = {}
+        deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+        verityenv = None
+        for file in os.listdir(deploy_dir):
+            if fnmatch.fnmatch(file, '*.verity.env'):
+                verityenv = os.path.join(deploy_dir, file)
+                break
+        if not verityenv:
+            msger.error("No verity env file found in directory %s", deploy_dir)
+            exit(1)
+        with open(verityenv, "r") as venv:
+            for line in venv:
+                k, v = line.strip().split("=")
+                if k == "ROOT_HASH":
+                    sd_key = "hash"
+                else:
+                    sd_key = k.replace("_", "-").lower()
+                opts[sd_key] = v
+        sd_opts = {k: v for k, v in opts.items() if k in verity_sd_keys}
+        return ",".join(["%s=%s" % (k, v) for k, v in sd_opts.items()])
+
     @classmethod
     def _create_img(cls, part_rootfs_dir, part, cr_workdir,
                     native_sysroot, oe_builddir):