From dabb158ad27610661ef16639843e2909f2a3dba5 Mon Sep 17 00:00:00 2001 From: Amey Deshpande Date: Wed, 16 Sep 2015 18:16:42 -0700 Subject: signer: update legacy bootloader templates after image signing Specifically, this patch updates 'root_hexdigest' in legacy bootloader templates in EFI system partition to match the signed rootfs. BRANCH=None BUG=chromium:512940 TEST=Ran sign_official_build.sh locally and booted the image on kvm (using BIOS). TEST=Ran signing_unittests.py by locally changing vboot_stable_hash to include this patch. $ ./sign_official_build.sh base chromiumos_base_image.bin \ ../../tests/devkeys chromiumos_base_image_signed.bin Change-Id: Ied021c4464b113a64508f5081605069bdcecbc1f Reviewed-on: https://chromium-review.googlesource.com/301742 Commit-Ready: Amey Deshpande Tested-by: Amey Deshpande Reviewed-by: Mike Frysinger --- scripts/image_signing/common_minimal.sh | 39 ++++++++++++++------ scripts/image_signing/sign_official_build.sh | 53 ++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 11 deletions(-) diff --git a/scripts/image_signing/common_minimal.sh b/scripts/image_signing/common_minimal.sh index be3d2adc..ad84c501 100644 --- a/scripts/image_signing/common_minimal.sh +++ b/scripts/image_signing/common_minimal.sh @@ -162,20 +162,18 @@ is_rootfs_partition() { # If the kernel is buggy and is unable to loop+mount quickly, # retry the operation a few times. # Args: IMAGE PARTNUM MOUNTDIRECTORY [ro] +# +# This function does not check whether the partition is allowed to be mounted as +# RW. Callers must ensure the partition can be mounted as RW before calling +# this function without |ro| argument. _mount_image_partition_retry() { local image=$1 local partnum=$2 local mount_dir=$3 local ro=$4 - local offset=$(( $(partoffset "$image" "$partnum") * 512 )) + local offset=$(( $(partoffset "${image}" "${partnum}") * 512 )) local out try - if [ "$ro" != "ro" ]; then - # Forcibly call enable_rw_mount. It should fail on unsupported - # filesystems and be idempotent on ext*. - enable_rw_mount "$image" ${offset} 2> /dev/null - fi - set -- sudo LC_ALL=C mount -o loop,offset=${offset},${ro} \ "${image}" "${mount_dir}" try=1 @@ -204,19 +202,38 @@ _mount_image_partition_retry() { return 1 } +# If called without 'ro', make sure the partition is allowed to be mounted as +# 'rw' before actually mounting it. +# Args: IMAGE PARTNUM MOUNTDIRECTORY [ro] +_mount_image_partition() { + local image=$1 + local partnum=$2 + local mount_dir=$3 + local ro=$4 + local offset=$(( $(partoffset "${image}" "${partnum}") * 512 )) + + if [ "$ro" != "ro" ]; then + # Forcibly call enable_rw_mount. It should fail on unsupported + # filesystems and be idempotent on ext*. + enable_rw_mount "${image}" ${offset} 2> /dev/null + fi + + _mount_image_partition_retry "$@" +} + # Mount a partition read-only from an image into a local directory # Args: IMAGE PARTNUM MOUNTDIRECTORY mount_image_partition_ro() { - _mount_image_partition_retry "$@" "ro" + _mount_image_partition "$@" "ro" } # Mount a partition from an image into a local directory # Args: IMAGE PARTNUM MOUNTDIRECTORY mount_image_partition() { local mount_dir=$3 - _mount_image_partition_retry "$@" - if is_rootfs_partition "$mount_dir"; then - tag_as_needs_to_be_resigned "$mount_dir" + _mount_image_partition "$@" + if is_rootfs_partition "${mount_dir}"; then + tag_as_needs_to_be_resigned "${mount_dir}" fi } diff --git a/scripts/image_signing/sign_official_build.sh b/scripts/image_signing/sign_official_build.sh index 72d4f58b..d1c87685 100755 --- a/scripts/image_signing/sign_official_build.sh +++ b/scripts/image_signing/sign_official_build.sh @@ -695,6 +695,55 @@ update_recovery_kernel_hash() { replace_image_partition ${image_bin} 2 ${updated_kimagea} } +# Update the legacy bootloader templates in EFI partition if available. +# Args: IMAGE_BIN DM_PARTNO +update_legacy_bootloader() { + local image="$1" + local dm_partno="$2" + + local esp_partnum=12 + local esp_offset=$(( $(partoffset "${image}" "${esp_partnum}") * 512 )) + # Check if the image has an ESP partition. + if [[ "${esp_offset}" == "0" ]]; then + info "Not updating legacy bootloader configs: ${image}" + return 0 + fi + + local esp_dir="$(make_temp_dir)" + # We use the 'unsafe' variant because the EFI system partition is vfat type + # and can be mounted in RW mode. + _mount_image_partition_retry "${image}" "${esp_partnum}" "${esp_dir}" + + # If we can't find the dm parameter in the kernel config, bail out now. + local kernel_config=$(grab_kernel_config "${image}" "${dm_partno}") + local root_hexdigest="$(get_hash_from_config "${kernel_config}")" + if [[ -z "${root_hexdigest}" ]]; then + error "Couldn't grab root_digest from kernel partition ${dm_partno}" + error " (config: ${kernel_config})" + return 1 + fi + # Update syslinux configs for legacy BIOS systems. + if [[ -d "${esp_dir}/syslinux" ]]; then + local cfg=("${esp_dir}"/syslinux/*.cfg) + if ! sudo sed -i -r \ + "s/\broot_hexdigest=[a-z0-9]+/root_hexdigest=${root_hexdigest}/g" \ + "${cfg[@]}"; then + error "Updating syslinux configs failed: '${cfg[*]}'" + return 1 + fi + fi + # Update grub configs for EFI systems. + local grub_cfg="${esp_dir}/efi/boot/grub.cfg" + if [[ -f "${grub_cfg}" ]]; then + if ! sudo sed -i -r \ + "s/\broot_hexdigest=[a-z0-9]+/root_hexdigest=${root_hexdigest}/g" \ + "${grub_cfg}"; then + error "Updating grub config failed: '${grub_cfg}'" + return 1 + fi + fi +} + # Sign an image file with proper keys. # Args: IMAGE_TYPE INPUT OUTPUT DM_PARTNO KERN_A_KEYBLOCK KERN_A_PRIVKEY \ # KERN_B_KEYBLOCK KERN_B_PRIVKEY @@ -735,6 +784,10 @@ sign_image_file() { if [[ "${image_type}" == "recovery" ]]; then update_recovery_kernel_hash "${output}" fi + if ! update_legacy_bootloader "${output}" "${dm_partno}"; then + # Error is already logged. + return 1 + fi echo "Signed ${image_type} image output to ${output}" } -- cgit v1.2.1