Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions acl/docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ ACL's primary boot path uses **systemd-boot** with **Unified Kernel Images (UKI)
The `/usr` partition (USR-A) is a read-only btrfs filesystem with zstd compression. **dm-verity** provides block-level integrity verification:

- The verity hash tree is stored in a dedicated hash partition (HASH-A, immediately following USR-A on disk).
- A separate, currently-unused 1 MiB partition (HASH-SIG-A) immediately follows HASH-A, reserved for a future verity root-hash signature.
- At boot, `systemd-veritysetup` activates the verity device using slot-specific parameters delivered via a per-slot systemd-stub addon: `systemd.verity_usr_data=PARTUUID=<usr-data-partition>`, `systemd.verity_usr_hash=PARTUUID=<usr-hash-partition>`, and `systemd.verity_usr_options=panic-on-corruption`.
- The main UKI cmdline stays slot-independent (`mount.usr=/dev/mapper/usr`); Trident switches slots by swapping which addon is active in `<uki>.efi.extra.d/`, so the same signed UKI boots either A or B. (The secondary GRUB boot path is out of scope for A/B update and is unchanged: it still uses the inline PARTUUID + hash-offset verity cmdline on the existing non-UKI partition layout.)
- Any corruption of `/usr` causes an immediate kernel panic, preventing the system from running a tampered image.
Expand Down
9 changes: 7 additions & 2 deletions acl/docs/containerd-image-preload.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,15 @@ actually recovers the store.
### Inspect the output image without booting

```sh
sudo modprobe nbd max_part=8
sudo modprobe nbd max_part=9
sudo qemu-nbd --connect=/dev/nbd0 --read-only -f vpc staging/out/acl-preloaded.vhd
sudo mkdir -p /mnt/verify
sudo mount -o ro /dev/nbd0p7 /mnt/verify # ROOT is the seventh partition

# Select ROOT by GPT partition label rather than a hard-coded index -- the
# partition number varies by layout (e.g. ROOT is p7 on the pre-usr-verity-sig
# layout, p9 once hash-sig-a/hash-sig-b are present).
ROOT_PART=$(sudo blkid -t PARTLABEL="ROOT" -o device /dev/nbd0p* | head -n1)
sudo mount -o ro "${ROOT_PART}" /mnt/verify

ls -la /mnt/verify/var/lib/containerd
strings /mnt/verify/var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db \
Expand Down
42 changes: 33 additions & 9 deletions build_library/disk_layout_uki.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,44 @@
]
},
"3": {
"_comment": "9 MiB verity hash tree for USR-A (1 GiB). Assumes sha256 + 4096-byte data/hash blocks (dm-verity default): tree size is ~8.08 MiB (2048 level-0 hash blocks + 17 upper-level blocks + superblock), so 9 MiB leaves headroom for growth. Recompute if USR-A size or verity hash/block params change.",
"label": "HASH-A",
"uuid": "b736baf1-cdb4-4535-beba-ddaaa30ad7b7",
"type": "dps-usr-verity",
"blocks": "20480"
"blocks": "18432"
},
"4": {
"_comment": "1 MiB reserved for a future USR-A verity root-hash signature. blocks/part_alignment are 512-byte sectors (see metadata.block_size); part_alignment is overridden to 2048 sectors (1 MiB, vs. the file-wide 4096-sector/2 MiB default) so this partition packs directly after HASH-A with no gap, while the combined 10 MiB HASH-A+HASH-SIG-A still lands on the 2 MiB boundary required by USR-B.",
"label": "HASH-SIG-A",
"uuid": "3514648f-e3da-44ae-89ba-8d0552418f88",
"type": "dps-usr-verity-sig",
"part_alignment": "2048",
"blocks": "2048"
},
"5": {
"label": "USR-B",
"uuid": "e03dd35c-7c2d-4a47-b3fe-27f15780a57c",
"type": "flatcar-rootfs",
"blocks": "2097152",
"fs_blocks": "262144",
"verity_hash": "5"
"verity_hash": "6"
},
"5": {
"6": {
"_comment": "9 MiB verity hash tree for USR-B. See HASH-A comment for sizing rationale.",
"label": "HASH-B",
"uuid": "35bdf78b-c453-4661-98e6-f834f534ef5b",
"type": "dps-usr-verity",
"blocks": "20480"
"blocks": "18432"
},
"6": {
"7": {
"_comment": "1 MiB reserved for a future USR-B verity root-hash signature. See HASH-SIG-A comment for units and part_alignment rationale.",
"label": "HASH-SIG-B",
"uuid": "d8941eb2-f713-4bb6-b4ae-bd8350ca27d4",
"type": "dps-usr-verity-sig",
"part_alignment": "2048",
"blocks": "2048"
},
"8": {
"label": "OEM",
"fs_label": "OEM",
"type": "data",
Expand All @@ -63,7 +81,7 @@
"fs_compression": "zlib",
"mount": "/oem"
},
"7": {
"9": {
Comment thread
bfjelds marked this conversation as resolved.
"label": "ROOT",
"fs_label": "ROOT",
"type": "dps-root",
Expand All @@ -73,21 +91,21 @@
}
},
"vm": {
"7": {
"9": {
"label": "ROOT",
"fs_label": "ROOT",
"blocks": "12943360"
}
},
"azure": {
"7": {
"9": {
"label": "ROOT",
"fs_label": "ROOT",
"blocks": "58875904"
}
},
"vagrant": {
"7": {
"9": {
"label": "ROOT",
"fs_label": "ROOT",
"blocks": "33845248"
Expand All @@ -113,6 +131,12 @@
"type": "blank"
},
"7": {
"type": "blank"
},
"8": {
"type": "blank"
},
"9": {
"label": "ROOT",
"fs_label": "ROOT",
"type": "0fc63daf-8483-4772-8e79-3d69d8477de4",
Expand Down
11 changes: 9 additions & 2 deletions build_library/disk_util
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ DPS_USR_VERITY_GUIDS = {
'aarch64': '6E11A4E7-FBCA-4DED-B9E9-E1A512BB664E',
}

DPS_USR_VERITY_SIG_GUIDS = {
'x86_64': 'E7BB33FB-06CF-4E81-8273-E543B413E2E2',
'aarch64': 'C23CE4FF-44BD-4B00-B2D4-B41B3419E02A',
}

# Map BOARD names used by the build system to machine architecture values.
BOARD_TO_ARCH = {
'amd64-usr': 'x86_64',
Expand All @@ -49,12 +54,14 @@ def _resolve_dps_types(config, arch):
"""Replace symbolic DPS partition type names with architecture-specific GUIDs.

Currently supported placeholders:
dps-root → DPS root partition GUID for the target architecture
dps-usr-verity → DPS /usr verity hash partition GUID
dps-root → DPS root partition GUID for the target architecture
dps-usr-verity → DPS /usr verity hash partition GUID
dps-usr-verity-sig → DPS /usr verity signature partition GUID
"""
dps_map = {
'dps-root': DPS_ROOT_GUIDS,
'dps-usr-verity': DPS_USR_VERITY_GUIDS,
'dps-usr-verity-sig': DPS_USR_VERITY_SIG_GUIDS,
}
for layout in config.get('layouts', {}).values():
for part in layout.values():
Expand Down
Loading