flash-gui.sh: Extend NPF archive format to ZIP, improve workflow

Allow configuring the ZIP-format update file extension with
CONFIG_BRAND_UPDATE_PKG_EXT in board config.  Default is 'zip'.

Create update package in the default Makefile target.  Delete
create_npf.sh.

Do not require /tmp/verified_rom in the update file package's
sha256sum.txt (but allow it for backward compatibility).

Show the integrity error if unzip fails instead of dying (which returns
to main menu with no explanation, error is left on recovery console).
This is the most likely way corruption would be detected as ZIP has
CRCs.  The sha256sum is still present for more robust detection.

Don't require the ROM to be the first file in sha256sum.txt since it
raises complexity of adding more files to the update archive in the
future.  Instead require that the package contains exactly one file
matching '*.rom'.

Restore confirmation prompt for the update-package flow, at some point
this was lost.

Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
This commit is contained in:
Jonathon Hall 2023-11-13 16:42:05 -05:00
parent bd0ebc4975
commit 5bd50652a0
No known key found for this signature in database
GPG Key ID: 1E9C3CA91AE25114
3 changed files with 78 additions and 27 deletions

View File

@ -52,6 +52,11 @@ CONFIG_TARGET_ARCH := x86
include $(CONFIG)
# Default update package extension is 'zip' unless a brand wants a branded
# extension
CONFIG_BRAND_UPDATE_PKG_EXT ?= zip
CB_UPDATE_PKG_FILE := $(CB_OUTPUT_BASENAME).$(CONFIG_BRAND_UPDATE_PKG_EXT)
# Unless otherwise specified, we are building for heads
CONFIG_HEADS ?= y
@ -159,7 +164,18 @@ payload: $(build)/$(BOARD)/bzImage $(build)/$(initrd_dir)/initrd.cpio.xz
ifeq ($(CONFIG_COREBOOT), y)
all: $(board_build)/$(CB_OUTPUT_FILE)
# Coreboot targets create an update package that can be applied with integrity
# verification before flashing (see flash-gui.sh). The ZIP package format
# allows other metadata that might be needed to added in the future without
# breaking backward compatibility.
$(board_build)/$(CB_UPDATE_PKG_FILE): $(board_build)/$(CB_OUTPUT_FILE)
rm -rf "$(board_build)/update_pkg"
mkdir -p "$(board_build)/update_pkg"
cp "$<" "$(board_build)/update_pkg/"
cd "$(board_build)/update_pkg" && sha256sum "$(CB_OUTPUT_FILE)" >sha256sum.txt
cd "$(board_build)/update_pkg" && zip -9 "$@" "$(CB_OUTPUT_FILE)" sha256sum.txt
all: $(board_build)/$(CB_OUTPUT_FILE) $(board_build)/$(CB_UPDATE_PKG_FILE)
ifneq ($(CONFIG_COREBOOT_BOOTBLOCK),)
all: $(board_build)/$(CB_BOOTBLOCK_FILE)
endif

View File

@ -1,8 +0,0 @@
#!/bin/bash
set -exuo pipefail
HEADS_GIT_VERSION=$(git describe --tags)
BOARD=$1
cd ./build/x86/${BOARD}/
sha256sum heads-${BOARD}-${HEADS_GIT_VERSION}.rom > sha256sum.txt
sed -ie 's@ @ /tmp/verified_rom/@g' sha256sum.txt
zip heads-${BOARD}-${HEADS_GIT_VERSION}.npf heads-${BOARD}-${HEADS_GIT_VERSION}.rom sha256sum.txt

View File

@ -13,6 +13,26 @@ if [ "$CONFIG_RESTRICTED_BOOT" = y ]; then
exit 1
fi
# A brand can override the extension used for update packages if desired
UPDATE_PKG_EXT="${CONFIG_BRAND_UPDATE_PKG_EXT:-zip}"
# Check that a glob matches exactly one thing. If so, echoes the single value.
# Otherwise, fails. As always, do not quote the glob.
#
# E.g, locate a ROM with unknown version when only one should be present:
# if ROM_FILE="$(single_glob /media/heads-*.rom)"; then
# echo "ROM is $ROM_FILE"
# else
# echo "Failed to find a ROM" >&2
# fi
single_glob() {
if [ "$#" -eq 1 ] && [ -f "$1" ]; then
echo "$1"
else
return 1
fi
}
while true; do
unset menu_choice
whiptail $BG_COLOR_MAIN_MENU --title "Firmware Management Menu" \
@ -30,38 +50,61 @@ while true; do
;;
f | c)
if (whiptail $BG_COLOR_WARNING --title 'Flash the BIOS with a new ROM' \
--yesno "You will need to insert a USB drive containing your BIOS image (*.rom, *.npf or *.tgz).\n\nAfter you select this file, this program will reflash your BIOS.\n\nDo you want to proceed?" 0 80); then
--yesno "You will need to insert a USB drive containing your BIOS image (*.$UPDATE_PKG_EXT, *.rom, or *.tgz).\n\nAfter you select this file, this program will reflash your BIOS.\n\nDo you want to proceed?" 0 80); then
mount_usb
if grep -q /media /proc/mounts; then
find /media ! -path '*/\.*' -type f \( -name '*.rom' -o -name '*.tgz' -o -type f -name '*.npf' \) | sort >/tmp/filelist.txt
find /media ! -path '*/\.*' -type f \( -name '*.rom' -o -name '*.tgz' -o -type f -name "*.$UPDATE_PKG_EXT" \) | sort >/tmp/filelist.txt
file_selector "/tmp/filelist.txt" "Choose the ROM to flash"
if [ "$FILE" == "" ]; then
exit 1
else
ROM=$FILE
PKG_FILE=$FILE
fi
# is a .npf provided?
if [ -z "${ROM##*.npf}" ]; then
#preventive cleanup
rm -rf /tmp/verified_rom >/dev/null 2>&1 || true
# unzip to /tmp/verified_rom
mkdir -p /tmp/verified_rom >/dev/null 2>&1 || true
unzip $ROM -d /tmp/verified_rom || die "Failed to unzip ROM file"
# is an update package provided?
if [ -z "${PKG_FILE##*.$UPDATE_PKG_EXT}" ]; then
# Unzip the package
PKG_EXTRACT="/tmp/flash_gui/update_package"
rm -rf "$PKG_EXTRACT"
mkdir -p "$PKG_EXTRACT"
# If extraction fails, delete everything and fall through to the
# integrity failure prompt. This is the most likely path if the ROM
# was actually corrupted in transit. Corrupting the ZIP in a way that
# still extracts is possible (the sha256sum detects this) but less
# likely.
unzip "$PKG_FILE" -d "$PKG_EXTRACT" || rm -rf "$PKG_EXTRACT"
# Older packages had /tmp/verified_rom hard-coded in the sha256sum.txt
# Remove that so it's a relative path to the ROM in the package.
# Ignore failure, if there is no sha256sum.txt the sha256sum will fail
sed -i -e 's| /tmp/verified_rom/\+| |g' "$PKG_EXTRACT/sha256sum.txt" || true
# check file integrity
if (cd /tmp/verified_rom/ && sha256sum -cs /tmp/verified_rom/sha256sum.txt); then
ROM="$(head -n1 /tmp/verified_rom/sha256sum.txt | cut -d ' ' -f 3)"
else
if ! (cd "$PKG_EXTRACT" && sha256sum -cs sha256sum.txt); then
whiptail --title 'ROM Integrity Check Failed! ' \
--msgbox "$ROM integrity check failed. Did not flash.\n\nPlease check your file (e.g. re-download).\n" 16 60
exit
--msgbox "Integrity check failed in\n$PKG_FILE.\nDid not flash.\n\nPlease check your file (e.g. re-download).\n" 16 60
exit 1
fi
# The package must contain exactly one *.rom file, flash that.
if ! PACKAGE_ROM="$(single_glob "$PKG_EXTRACT/"*.rom)"; then
whiptail --title 'BIOS Image Not Found! ' \
--msgbox "A BIOS image was not found in\n$PKG_FILE.\n\nPlease check your file (e.g. re-download).\n" 16 60
exit 1
fi
if ! whiptail $BG_COLOR_WARNING --title 'Flash ROM?' \
--yesno "This will replace your current ROM with:\n\n${PKG_FILE#"/media/"}\n\nDo you want to proceed?" 0 80; then
exit 1
fi
# Continue on using the verified ROM
ROM="$PACKAGE_ROM"
else
# a rom file was provided. exit if we shall not proceed
ROM="$PKG_FILE"
ROM_HASH=$(sha256sum "$ROM" | awk '{print $1}') || die "Failed to hash ROM file"
if ! (whiptail $CONFIG_ERROR_BG_COLOR --title 'Flash ROM without integrity check?' \
--yesno "You have provided a *.rom file. The integrity of the file can not be\nchecked automatically for this file type.\n\nROM: $ROM\nSHA256SUM: $ROM_HASH\n\nIf you do not know how to check the file integrity yourself,\nyou should use a *.npf file instead.\n\nIf the file is damaged, you will not be able to boot anymore.\nDo you want to proceed flashing without file integrity check?" 0 80); then
exit
--yesno "You have provided a *.rom file. The integrity of the file can not be\nchecked automatically for this file type.\n\nROM: $ROM\nSHA256SUM: $ROM_HASH\n\nIf you do not know how to check the file integrity yourself,\nyou should use a *.$UPDATE_PKG_EXT file instead.\n\nIf the file is damaged, you will not be able to boot anymore.\nDo you want to proceed flashing without file integrity check?" 0 80); then
exit 1
fi
fi
@ -79,7 +122,7 @@ while true; do
/bin/flash.sh "$ROM"
fi
whiptail --title 'ROM Flashed Successfully' \
--msgbox "${ROM#"/media/"}\n\nhas been flashed successfully.\n\nPress Enter to reboot\n" 0 80
--msgbox "${PKG_FILE#"/media/"}\n\nhas been flashed successfully.\n\nPress Enter to reboot\n" 0 80
umount /media
/bin/reboot
fi