From accd9f470dee5105e9a548f7e67506dd4534ae0e Mon Sep 17 00:00:00 2001 From: 3hhh Date: Sat, 31 Dec 2022 18:41:24 +0100 Subject: [PATCH] initrd: track files in /boot in kexec_tree.txt Fixes #1248 --- initrd/bin/gui-init | 5 +++-- initrd/bin/kexec-select-boot | 5 +++-- initrd/bin/kexec-sign-config | 6 +++++- initrd/bin/oem-factory-reset | 11 ++++++++--- initrd/etc/functions | 25 +++++++++++++++++++++++++ 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index e3555cb6..ff4f7310 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -66,12 +66,13 @@ verify_global_hashes() # Check the hashes of all the files, ignoring signatures for now check_config /boot force TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt" + TMP_TREE_FILE="/tmp/kexec/kexec_tree.txt" TMP_PACKAGE_TRIGGER_PRE="/tmp/kexec/kexec_package_trigger_pre.txt" TMP_PACKAGE_TRIGGER_POST="/tmp/kexec/kexec_package_trigger_post.txt" - if ( cd /boot && sha256sum -c "$TMP_HASH_FILE" > /tmp/hash_output ) then + if verify_checksums /boot ; then return 0 - elif [ ! -f $TMP_HASH_FILE ]; then + elif [[ ! -f "$TMP_HASH_FILE" || ! -f "$TMP_TREE_FILE" ]] ; then if (whiptail $BG_COLOR_ERROR --title 'ERROR: Missing Hash File!' \ --yesno "The file containing hashes for /boot is missing!\n\nIf you are setting this system up for the first time, select Yes to update\nyour list of checksums.\n\nOtherwise this could indicate a compromise and you should select No to\nreturn to the main menu.\n\nWould you like to update your checksums now?" 0 80) then if update_checksums ; then diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index ceb0c5e9..a79f2eaa 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -52,7 +52,7 @@ verify_global_hashes() { echo "+++ Checking verified boot hash file " # Check the hashes of all the files - if ( cd $bootdir && sha256sum -c "$TMP_HASH_FILE" > /tmp/hash_output ); then + if verify_checksums "$bootdir" ; then echo "+++ Verified boot hashes " valid_hash='y' valid_global_hash='y' @@ -326,6 +326,7 @@ while true; do TMP_DEFAULT_FILE=`find /tmp/kexec/kexec_default.*.txt 2>/dev/null | head -1` || true TMP_MENU_FILE="/tmp/kexec/kexec_menu.txt" TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt" + TMP_TREE_FILE="/tmp/kexec/kexec_tree.txt" TMP_DEFAULT_HASH_FILE="/tmp/kexec/kexec_default_hashes.txt" TMP_ROLLBACK_FILE="/tmp/kexec/kexec_rollback.txt" TMP_KEY_DEVICES="/tmp/kexec/kexec_key_devices.txt" @@ -385,4 +386,4 @@ while true; do fi done -die "!!! Shouldn't get here"" +die "!!! Shouldn't get here" diff --git a/initrd/bin/kexec-sign-config b/initrd/bin/kexec-sign-config index cb69ef52..a968b160 100755 --- a/initrd/bin/kexec-sign-config +++ b/initrd/bin/kexec-sign-config @@ -27,12 +27,16 @@ confirm_gpg_card if [ "$update" = "y" ]; then ( cd /boot - find ./ -type f ! -name '*kexec*' -print0 | xargs -0 sha256sum > /boot/kexec_hashes.txt + find ./ -type f ! -path './kexec*' -print0 | xargs -0 sha256sum > /boot/kexec_hashes.txt if [ -e /boot/kexec_default_hashes.txt ]; then DEFAULT_FILES=$(cat /boot/kexec_default_hashes.txt | cut -f3 -d ' ') echo $DEFAULT_FILES | xargs sha256sum > /boot/kexec_default_hashes.txt fi + + #also save the file & directory structure to detect added files + print_tree > /boot/kexec_tree.txt ) + [ $? -eq 0 ] || die "$paramsdir: Failed to update hashes." # Remove any package trigger log files # We don't need them after the user decides to sign diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 89459f6d..392a11f5 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -195,9 +195,14 @@ generate_checksums() fi # generate hashes - find /boot -type f ! -name '*kexec*' -print0 \ - | xargs -0 sha256sum > /boot/kexec_hashes.txt 2>/dev/null \ - || whiptail_error_die "Error generating kexec hashes" + ( + set -e -o pipefail + cd /boot + find ./ -type f ! -path './kexec*' -print0 \ + | xargs -0 sha256sum > /boot/kexec_hashes.txt 2>/dev/null + print_tree > /boot/kexec_tree.txt + ) + [ $? -eq 0 ] || whiptail_error_die "Error generating kexec hashes" param_files=`find /boot/kexec*.txt` [ -z "$param_files" ] \ diff --git a/initrd/etc/functions b/initrd/etc/functions index af787213..bb833d65 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -335,6 +335,31 @@ update_checksums() return $rv } +print_tree() { + #use \x0 as long as possible to avoid issues with newlines in file names + find ./ ! -path './kexec*' -print0 | sort -z | xargs -0 printf "%s\n" +} + +verify_checksums() +{ + local boot_dir="$1" + + ( + set +e -o pipefail + local ret=0 + cd "$boot_dir" || ret=1 + sha256sum -c "$TMP_HASH_FILE" > /tmp/hash_output || ret=1 + + # also make sure that the file & directory structure didn't change + # (sha256sum won't detect added files) + print_tree > /tmp/tree_output || ret=1 + diff "$TMP_TREE_FILE" /tmp/tree_output > /tmp/tree_diff || ret=1 + grep -E '^\+[^\+].*$' /tmp/tree_diff | sed -E 's/^\+(.*)/(new) \1/g' >> /tmp/hash_output + exit $ret + ) + return $? +} + # detect and set /boot device # mount /boot if successful detect_boot_device()