m: enable dm-verity rootfs
This makes all the existing EFI unified kernel images boot from a
dm-verity rootfs.
Change-Id: Iac05942e40b81825252e84feb5c79c8ff215680a
Reviewed-on: https://review.monogon.dev/c/monogon/+/527
Reviewed-by: Sergiusz Bazanski <serge@monogon.tech>
diff --git a/metropolis/installer/main.go b/metropolis/installer/main.go
index 4e6d6e0..520bc89 100644
--- a/metropolis/installer/main.go
+++ b/metropolis/installer/main.go
@@ -242,7 +242,7 @@
panicf("Cannot open EFI payload in bundle: %v", err)
}
defer efiPayload.Close()
- systemImage, err := bundle.Open("rootfs.img")
+ systemImage, err := bundle.Open("verity_rootfs.img")
if err != nil {
panicf("Cannot open system image in bundle: %v", err)
}
diff --git a/metropolis/installer/test/testos/BUILD b/metropolis/installer/test/testos/BUILD
index b264527..0dcb8cb 100644
--- a/metropolis/installer/test/testos/BUILD
+++ b/metropolis/installer/test/testos/BUILD
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
-load("//metropolis/node/build:def.bzl", "erofs_image")
+load("//metropolis/node/build:def.bzl", "erofs_image", "verity_image")
load("//metropolis/node/build:efi.bzl", "efi_unified_kernel_image")
load("@rules_pkg//:pkg.bzl", "pkg_zip")
@@ -10,10 +10,16 @@
},
)
+verity_image(
+ name = "verity_rootfs",
+ source = ":rootfs",
+)
+
efi_unified_kernel_image(
name = "kernel_efi",
- cmdline = "loglevel=0 console=ttyS0 root=PARTLABEL=METROPOLIS-SYSTEM rootfstype=erofs init=/init",
+ cmdline = "loglevel=0 console=ttyS0 init=/init",
kernel = "//third_party/linux",
+ verity = ":verity_rootfs",
)
# An intermediary "bundle" format until we finalize the actual bundle format. This is NOT stable until migrated
@@ -23,7 +29,7 @@
name = "testos_bundle",
srcs = [
":kernel_efi",
- ":rootfs",
+ ":verity_rootfs",
],
visibility = ["//metropolis/installer/test:__subpackages__"],
)
diff --git a/metropolis/node/BUILD.bazel b/metropolis/node/BUILD.bazel
index f37ed9a..722f05b 100644
--- a/metropolis/node/BUILD.bazel
+++ b/metropolis/node/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
-load("//metropolis/node/build:def.bzl", "erofs_image")
+load("//metropolis/node/build:def.bzl", "erofs_image", "verity_image")
load("//metropolis/node/build:efi.bzl", "efi_unified_kernel_image")
load("@rules_pkg//:pkg.bzl", "pkg_zip")
@@ -92,11 +92,17 @@
},
)
+verity_image(
+ name = "verity_rootfs",
+ source = ":rootfs",
+)
+
efi_unified_kernel_image(
name = "kernel_efi",
- cmdline = "console=ttyS0,115200 console=tty0 quiet root=PARTLABEL=METROPOLIS-SYSTEM rootfstype=erofs init=/init",
+ cmdline = "console=ttyS0,115200 console=tty0 quiet rootfstype=erofs init=/init",
kernel = "//third_party/linux",
os_release = ":os-release-info",
+ verity = ":verity_rootfs",
)
# An intermediary "bundle" format until we finalize the actual bundle format. This is NOT stable until migrated
@@ -106,7 +112,7 @@
name = "node",
srcs = [
":kernel_efi",
- ":rootfs",
+ ":verity_rootfs",
],
visibility = ["//visibility:public"],
)
@@ -115,7 +121,7 @@
name = "image",
srcs = [
":kernel_efi",
- ":rootfs",
+ ":verity_rootfs",
],
outs = [
"node.img",
@@ -123,7 +129,7 @@
cmd = """
$(location //metropolis/node/build/mkimage) \
-efi $(location :kernel_efi) \
- -system $(location :rootfs) \
+ -system $(location :verity_rootfs) \
-out $@
""",
tools = [
diff --git a/metropolis/node/build/efi.bzl b/metropolis/node/build/efi.bzl
index 21b1ef9..12d32db 100644
--- a/metropolis/node/build/efi.bzl
+++ b/metropolis/node/build/efi.bzl
@@ -4,50 +4,56 @@
"""
load("//build/toolchain/llvm-efi:transition.bzl", "build_efi_transition")
+load("//metropolis/node/build:def.bzl", "VerityConfig")
def _efi_unified_kernel_image_impl(ctx):
- out = ctx.actions.declare_file(ctx.attr.name + ".efi")
-
- toolchain_info = ctx.attr._toolchain[platform_common.ToolchainInfo]
-
- sections = [
- dict(name = ".linux", file = ctx.file.kernel, vma = 0x2000000),
- ]
-
- if ctx.attr.cmdline != "":
- cmdline_file = ctx.actions.declare_file("cmdline")
+ # Find the dependency paths to be passed to mkpayload.
+ deps = {
+ "linux": ctx.file.kernel,
+ "initrd": ctx.file.initramfs,
+ "osrel": ctx.file.os_release,
+ "splash": ctx.file.splash,
+ "stub": ctx.file.stub,
+ }
+ # Since cmdline is a string attribute, put it into a file, then append
+ # that file to deps.
+ if ctx.attr.cmdline and ctx.attr.cmdline != "":
+ cmdline = ctx.actions.declare_file("cmdline")
ctx.actions.write(
- output = cmdline_file,
+ output = cmdline,
content = ctx.attr.cmdline,
)
- sections.append(dict(name = ".cmdline", file = cmdline_file, vma = 0x30000))
-
- if ctx.file.initramfs:
- sections += [dict(name = ".initrd", file = ctx.file.initramfs, vma = 0x5000000)]
- if ctx.file.os_release:
- sections += [dict(name = ".osrel", file = ctx.file.os_release, vma = 0x20000)]
- if ctx.file.splash:
- sections += [dict(name = ".splash", file = ctx.file.splash, vma = 0x40000)]
-
+ deps["cmdline"] = cmdline
+ # Get the dm-verity target table from VerityConfig provider.
+ if ctx.attr.verity:
+ deps["rootfs_dm_table"] = ctx.attr.verity[VerityConfig].table
+ # Format deps into command line arguments while keeping track of mkpayload
+ # runtime inputs.
args = []
- for sec in sections:
- args.append("--add-section")
- args.append("{}={}".format(sec["name"], sec["file"].path))
- args.append("--change-section-vma")
- args.append("{}={}".format(sec["name"], sec["vma"]))
-
+ inputs = []
+ for name, file in deps.items():
+ if file:
+ args.append("-{}={}".format(name, file.path))
+ inputs.append(file)
+ # Append the output parameter separately, as it doesn't belong with the
+ # runtime inputs.
+ image = ctx.actions.declare_file(ctx.attr.name + ".efi")
+ args.append("-output={}".format(image.path))
+ # Append the objcopy parameter separately, as it's not of File type, and
+ # it does not constitute an input, since it's part of the toolchain.
+ objcopy = ctx.attr._toolchain[platform_common.ToolchainInfo].objcopy_executable
+ args.append("-objcopy={}".format(objcopy))
+ # Run mkpayload.
ctx.actions.run(
- mnemonic = "GenEFIKernelImage",
- progress_message = "Generating EFI unified kernel image",
- inputs = [ctx.file.stub] + [s["file"] for s in sections],
- outputs = [out],
- executable = toolchain_info.objcopy_executable,
- arguments = args + [
- ctx.file.stub.path,
- out.path,
- ],
+ mnemonic = "GenEFIKernelImage",
+ progress_message = "Generating EFI unified kernel image",
+ inputs = inputs,
+ outputs = [image],
+ executable = ctx.file._mkpayload,
+ arguments = args
)
- return [DefaultInfo(files = depset([out]), runfiles = ctx.runfiles(files = [out]))]
+ # Return the unified kernel image file.
+ return [DefaultInfo(files = depset([image]), runfiles = ctx.runfiles(files = [image]))]
efi_unified_kernel_image = rule(
implementation = _efi_unified_kernel_image_impl,
@@ -82,6 +88,18 @@
executable = True,
cfg = build_efi_transition,
),
+ "verity": attr.label(
+ doc = "The DeviceMapper Verity rootfs target table.",
+ allow_single_file = True,
+ providers = [DefaultInfo, VerityConfig],
+ ),
+ "_mkpayload": attr.label(
+ doc = "The mkpayload executable.",
+ default = "//metropolis/node/build/mkpayload",
+ allow_single_file = True,
+ executable = True,
+ cfg = "exec",
+ ),
"_toolchain": attr.label(
doc = "The toolchain used for objcopy.",
default = "//build/toolchain/llvm-efi:efi_cc_suite",
diff --git a/third_party/linux/linux-metropolis.config b/third_party/linux/linux-metropolis.config
index b18213e..b584a0c 100644
--- a/third_party/linux/linux-metropolis.config
+++ b/third_party/linux/linux-metropolis.config
@@ -1582,7 +1582,7 @@
# CONFIG_DM_MULTIPATH is not set
# CONFIG_DM_DELAY is not set
# CONFIG_DM_DUST is not set
-# CONFIG_DM_INIT is not set
+CONFIG_DM_INIT=y
# CONFIG_DM_UEVENT is not set
# CONFIG_DM_FLAKEY is not set
CONFIG_DM_VERITY=y