From a0555bbcf0fcafc7fd0f0f60770548fcb26f0cb8 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 25 Feb 2025 10:34:12 +0000 Subject: [PATCH 1/6] mkosi-obs: carry over all raw and efi files, not just those that match IMAGE_ID e.g.: netesp in particleos --- mkosi/resources/mkosi-obs/mkosi.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkosi/resources/mkosi-obs/mkosi.build b/mkosi/resources/mkosi-obs/mkosi.build index dc5ed8917..7f6aa94db 100755 --- a/mkosi/resources/mkosi-obs/mkosi.build +++ b/mkosi/resources/mkosi-obs/mkosi.build @@ -35,7 +35,7 @@ certutil -N -d sql:"$nss_db" --empty-password certutil -A -d sql:"$nss_db" -n cert -t CT,CT,CT -i /usr/src/packages/SOURCES/_projectcert.crt openssl x509 -inform PEM -in /usr/src/packages/SOURCES/_projectcert.crt -outform DER -out _projectcert.cer -cp -r /usr/src/packages/SOURCES/"$IMAGE_ID"* "$OUTPUTDIR" +cp -r /usr/src/packages/SOURCES/"$IMAGE_ID"* /usr/src/packages/SOURCES/*raw* /usr/src/packages/SOURCES/*efi* "$OUTPUTDIR" || true rm -f "$OUTPUTDIR/hashes.cpio.rsasign*" "$OUTPUTDIR"/*.sha* # First step: if there are UKI signatures, attach them From 1ade15f9403d5cabc0f286dd13ea35de7f28b76f Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 25 Feb 2025 11:40:02 +0000 Subject: [PATCH 2/6] mkosi-obs: fix compression detection The recompress variable is not reset in the loop, so if there is a compressed ddi and an uncompressed one, the variable will be true for the second one. Reset it. --- mkosi/resources/mkosi-obs/mkosi.build | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mkosi/resources/mkosi-obs/mkosi.build b/mkosi/resources/mkosi-obs/mkosi.build index 7f6aa94db..447fef12c 100755 --- a/mkosi/resources/mkosi-obs/mkosi.build +++ b/mkosi/resources/mkosi-obs/mkosi.build @@ -67,6 +67,8 @@ while read -r SIG; do unzstd "${DEST%efi}"raw*.zst rm -f "${DEST%efi}"raw*.zst recompress=1 + else + recompress=0 fi offset="$(systemd-repart --json=short "${DEST%efi}"raw* | jq -r '.[] | select(.type == "esp") | .offset')" @@ -198,6 +200,8 @@ while read -r SIG; do recompress=1 unzstd "$OUTPUTDIR/$(basename "${SIG%roothash.sig}")"raw*.zst rm -f "$OUTPUTDIR/$(basename "${SIG%roothash.sig}")"raw*.zst + else + recompress=0 fi ARGS=( @@ -245,10 +249,14 @@ mapfile -t AUTHVARS < <(find hashes/authvars -type f -name "*.auth") if (( ${#AUTHVARS[@]} > 0 )); then for ddi in "$OUTPUTDIR"/*.raw*; do test -f "$ddi" || continue + if [[ $ddi == *.zst ]]; then unzstd "${ddi}" recompress=1 + else + recompress=0 fi + offset="$(systemd-repart --json=short "${ddi%.zst}" | jq -r '.[] | select(.type == "esp") | .offset')" if [ -z "$offset" ] || [ "$offset" = "null" ]; then if [[ $ddi == *.zst ]]; then From 947d090466fb7a6309fd35ed31e1e5d456075723 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 25 Feb 2025 11:42:31 +0000 Subject: [PATCH 3/6] mkosi-obs: drop leftover debug env --- mkosi/resources/mkosi-obs/mkosi.postoutput | 1 - 1 file changed, 1 deletion(-) diff --git a/mkosi/resources/mkosi-obs/mkosi.postoutput b/mkosi/resources/mkosi-obs/mkosi.postoutput index 4d80d0cd5..6ddf8a21b 100755 --- a/mkosi/resources/mkosi-obs/mkosi.postoutput +++ b/mkosi/resources/mkosi-obs/mkosi.postoutput @@ -102,7 +102,6 @@ if ((${#DDIS[@]} > 0)); then cert-to-efi-sig-list -g "$guid" /usr/src/packages/SOURCES/_projectcert.crt db.esl cp db.esl KEK.esl cp db.esl PK.esl - env for i in *.esl; do sign-efi-sig-list -o -g "$guid" -t "${SOURCE_DATE_EPOCH:-$(date +%s)}" "${i%.esl}" "$i" "${i%.esl}.auth" done From 36a10172a2991a628a149c23ec07d91c18df9130 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 25 Feb 2025 14:04:22 +0000 Subject: [PATCH 4/6] mkosi-obs: rearrange second stage so that only unsigned hashes are staged for third Create cpio for next stage at the very end, after all signed hashes have been handled and removed, to avoid resigning already signed files --- mkosi/resources/mkosi-obs/mkosi.build | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/mkosi/resources/mkosi-obs/mkosi.build b/mkosi/resources/mkosi-obs/mkosi.build index 447fef12c..b4e71d759 100755 --- a/mkosi/resources/mkosi-obs/mkosi.build +++ b/mkosi/resources/mkosi-obs/mkosi.build @@ -90,7 +90,7 @@ while read -r SIG; do done < <(find hashes/ukis hashes/kernels -type f \( -name '*efi.sig' -o -name 'vmlinu*.sig' \) -printf '%P\n') rm -rf "$OUTPUTDIR"/*.sig hashes/ukis -# If there are signed bootloaders, install them in the ESP +# Second step: if there are signed bootloaders, install them in the ESP while read -r BOOTLOADER; do unsigned="$(basename "${BOOTLOADER%.sig}")" signed="$(basename "${BOOTLOADER%.sig}".signed)" @@ -135,7 +135,7 @@ done < <(find "hashes/bootloaders/$(basename "$ddi")/" -type f -iname '*.efi.sig rm -rf hashes/bootloaders rm -rf nss-db -# Second step: if there are PCR policy signatures, rebuild the JSON +# Third step: if there are PCR policy signatures, rebuild the JSON # blobs with the attached signatures while read -r SIG; do uki="$OUTPUTDIR/$(basename "$(dirname "${SIG%.sig}")")" @@ -165,7 +165,7 @@ rm -rf hashes/pcrs mkdir -p "$nss_db" certutil -N -d sql:"$nss_db" --empty-password -# Third step: now that the JSON blob is rebuilt, merge it in the UKI +# Fourth step: now that the JSON blob is rebuilt, merge it in the UKI while read -r PCRS; do uki="${PCRS%.pcrs.sig}.efi" ukify --json=short --pcrsig "@$PCRS" --join-pcrsig "$uki" --output "$uki.attached" build @@ -175,17 +175,6 @@ while read -r PCRS; do done < <(find "$OUTPUTDIR" -type f -name '*.pcrs.sig') rm -f "$OUTPUTDIR"/*.pcrs* -# Fourth step: take hash of the UKIs after the signed JSON blobs have been merged -# and prepare for the next iteration -if [ -d hashes/ukis ]; then - pushd hashes - find . -type f | cpio -H newc -o >"$OUTPUTDIR/hashes.cpio.rsasign" - popd - cp /usr/src/packages/SOURCES/mkosi.conf "$OUTPUTDIR" - echo "Staging the following files for signing:" - cpio -t <"$OUTPUTDIR/hashes.cpio.rsasign" -fi - # Fifth step: finalize any DDI by attaching the verity roothash signatures while read -r SIG; do test -f "/usr/src/packages/SOURCES/$(basename "${SIG%roothash.sig}repart.tar")" || continue @@ -279,4 +268,15 @@ if (( ${#AUTHVARS[@]} > 0 )); then fi rm -rf hashes/authvars +# Final step: if there are any hashes staged, prepare for the next stage +rmdir --ignore-fail-on-non-empty hashes +if [ -d hashes ]; then + pushd hashes + find . -type f | cpio -H newc -o >"$OUTPUTDIR/hashes.cpio.rsasign" + popd + cp /usr/src/packages/SOURCES/mkosi.conf "$OUTPUTDIR" + echo "Staging the following files for signing:" + cpio -t <"$OUTPUTDIR/hashes.cpio.rsasign" +fi + rm -rf hashes "$nss_db" From 3009f5ed3429c9bfeca25ba6ebcd541bf096cc7a Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 25 Feb 2025 14:05:33 +0000 Subject: [PATCH 5/6] mkosi-obs: support multiple mkosi.postoutput invocations When multiple images are built mkosi.postoutput runs once per image, so add access to output directory and ensure the hashes.cpio.rsasign archive accumulates the hashes for all images before proceeding to the next stage --- mkosi/resources/mkosi-obs/mkosi.conf | 1 + mkosi/resources/mkosi-obs/mkosi.postoutput | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/mkosi/resources/mkosi-obs/mkosi.conf b/mkosi/resources/mkosi-obs/mkosi.conf index 378383f21..d44afb8af 100644 --- a/mkosi/resources/mkosi-obs/mkosi.conf +++ b/mkosi/resources/mkosi-obs/mkosi.conf @@ -1,6 +1,7 @@ # SPDX-License-Identifier: LGPL-2.1-or-later [Build] SandboxTrees=/usr/src/packages/SOURCES:/usr/src/packages/SOURCES +BuildSources=/usr/src/packages/OTHER:/usr/src/packages/OTHER ToolsTree= History=no CacheDirectory= diff --git a/mkosi/resources/mkosi-obs/mkosi.postoutput b/mkosi/resources/mkosi-obs/mkosi.postoutput index 6ddf8a21b..1857c8273 100755 --- a/mkosi/resources/mkosi-obs/mkosi.postoutput +++ b/mkosi/resources/mkosi-obs/mkosi.postoutput @@ -29,6 +29,14 @@ rm -rf "$nss_db" mkdir -p "$nss_db" hashes certutil -N -d sql:"$nss_db" --empty-password +# When a single build has multiple images, postoutput is called for each image, +# so make sure the hashes.cpio from the previous stages gets its content preserved +if [ -f /usr/src/packages/OTHER/hashes.cpio.rsasign ]; then + pushd hashes + cpio -idm Date: Tue, 25 Feb 2025 14:10:31 +0000 Subject: [PATCH 6/6] mkosi-obs: rearrange settings into a subfile that is only for Profile=main These cannot be used with subimages, so move them down one level --- mkosi/resources/mkosi-obs/mkosi.conf | 14 +----------- .../mkosi-obs/mkosi.conf.d/main.conf | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 mkosi/resources/mkosi-obs/mkosi.conf.d/main.conf diff --git a/mkosi/resources/mkosi-obs/mkosi.conf b/mkosi/resources/mkosi-obs/mkosi.conf index d44afb8af..0c278578a 100644 --- a/mkosi/resources/mkosi-obs/mkosi.conf +++ b/mkosi/resources/mkosi-obs/mkosi.conf @@ -1,25 +1,13 @@ # SPDX-License-Identifier: LGPL-2.1-or-later [Build] -SandboxTrees=/usr/src/packages/SOURCES:/usr/src/packages/SOURCES -BuildSources=/usr/src/packages/OTHER:/usr/src/packages/OTHER -ToolsTree= History=no -CacheDirectory= -Incremental=no -WithNetwork=never - -[Distribution] -RepositoryKeyCheck=no -LocalMirror=file:///.build.binaries/ [Output] -OutputDirectory= -Checksum=yes SplitArtifacts=pcrs,roothash,os-release CompressOutput=zstd [Validation] -SignExpectedPcrCertificate=/usr/src/packages/SOURCES/_projectcert.crt SecureBoot=no SignExpectedPcr=no Verity=defer +Checksum=yes diff --git a/mkosi/resources/mkosi-obs/mkosi.conf.d/main.conf b/mkosi/resources/mkosi-obs/mkosi.conf.d/main.conf new file mode 100644 index 000000000..9be3c88dd --- /dev/null +++ b/mkosi/resources/mkosi-obs/mkosi.conf.d/main.conf @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +[Match] +Image=main + +[Build] +SandboxTrees=/usr/src/packages/SOURCES:/usr/src/packages/SOURCES +BuildSources=/usr/src/packages/OTHER:/usr/src/packages/OTHER +ToolsTree= +CacheDirectory= +Incremental=no +WithNetwork=never + +[Distribution] +RepositoryKeyCheck=no +LocalMirror=file:///.build.binaries/ + +[Output] +OutputDirectory= + +[Validation] +SignExpectedPcrCertificate=/usr/src/packages/SOURCES/_projectcert.crt