From e44b946abf73ec2a6556f42795526f6fa64a8f11 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Mon, 25 Nov 2024 17:53:23 +0000 Subject: [PATCH 1/5] build_image: Deduplicate --extract_update and --generate_update options The --extract_update option used to do exactly that, just extract the USR-A partition for updates and no more. Now it does the same thing as --generate_update, except it names the file flatcar_test_update.gz rather than flatcar_production_update.gz. --generate_update is never actually used because official update payloads are manually generated with the generate_payload script later on. Resolve this confusion by deduplicating the common code between them. Any update payload produced during this stage of the build is only useful for testing, so change --generate_update to always create flatcar_test_update.gz. --generate_update now implies --extract_update and both are enabled by default. Signed-off-by: James Le Cuirot --- build_image | 22 +++++++------ build_library/build_image_util.sh | 54 ++++++++++++------------------- 2 files changed, 33 insertions(+), 43 deletions(-) diff --git a/build_image b/build_image index a1356b03f0..a9e6bcdaf8 100755 --- a/build_image +++ b/build_image @@ -41,10 +41,10 @@ DEFINE_string disk_layout "" \ "The disk layout type to use for this image." DEFINE_string group "${DEFAULT_GROUP}" \ "The update group." -DEFINE_boolean generate_update "${FLAGS_FALSE}" \ - "Generate update payload. (prod only)" DEFINE_boolean extract_update "${FLAGS_TRUE}" \ - "Extract the /usr partition for generating updates." + "Extract the /usr partition for generating updates. Only valid for the prod image." +DEFINE_boolean generate_update "${FLAGS_TRUE}" \ + "Generate update payload for testing. The update is signed with a dev key. The kernel is signed with a dev key (unofficial builds) or not at all (official builds). Only valid for the prod image. Implies --extract_update." DEFINE_string developer_data "" \ "Insert a custom cloudinit file into the image." DEFINE_string devcontainer_binhost "${DEFAULT_DEVCONTAINER_BINHOST}" \ @@ -139,6 +139,11 @@ fi # Create the output directory and temporary mount points. mkdir -p "${BUILD_DIR}" +# --generate_update implies --extract_update. +if [[ ${FLAGS_generate_update} -eq ${FLAGS_TRUE} ]]; then + FLAGS_extract_update=${FLAGS_TRUE} +fi + DISK_LAYOUT="${FLAGS_disk_layout:-base}" CONTAINER_LAYOUT="${FLAGS_disk_layout:-container}" @@ -169,11 +174,12 @@ fi if [[ "${PROD_IMAGE}" -eq 1 ]]; then IMAGE_BUILD_TYPE="prod" create_prod_image ${FLATCAR_PRODUCTION_IMAGE_NAME} ${DISK_LAYOUT} ${FLAGS_group} ${FLAGS_base_pkg} ${FLAGS_base_sysexts} - if [[ ${FLAGS_generate_update} -eq ${FLAGS_TRUE} ]]; then - generate_update "${FLATCAR_PRODUCTION_IMAGE_NAME}" ${DISK_LAYOUT} - elif [[ ${FLAGS_extract_update} -eq ${FLAGS_TRUE} ]]; then + if [[ ${FLAGS_extract_update} -eq ${FLAGS_TRUE} ]]; then extract_update "${FLATCAR_PRODUCTION_IMAGE_NAME}" "${DISK_LAYOUT}" fi + if [[ ${FLAGS_generate_update} -eq ${FLAGS_TRUE} ]]; then + generate_update "${FLATCAR_PRODUCTION_IMAGE_NAME}" "${DISK_LAYOUT}" + fi if [[ "${PROD_TAR}" -eq 1 ]]; then create_prod_tar ${FLATCAR_PRODUCTION_IMAGE_NAME} fi @@ -182,9 +188,7 @@ if [[ "${SYSEXT}" -eq 1 ]]; then create_prod_sysexts "${FLATCAR_PRODUCTION_IMAGE_NAME}" fi -if [[ ${FLAGS_generate_update} -eq ${FLAGS_TRUE} ]] || \ - [[ ${FLAGS_extract_update} -eq ${FLAGS_TRUE} ]] -then +if [[ ${FLAGS_extract_update} -eq ${FLAGS_TRUE} ]]; then zip_update_tools fi diff --git a/build_library/build_image_util.sh b/build_library/build_image_util.sh index a29470dc82..87f74bc7b4 100755 --- a/build_library/build_image_util.sh +++ b/build_library/build_image_util.sh @@ -61,23 +61,32 @@ delete_prompt() { extract_update() { local image_name="$1" local disk_layout="$2" - local update_path="${BUILD_DIR}/${image_name%_image.bin}_update.bin" + local update="${BUILD_DIR}/${image_name%_image.bin}_update.bin" "${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${disk_layout}" \ - extract "${BUILD_DIR}/${image_name}" "USR-A" "${update_path}" + extract "${BUILD_DIR}/${image_name}" "USR-A" "${update}" # Compress image - files_to_evaluate+=( "${update_path}" ) + files_to_evaluate+=( "${update}" ) compress_disk_images files_to_evaluate +} - # For production as well as dev builds we generate a dev-key-signed update - # payload for running tests (the signature won't be accepted by production systems). - local update_test="${BUILD_DIR}/flatcar_test_update.gz" +generate_update() { + local image_name="$1" + local disk_layout="$2" + local image_kernel="${BUILD_DIR}/${image_name%.bin}.vmlinuz" + local update="${BUILD_DIR}/${image_name%_image.bin}_update.bin" + local devkey="/usr/share/update_engine/update-payload-key.key.pem" + + # Extract the partition if it isn't extracted already. + [[ -s ${update} ]] || extract_update "${image_name}" "${disk_layout}" + + echo "Generating update payload, signed with a dev key" delta_generator \ - -private_key "/usr/share/update_engine/update-payload-key.key.pem" \ - -new_image "${update_path}" \ - -new_kernel "${BUILD_DIR}/${image_name%.bin}.vmlinuz" \ - -out_file "${update_test}" + -private_key "${devkey}" \ + -new_image "${update}" \ + -new_kernel "${image_kernel}" \ + -out_file "${BUILD_DIR}/flatcar_test_update.gz" } zip_update_tools() { @@ -86,34 +95,11 @@ zip_update_tools() { info "Generating update tools zip" # Make sure some vars this script needs are exported - export REPO_MANIFESTS_DIR SCRIPTS_DIR + local -x REPO_MANIFESTS_DIR SCRIPTS_DIR "${BUILD_LIBRARY_DIR}/generate_au_zip.py" \ --arch "$(get_sdk_arch)" --output-dir "${BUILD_DIR}" --zip-name "${update_zip}" } -generate_update() { - local image_name="$1" - local disk_layout="$2" - local image_kernel="${BUILD_DIR}/${image_name%.bin}.vmlinuz" - local update_prefix="${image_name%_image.bin}_update" - local update="${BUILD_DIR}/${update_prefix}" - local devkey="/usr/share/update_engine/update-payload-key.key.pem" - - echo "Generating update payload, signed with a dev key" - "${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${disk_layout}" \ - extract "${BUILD_DIR}/${image_name}" "USR-A" "${update}.bin" - delta_generator \ - -private_key "${devkey}" \ - -new_image "${update}.bin" \ - -new_kernel "${image_kernel}" \ - -out_file "${update}.gz" - - # Compress image - declare -a files_to_evaluate - files_to_evaluate+=( "${update}.bin" ) - compress_disk_images files_to_evaluate -} - # ldconfig cannot generate caches for non-native arches. # Use qemu & the native ldconfig to work around that. # http://code.google.com/p/chromium/issues/detail?id=378377 From 0fd811f4531545cd300fb1748a04fec648c3c0d5 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Wed, 27 Nov 2024 17:17:38 +0000 Subject: [PATCH 2/5] Drop more unused "modify_image" code Signed-off-by: James Le Cuirot --- build_library/modify_image_util.sh | 100 ----------------------------- image_inject_bootchain | 99 ---------------------------- image_set_group | 64 ------------------ 3 files changed, 263 deletions(-) delete mode 100755 build_library/modify_image_util.sh delete mode 100755 image_inject_bootchain delete mode 100755 image_set_group diff --git a/build_library/modify_image_util.sh b/build_library/modify_image_util.sh deleted file mode 100755 index 9099b02e10..0000000000 --- a/build_library/modify_image_util.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2014 The CoreOS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Shell library for modifying an image built with build_image. - -start_modify_image() { - # Default to the most recent image - if [[ -z "${FLAGS_from}" ]] ; then - FLAGS_from="$(${SCRIPT_ROOT}/get_latest_image.sh --board=${FLAGS_board})" - else - FLAGS_from="$(readlink -f "${FLAGS_from}")" - fi - - local src_image="${FLAGS_from}/${FLATCAR_PRODUCTION_IMAGE_NAME}" - if [[ ! -f "${src_image}" ]]; then - die_notrace "Source image does not exist: ${src_image}" - fi - - # Source should include version.txt, switch to its version information - if [[ ! -f "${FLAGS_from}/version.txt" ]]; then - die_notrace "Source version info does not exist: ${FLAGS_from}/version.txt" - fi - source "${FLAGS_from}/version.txt" - FLATCAR_VERSION_STRING="${FLATCAR_VERSION}" - - # Load after version.txt to set the correct output paths - . "${BUILD_LIBRARY_DIR}/toolchain_util.sh" - . "${BUILD_LIBRARY_DIR}/board_options.sh" - . "${BUILD_LIBRARY_DIR}/build_image_util.sh" - - # Handle existing directory. - if [[ -e "${BUILD_DIR}" ]]; then - if [[ ${FLAGS_replace} -eq ${FLAGS_TRUE} ]]; then - sudo rm -rf "${BUILD_DIR}" - else - error "Directory ${BUILD_DIR} already exists." - error "Use --build_attempt option to specify an unused attempt." - error "Or use --replace if you want to overwrite this directory." - die "Unwilling to overwrite ${BUILD_DIR}." - fi - fi - - # Create the output directory and temporary mount points. - DST_IMAGE="${BUILD_DIR}/${FLATCAR_PRODUCTION_IMAGE_NAME}" - ROOT_FS_DIR="${BUILD_DIR}/rootfs" - mkdir -p "${ROOT_FS_DIR}" - - info "Copying from ${FLAGS_from}" - cp "${src_image}" "${DST_IMAGE}" - - # Copy all extra useful things, these do not need to be modified. - local update_prefix="${FLATCAR_PRODUCTION_IMAGE_NAME%_image.bin}_update" - local production_prefix="${FLATCAR_PRODUCTION_IMAGE_NAME%.bin}" - local container_prefix="${FLATCAR_DEVELOPER_CONTAINER_NAME%.bin}" - local pcr_data="${FLATCAR_PRODUCTION_IMAGE_NAME%.bin}_pcr_policy.zip" - EXTRA_FILES=( - "version.txt" - "${update_prefix}.bin" - "${update_prefix}.zip" - "${pcr_data}" - "${production_prefix}_contents.txt" - "${production_prefix}_packages.txt" - "${production_prefix}_kernel_config.txt" - "${FLATCAR_DEVELOPER_CONTAINER_NAME}" - "${container_prefix}_contents.txt" - "${container_prefix}_packages.txt" - ) - for filename in "${EXTRA_FILES[@]}"; do - if [[ -e "${FLAGS_from}/${filename}" ]]; then - cp "${FLAGS_from}/${filename}" "${BUILD_DIR}/${filename}" - fi - done - - "${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${FLAGS_disk_layout}" \ - mount "${DST_IMAGE}" "${ROOT_FS_DIR}" - trap "cleanup_mounts '${ROOT_FS_DIR}'" EXIT -} - -finish_modify_image() { - cleanup_mounts "${ROOT_FS_DIR}" - trap - EXIT - - - declare -a files_to_evaluate - files_to_evaluate+=( "${DST_IMAGE}" ) - compress_disk_images files_to_evaluate - - set_build_symlinks "${FLAGS_group}-latest" - - info "Done. Updated image is in ${BUILD_DIR}" - cat << EOF -To convert it to a virtual machine image, use: - ./image_to_vm.sh --from=${OUTSIDE_OUTPUT_DIR} --board=${BOARD} - -The default type is qemu, see ./image_to_vm.sh --help for other options. -EOF -} diff --git a/image_inject_bootchain b/image_inject_bootchain deleted file mode 100755 index 45f115aba3..0000000000 --- a/image_inject_bootchain +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2014 The CoreOS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -SCRIPT_ROOT=$(dirname "$(readlink -f "$0")") -. "${SCRIPT_ROOT}/common.sh" || exit 1 - -# Script must run inside the chroot -assert_inside_chroot - -assert_not_root_user - -DEFAULT_GROUP=developer - -# Flags -DEFINE_string kernel_path "" \ - "Path to the kernel to inject." -DEFINE_string efi_grub_path "" \ - "Path to the EFI GRUB image to inject." -DEFINE_string shim_path "" \ - "Path to the shim image to inject." -DEFINE_string group "${DEFAULT_GROUP}" \ - "The update group." -DEFINE_string board "${DEFAULT_BOARD}" \ - "Board for which the image was built" -DEFINE_string disk_layout "base" \ - "The disk layout type to use for this image." -DEFINE_string from "" \ - "Directory containing ${FLATCAR_PRODUCTION_IMAGE_NAME}" -DEFINE_string output_root "${DEFAULT_BUILD_ROOT}/images" \ - "Directory in which to place image result directories (named by version)" -DEFINE_boolean replace ${FLAGS_FALSE} \ - "Overwrite existing output, if any." - -# include upload options -. "${BUILD_LIBRARY_DIR}/release_util.sh" || exit 1 - -show_help_if_requested "$@" - -# Usually unneeded, so just leave this option hidden. -DEFINE_integer build_attempt 1 \ - "The build attempt for this image build." - -# Parse command line -FLAGS "$@" || exit 1 -eval set -- "${FLAGS_ARGV}" - -# Die on any errors. -switch_to_strict_mode - -if [[ -z "${FLAGS_kernel_path}" && -z "${FLAGS_efi_grub_path}" && - -z "${FLAGS_shim_path}" ]]; then - die_notrace "Specify at least one of --kernel_path, --efi_grub_path, --shim_path" -fi - -. "${BUILD_LIBRARY_DIR}/modify_image_util.sh" - -do_copy() { - local src="$1" - local dst="$2" - - if [[ ! -f "${ROOT_FS_DIR}/${dst}" ]]; then - # We should only be overwriting existing files. - die "${dst} doesn't exist in image; refusing to create it" - fi - info "Replacing ${dst}" - sudo cp "${src}" "${ROOT_FS_DIR}/${dst}" -} - -start_modify_image - -if [[ -n "${FLAGS_kernel_path}" ]]; then - do_copy "${FLAGS_kernel_path}" "/boot/flatcar/vmlinuz-a" -fi - -# FIXME(bgilbert): no shim on arm64 -if [[ -n "${FLAGS_efi_grub_path}" ]]; then - case "${BOARD}" in - amd64-usr) image_name="grub.efi" ;; - arm64-usr) image_name="bootaa64.efi" ;; - *) die "GRUB filename not known for this board" ;; - esac - - do_copy "${FLAGS_efi_grub_path}" "/boot/EFI/boot/${image_name}" -fi - -if [[ -n "${FLAGS_shim_path}" ]]; then - case "${BOARD}" in - amd64-usr) image_name="bootx64.efi" ;; - *) die "Shim filename not known for this board" ;; - esac - - do_copy "${FLAGS_shim_path}" "/boot/EFI/boot/${image_name}" -fi - -finish_modify_image -command_completed diff --git a/image_set_group b/image_set_group deleted file mode 100755 index a034167b11..0000000000 --- a/image_set_group +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2014 The CoreOS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -SCRIPT_ROOT=$(dirname "$(readlink -f "$0")") -. "${SCRIPT_ROOT}/common.sh" || exit 1 - -# Script must run inside the chroot -assert_inside_chroot - -assert_not_root_user - -# Flags -DEFINE_string group "" \ - "The update group, required." -DEFINE_string board "${DEFAULT_BOARD}" \ - "Board for which the image was built" -DEFINE_string disk_layout "base" \ - "The disk layout type to use for this image." -DEFINE_string from "" \ - "Directory containing ${FLATCAR_PRODUCTION_IMAGE_NAME}" -DEFINE_string output_root "${DEFAULT_BUILD_ROOT}/images" \ - "Directory in which to place image result directories (named by version)" -DEFINE_boolean replace ${FLAGS_FALSE} \ - "Overwrite existing output, if any." - -# include upload options -. "${BUILD_LIBRARY_DIR}/release_util.sh" || exit 1 - -show_help_if_requested "$@" - -# Usually unneded, so just leave this option hidden. -DEFINE_integer build_attempt 1 \ - "The build attempt for this image build." - -# Parse command line -FLAGS "$@" || exit 1 -eval set -- "${FLAGS_ARGV}" - -# Die on any errors. -switch_to_strict_mode - -if [[ -z "${FLAGS_board}" ]] ; then - die_notrace "--board is required." -fi - -if [[ -z "${FLAGS_group}" ]] ; then - die_notrace "--group is required." -fi - -. "${BUILD_LIBRARY_DIR}/modify_image_util.sh" - -start_modify_image - -info "Replacing /etc/flatcar/update.conf" -sudo mkdir -p "${ROOT_FS_DIR}/etc/flatcar" -sudo_clobber "${ROOT_FS_DIR}/etc/flatcar/update.conf" < Date: Fri, 29 Nov 2024 10:31:33 +0000 Subject: [PATCH 3/5] app-crypt/azure-keyvault-pkcs11: Bump snapshot to 20241129 to fix debug Debug output was causing a stack smashing error. Signed-off-by: James Le Cuirot --- .../coreos-overlay/app-crypt/azure-keyvault-pkcs11/Manifest | 2 +- ...20241115.ebuild => azure-keyvault-pkcs11-0_p20241129.ebuild} | 2 +- .../coreos-overlay/profiles/coreos/base/package.accept_keywords | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename sdk_container/src/third_party/coreos-overlay/app-crypt/azure-keyvault-pkcs11/{azure-keyvault-pkcs11-0_p20241115.ebuild => azure-keyvault-pkcs11-0_p20241129.ebuild} (91%) diff --git a/sdk_container/src/third_party/coreos-overlay/app-crypt/azure-keyvault-pkcs11/Manifest b/sdk_container/src/third_party/coreos-overlay/app-crypt/azure-keyvault-pkcs11/Manifest index 361fad19ea..a4639a5a28 100644 --- a/sdk_container/src/third_party/coreos-overlay/app-crypt/azure-keyvault-pkcs11/Manifest +++ b/sdk_container/src/third_party/coreos-overlay/app-crypt/azure-keyvault-pkcs11/Manifest @@ -1 +1 @@ -DIST azure-keyvault-pkcs11-0_p20241115.tar.gz 22226 BLAKE2B 4dd9bc861ced98c305c1a670149f2e03d0c77b667fcd378521128d7f73334b1882427f4c2dd41dbba8fe0551d5bffcfcb819f085211c733c7f3c4dc4b6acdba1 SHA512 c6640f3989b10db251fbc0dbd157faa0e9b339c9ed22b9d92e2040805aecdc1dc36b76cc5f48ad4dfa41d1fcd7402843de17198e26a952f2cdfb920e7eb16a89 +DIST azure-keyvault-pkcs11-0_p20241129.tar.gz 22227 BLAKE2B c1949b7dacca80c353db1b4d9eb5f0c18ea352fd31eec7312ab964da8b6e5e9bc2f98499de1a08bd67734f857072800be6879df7f388b1d9b78c865c04708d5c SHA512 82fd396c70ca3322b2dcacddf1f1ae2f53c147e99f4c71d95952a60abcbb2fbbb11686f5fb863364c30acc2cd879d4ba5f2b539493f2976d9a2fa118a40efcf5 diff --git a/sdk_container/src/third_party/coreos-overlay/app-crypt/azure-keyvault-pkcs11/azure-keyvault-pkcs11-0_p20241115.ebuild b/sdk_container/src/third_party/coreos-overlay/app-crypt/azure-keyvault-pkcs11/azure-keyvault-pkcs11-0_p20241129.ebuild similarity index 91% rename from sdk_container/src/third_party/coreos-overlay/app-crypt/azure-keyvault-pkcs11/azure-keyvault-pkcs11-0_p20241115.ebuild rename to sdk_container/src/third_party/coreos-overlay/app-crypt/azure-keyvault-pkcs11/azure-keyvault-pkcs11-0_p20241129.ebuild index faf127dacc..ae870bcea7 100644 --- a/sdk_container/src/third_party/coreos-overlay/app-crypt/azure-keyvault-pkcs11/azure-keyvault-pkcs11-0_p20241115.ebuild +++ b/sdk_container/src/third_party/coreos-overlay/app-crypt/azure-keyvault-pkcs11/azure-keyvault-pkcs11-0_p20241129.ebuild @@ -5,7 +5,7 @@ EAPI=8 inherit cmake -COMMIT="f5ea4244d7b9d0cd232498d251441698d3c5760f" # chewi/rename +COMMIT="d6e74962ca05bc0ea329ead2e59e3022ebff2649" # chewi/rename DESCRIPTION="PKCS#11 module for Azure Key Vault" HOMEPAGE="https://github.com/jepio/azure_keyvault_pkcs11" SRC_URI="https://github.com/jepio/azure_keyvault_pkcs11/archive/${COMMIT}.tar.gz -> ${P}.tar.gz" diff --git a/sdk_container/src/third_party/coreos-overlay/profiles/coreos/base/package.accept_keywords b/sdk_container/src/third_party/coreos-overlay/profiles/coreos/base/package.accept_keywords index 8b3d91fe60..3987d087f9 100644 --- a/sdk_container/src/third_party/coreos-overlay/profiles/coreos/base/package.accept_keywords +++ b/sdk_container/src/third_party/coreos-overlay/profiles/coreos/base/package.accept_keywords @@ -45,7 +45,7 @@ =app-crypt/adcli-0.9.2 ~arm64 # Needs cleaning up and adding to Gentoo before stabilising -=app-crypt/azure-keyvault-pkcs11-0_p20241115 ~amd64 +=app-crypt/azure-keyvault-pkcs11-0_p20241129 ~amd64 # Needed by arm64-native SDK =app-crypt/ccid-1.5.4 ~arm64 From b3183b42c48339fa2feb6ba253782345c17d4453 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Fri, 22 Nov 2024 11:09:44 +0000 Subject: [PATCH 4/5] Do SB signing for official builds in a separate additional job We only want to do the signing in Azure, not the whole image job. This new job downloads the unsigned image, signs it, and replaces it. Signed-off-by: James Le Cuirot --- build_library/build_image_util.sh | 74 +++++++++++++++++++++-- build_library/grub_install.sh | 4 +- build_library/prod_image_util.sh | 32 ++++++++++ ci-automation/sbsign_image.sh | 97 +++++++++++++++++++++++++++++++ sbsign_image | 68 ++++++++++++++++++++++ 5 files changed, 269 insertions(+), 6 deletions(-) create mode 100644 ci-automation/sbsign_image.sh create mode 100755 sbsign_image diff --git a/build_library/build_image_util.sh b/build_library/build_image_util.sh index 87f74bc7b4..132b52374e 100755 --- a/build_library/build_image_util.sh +++ b/build_library/build_image_util.sh @@ -791,10 +791,12 @@ EOF seek=${verity_offset} count=64 bs=1 status=none fi - # Sign the kernel after /usr is in a consistent state and verity is calculated - [[ ${COREOS_OFFICIAL:-0} -ne 1 ]] && \ - do_sbsign --output "${root_fs_dir}/boot/flatcar/vmlinuz-a"{,} - cleanup_sbsign_certs + # Sign the kernel after /usr is in a consistent state and verity is + # calculated. Only for unofficial builds as official builds get signed later. + if [[ ${COREOS_OFFICIAL:-0} -ne 1 ]]; then + do_sbsign --output "${root_fs_dir}/boot/flatcar/vmlinuz-a"{,} + cleanup_sbsign_certs + fi if [[ -n "${image_kernel}" ]]; then # copying kernel from vfat so ignore the permissions @@ -880,3 +882,67 @@ EOF cleanup_mounts "${root_fs_dir}" trap - EXIT } + +sbsign_image() { + local image_name="$1" + local disk_layout="$2" + local root_fs_dir="$3" + local image_kernel="$4" + local pcr_policy="$5" + local image_grub="$6" + + local disk_img="${BUILD_DIR}/${image_name}" + local EFI_ARCH + + case "${BOARD}" in + amd64-usr) EFI_ARCH="x64" ;; + arm64-usr) EFI_ARCH="aa64" ;; + *) die "Unknown board ${BOARD@Q}" ;; + esac + + "${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${disk_layout}" \ + mount "${disk_img}" "${root_fs_dir}" + trap "cleanup_mounts '${root_fs_dir}'; cleanup_sbsign_certs" EXIT + + # Sign the kernel with the shim-embedded key. + do_sbsign --output "${root_fs_dir}/boot/flatcar/vmlinuz-a"{,} + + if [[ -n "${image_kernel}" ]]; then + # copying kernel from vfat so ignore the permissions + cp --no-preserve=mode \ + "${root_fs_dir}/boot/flatcar/vmlinuz-a" \ + "${BUILD_DIR}/${image_kernel}" + fi + + # Sign GRUB and mokmanager(mm) with the shim-embedded key. + do_sbsign --output "${root_fs_dir}/boot/EFI/boot/grub${EFI_ARCH}.efi"{,} + do_sbsign --output "${root_fs_dir}/boot/EFI/boot/mm${EFI_ARCH}.efi"{,} + + # copying from vfat so ignore permissions + if [[ -n "${image_grub}" ]]; then + cp --no-preserve=mode "${root_fs_dir}/boot/EFI/boot/grub${EFI_ARCH}.efi" \ + "${BUILD_DIR}/${image_grub}" + fi + + if [[ -n "${pcr_policy}" ]]; then + mkdir -p "${BUILD_DIR}/pcrs" + "${BUILD_LIBRARY_DIR}"/generate_kernel_hash.py \ + "${root_fs_dir}/boot/flatcar/vmlinuz-a" "${FLATCAR_VERSION}" \ + >"${BUILD_DIR}/pcrs/kernel.config" + fi + + cleanup_mounts "${root_fs_dir}" + cleanup_sbsign_certs + trap - EXIT + + if [[ -n "${pcr_policy}" ]]; then + "${BUILD_LIBRARY_DIR}"/generate_grub_hashes.py \ + "${disk_img}" /usr/lib/grub/ "${BUILD_DIR}/pcrs" "${FLATCAR_VERSION}" + + info "Generating $pcr_policy" + pushd "${BUILD_DIR}" >/dev/null + zip --quiet -r -9 "${BUILD_DIR}/${pcr_policy}" pcrs + popd >/dev/null + rm -rf "${BUILD_DIR}/pcrs" + fi +} diff --git a/build_library/grub_install.sh b/build_library/grub_install.sh index 840dbdd029..61e2fc6fb8 100755 --- a/build_library/grub_install.sh +++ b/build_library/grub_install.sh @@ -205,10 +205,10 @@ case "${FLAGS_target}" in --output "${ESP_DIR}/EFI/boot/boot${EFI_ARCH}.efi" \ "${BOARD_ROOT}/usr/lib/shim/shim${EFI_ARCH}.efi" else - # Official build: Copy the unsigned files. + # Official build: Copy signed shim and mm for signing later. sudo cp "${BOARD_ROOT}/usr/lib/shim/mm${EFI_ARCH}.efi" \ "${ESP_DIR}/EFI/boot/mm${EFI_ARCH}.efi" - sudo cp "${BOARD_ROOT}/usr/lib/shim/shim${EFI_ARCH}.efi" \ + sudo cp "${BOARD_ROOT}/usr/lib/shim/shim${EFI_ARCH}.efi.signed" \ "${ESP_DIR}/EFI/boot/boot${EFI_ARCH}.efi" fi diff --git a/build_library/prod_image_util.sh b/build_library/prod_image_util.sh index 561766aa21..291795ee8c 100755 --- a/build_library/prod_image_util.sh +++ b/build_library/prod_image_util.sh @@ -180,6 +180,15 @@ EOF "${image_initrd_contents_wtd}" \ "${image_disk_usage}" + # Official builds will sign and upload these files later, so remove them to + # prevent them from being uploaded now. + if [[ ${COREOS_OFFICIAL:-0} -eq 1 ]]; then + rm -v \ + "${BUILD_DIR}/${image_kernel}" \ + "${BUILD_DIR}/${image_pcr_policy}" \ + "${BUILD_DIR}/${image_grub}" + fi + local files_to_evaluate=( "${BUILD_DIR}/${image_name}" ) compress_disk_images files_to_evaluate } @@ -225,3 +234,26 @@ create_prod_sysexts() { -out_file "${BUILD_DIR}/flatcar_test_update-${name}.gz" done } + +sbsign_prod_image() { + local image_name="$1" + local disk_layout="$2" + + info "Signing production image ${image_name} for Secure Boot" + local root_fs_dir="${BUILD_DIR}/rootfs" + local image_prefix="${image_name%.bin}" + local image_kernel="${image_prefix}.vmlinuz" + local image_pcr_policy="${image_prefix}_pcr_policy.zip" + local image_grub="${image_prefix}.grub" + + sbsign_image \ + "${image_name}" \ + "${disk_layout}" \ + "${root_fs_dir}" \ + "${image_kernel}" \ + "${image_pcr_policy}" \ + "${image_grub}" + + local files_to_evaluate=( "${BUILD_DIR}/${image_name}" ) + compress_disk_images files_to_evaluate +} diff --git a/ci-automation/sbsign_image.sh b/ci-automation/sbsign_image.sh new file mode 100644 index 0000000000..fe3053e7fd --- /dev/null +++ b/ci-automation/sbsign_image.sh @@ -0,0 +1,97 @@ +#!/bin/bash +# +# Copyright (c) 2024 The Flatcar Maintainers. +# Use of this source code is governed by the Apache 2.0 license. + +# >>> This file is supposed to be SOURCED from the repository ROOT. <<< +# +# sbsign_image() should be called w/ the positional INPUT parameters below. + +# Secure Boot image signing build automation stub. +# This script will sign an existing OS image for Secure Boot. +# +# PREREQUISITES: +# +# 1. SDK version and OS image version are recorded in sdk_container/.repo/manifests/version.txt +# 2. Scripts repo version tag of OS image version to be built is available and checked out. +# 3. The generic Flatcar image must be present in build cache server. +# +# INPUT: +# +# 1. Architecture (ARCH) of the TARGET vm images ("arm64", "amd64"). +# +# OPTIONAL INPUT: +# +# 1. SIGNER. Environment variable. Name of the owner of the artifact signing key. +# Defaults to nothing if not set - in such case, artifacts will not be signed. +# If provided, SIGNING_KEY environment variable should also be provided, otherwise this environment variable will be ignored. +# +# 2. SIGNING_KEY. Environment variable. The artifact signing key. +# Defaults to nothing if not set - in such case, artifacts will not be signed. +# If provided, SIGNER environment variable should also be provided, otherwise this environment variable will be ignored. +# +# 3. A file ../scripts.patch to apply with "git am -3" for the scripts repo. +# +# OUTPUT: +# +# 1. OS image and related artifacts signed for Secure Boot pushed to buildcache. +# 2. If signer key was passed, signatures of artifacts from point 1, pushed along to buildcache. +# 3. DIGESTS of the artifacts from point 1, pushed to buildcache. If signer key was passed, armored ASCII files of the generated DIGESTS files too, pushed to buildcache. + +function sbsign_image() { + # Run a subshell, so the traps, environment changes and global + # variables are not spilled into the caller. + ( + set -euo pipefail + + _sbsign_image_impl "${@}" + ) +} +# -- + +function _sbsign_image_impl() { + local arch="$1" + + source sdk_lib/sdk_container_common.sh + local channel="" + channel="$(get_git_channel)" + source ci-automation/ci_automation_common.sh + source ci-automation/gpg_setup.sh + source sdk_container/.repo/manifests/version.txt + + if is_official "${FLATCAR_VERSION}"; then + export COREOS_OFFICIAL=1 + else + export COREOS_OFFICIAL=0 + fi + + apply_local_patches + + local images_remote="images/${arch}/${FLATCAR_VERSION}" + local images_local="__build__/images/images/${arch}-usr/${channel}-${FLATCAR_VERSION}" + + copy_from_buildcache "${images_remote}/flatcar_production_image.bin.bz2" "${images_local}" + lbunzip2 --force "${images_local}/flatcar_production_image.bin.bz2" + + # Get SDK from either the registry or import from build cache + # This is a NOP if the image is present locally. + local sdk_name="flatcar-sdk-${arch}" + local docker_sdk_vernum="$(vernum_to_docker_image_version "${FLATCAR_SDK_VERSION}")" + + docker_image_from_registry_or_buildcache "${sdk_name}" "${docker_sdk_vernum}" + local sdk_image="$(docker_image_fullname "${sdk_name}" "${docker_sdk_vernum}")" + echo "docker image rm -f '${sdk_image}'" >> ./ci-cleanup.sh + + ./run_sdk_container -x ./ci-cleanup.sh -v "${FLATCAR_VERSION}" -U -C "${sdk_image}" \ + ./sbsign_image --board="${arch}-usr" \ + --group="${channel}" --version="${FLATCAR_VERSION}" \ + --output_root="${CONTAINER_IMAGE_ROOT}" \ + --only_store_compressed + + # Delete uncompressed generic image before signing and upload + rm "${images_local}/flatcar_production_image.bin" + create_digests "${SIGNER}" "${images_local}"/* + sign_artifacts "${SIGNER}" "${images_local}"/* + copy_to_buildcache "${images_remote}"/ "${images_local}"/* +} +# -- diff --git a/sbsign_image b/sbsign_image new file mode 100755 index 0000000000..66aca04472 --- /dev/null +++ b/sbsign_image @@ -0,0 +1,68 @@ +#!/bin/bash + +# Copyright (c) 2024 The Flatcar Maintainers. +# Use of this source code is governed by the Apache 2.0 license. + +# Script to sign an existing raw Flatcar disk image for Secure Boot. + +SCRIPT_ROOT=$(dirname "$(readlink -f "$0")") +. "${SCRIPT_ROOT}/common.sh" || exit 1 + +# Script must run inside the chroot +assert_inside_chroot + +assert_not_root_user + +DEFAULT_GROUP=developer + +# Developer-visible flags. +DEFINE_string board "${DEFAULT_BOARD}" \ + "The board to build an image for." +DEFINE_string output_root "${DEFAULT_BUILD_ROOT}/images" \ + "Directory in which to place image result directories (named by version)" +DEFINE_string disk_layout "" \ + "The disk layout type to use for this image." +DEFINE_string group "${DEFAULT_GROUP}" \ + "The update group." + +# include upload options +. "${BUILD_LIBRARY_DIR}/release_util.sh" || exit 1 + +FLAGS_HELP="USAGE: sbsign_image [flags] +This script is used to sign the GRUB and kernel images within an +existing raw Flatcar disk image for Secure Boot. The disk image is +read from the output directory and modified in-place. The signed GRUB +and kernel images are also written separately to the same directory. +" +show_help_if_requested "$@" + +# The following options are advanced options, only available to those willing +# to read the source code. They are not shown in help output, since they are +# not needed for the typical developer workflow. +DEFINE_integer build_attempt 1 \ + "The build attempt for this image build." +DEFINE_string version "" \ + "Overrides version number in name to this version." + +# Parse command line. +FLAGS "$@" || exit 1 + +# Only now can we die on error. shflags functions leak non-zero error codes, +# so will die prematurely if 'switch_to_strict_mode' is specified before now. +switch_to_strict_mode + +# N.B. Ordering matters for some of the libraries below, because +# some of the files contain initialization used by later files. +. "${BUILD_LIBRARY_DIR}/toolchain_util.sh" || exit 1 +. "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1 +. "${BUILD_LIBRARY_DIR}/build_image_util.sh" || exit 1 +. "${BUILD_LIBRARY_DIR}/prod_image_util.sh" || exit 1 + +# Create the output directory and temporary mount points. +mkdir -p "${BUILD_DIR}" + +fix_mtab +sbsign_prod_image "${FLATCAR_PRODUCTION_IMAGE_NAME}" "${FLAGS_disk_layout:-base}" + +echo "Done. ${FLATCAR_PRODUCTION_IMAGE_NAME} and associated files are now signed for Secure Boot in ${BUILD_DIR}." +command_completed From e6e3dafa86c29e94e9aaba8d965e294dc5e59819 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Mon, 2 Dec 2024 10:51:14 +0000 Subject: [PATCH 5/5] grub_install.sh: Temporarily undo copying the officially signed shim We previously did the AKV signing in the image job but temporarily nobbled that code path while we completed the shim review. Now the AKV signing has been split out into a separate job that will only be invoked once changes to the jenkins-os repo have been merged. The only thing we now need to nobble here is copying the signed shim. In the meantime, we copy the unsigned shim instead. Revert this commit once the shim review is complete. --- build_library/grub_install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_library/grub_install.sh b/build_library/grub_install.sh index 61e2fc6fb8..43dfd606e7 100755 --- a/build_library/grub_install.sh +++ b/build_library/grub_install.sh @@ -208,7 +208,7 @@ case "${FLAGS_target}" in # Official build: Copy signed shim and mm for signing later. sudo cp "${BOARD_ROOT}/usr/lib/shim/mm${EFI_ARCH}.efi" \ "${ESP_DIR}/EFI/boot/mm${EFI_ARCH}.efi" - sudo cp "${BOARD_ROOT}/usr/lib/shim/shim${EFI_ARCH}.efi.signed" \ + sudo cp "${BOARD_ROOT}/usr/lib/shim/shim${EFI_ARCH}.efi" \ "${ESP_DIR}/EFI/boot/boot${EFI_ARCH}.efi" fi