mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-30 09:48:56 +00:00
4910c1188f
Changes: - As per master: when TOTP cannot unseal TOTP, user is prompted to either reset or regenerate TOTP - Now, when either is done and a previous TPM Disk Unlock Key was setuped, the user is guided into: - Regenerating checksums and signing them - Regenerating TPM disk Unlock Key and resealing TPM disk Unlock Key with passphrase into TPM - LUKS header being modified, user is asked to resign kexec.sig one last time prior of being able to default boot - When no previous Disk Unlock Key was setuped, the user is guided into: - The above, plus - Detection of LUKS containers,suggesting only relevant partitions - Addition of TRACE and DEBUG statements to troubleshoot actual vs expected behavior while coding - Were missing under TPM Disk Unlock Key setup codepaths - Fixes for #645 : We now check if only one slots exists and we do not use it if its slot1. - Also shows in DEBUG traces now Unrelated staged changes - ash_functions: warn and die now contains proper spacing and eye attaction - all warn and die calls modified if containing warnings and too much punctuation - unify usage of term TPM Disk Unlock Key and Disk Recovery Key
180 lines
4.2 KiB
Bash
Executable File
180 lines
4.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# Launches kexec from saved configuration entries
|
|
set -e -o pipefail
|
|
. /tmp/config
|
|
. /etc/functions
|
|
|
|
TRACE "Under /bin/kexec-boot"
|
|
|
|
dryrun="n"
|
|
printfiles="n"
|
|
printinitrd="n"
|
|
while getopts "b:e:r:a:o:fi" arg; do
|
|
case $arg in
|
|
b) bootdir="$OPTARG" ;;
|
|
e) entry="$OPTARG" ;;
|
|
r) cmdremove="$OPTARG" ;;
|
|
a) cmdadd="$OPTARG" ;;
|
|
o) override_initrd="$OPTARG" ;;
|
|
f) dryrun="y"; printfiles="y" ;;
|
|
i) dryrun="y"; printinitrd="y" ;;
|
|
esac
|
|
done
|
|
|
|
if [ -z "$bootdir" -o -z "$entry" ]; then
|
|
die "Usage: $0 -b /boot -e 'kexec params|...|...'"
|
|
fi
|
|
|
|
bootdir="${bootdir%%/}"
|
|
|
|
kexectype=`echo $entry | cut -d\| -f2`
|
|
kexecparams=`echo $entry | cut -d\| -f3- | tr '|' '\n'`
|
|
kexeccmd="kexec"
|
|
|
|
cmdadd="$CONFIG_BOOT_KERNEL_ADD $cmdadd"
|
|
cmdremove="$CONFIG_BOOT_KERNEL_REMOVE $cmdremove"
|
|
|
|
if [ "$(load_config_value CONFIG_USE_BLOB_JAIL)" = "y" ]; then
|
|
cmdadd="$cmdadd firmware_class.path=/run/firmware/"
|
|
fi
|
|
|
|
fix_file_path() {
|
|
if [ "$printfiles" = "y" ]; then
|
|
# output file relative to local boot directory
|
|
echo ".$firstval"
|
|
fi
|
|
|
|
filepath="$bootdir$firstval"
|
|
|
|
if ! [ -r $filepath ]; then
|
|
die "Failed to find file $firstval"
|
|
fi
|
|
}
|
|
|
|
adjusted_cmd_line="n"
|
|
adjust_cmd_line() {
|
|
if [ -n "$cmdremove" ]; then
|
|
for i in $cmdremove; do
|
|
cmdline=$(echo $cmdline | sed "s/\b$i\b//g")
|
|
done
|
|
fi
|
|
|
|
if [ -n "$cmdadd" ]; then
|
|
cmdline="$cmdline $cmdadd"
|
|
fi
|
|
adjusted_cmd_line="y"
|
|
}
|
|
|
|
if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then
|
|
#If expecting debug output, have kexec load (-l) output debug info
|
|
kexeccmd="$kexeccmd -d"
|
|
fi
|
|
|
|
module_number="1"
|
|
while read line
|
|
do
|
|
key=`echo $line | cut -d\ -f1`
|
|
firstval=`echo $line | cut -d\ -f2`
|
|
restval=`echo $line | cut -d\ -f3-`
|
|
if [ "$key" = "kernel" ]; then
|
|
fix_file_path
|
|
if [ "$kexectype" = "xen" ]; then
|
|
# always use xen with custom arguments
|
|
kexeccmd="$kexeccmd -l $filepath"
|
|
kexeccmd="$kexeccmd --command-line \"$restval no-real-mode reboot=no vga=current\""
|
|
elif [ "$kexectype" = "multiboot" ]; then
|
|
kexeccmd="$kexeccmd -l $filepath"
|
|
kexeccmd="$kexeccmd --command-line \"$restval\""
|
|
elif [ "$kexectype" = "elf" ]; then
|
|
DEBUG "kexectype= $kexectype"
|
|
DEBUG "restval= $restval"
|
|
DEBUG "filepath= $filepath"
|
|
kexeccmd="$kexeccmd -l $filepath"
|
|
DEBUG "kexeccmd= $kexeccmd"
|
|
else
|
|
DEBUG "unknown kexectype!!!!"
|
|
kexeccmd="$kexeccmd -l $filepath"
|
|
fi
|
|
fi
|
|
if [ "$key" = "module" ]; then
|
|
fix_file_path
|
|
cmdline="$restval"
|
|
if [ "$kexectype" = "xen" ]; then
|
|
if [ "$module_number" -eq 1 ]; then
|
|
adjust_cmd_line
|
|
elif [ "$module_number" -eq 2 ]; then
|
|
if [ "$printinitrd" = "y" ]; then
|
|
# output the current path to initrd
|
|
echo $filepath
|
|
fi
|
|
if [ -n "$override_initrd" ]; then
|
|
filepath="$override_initrd"
|
|
fi
|
|
fi
|
|
fi
|
|
module_number=`expr $module_number + 1`
|
|
kexeccmd="$kexeccmd --module \"$filepath $cmdline\""
|
|
fi
|
|
if [ "$key" = "initrd" ]; then
|
|
fix_file_path
|
|
if [ "$printinitrd" = "y" ]; then
|
|
# output the current path to initrd
|
|
echo $filepath
|
|
fi
|
|
if [ -n "$override_initrd" ]; then
|
|
filepath="$override_initrd"
|
|
fi
|
|
firmware_initrd="$(inject_firmware.sh "$filepath" || true)"
|
|
if [ -n "$firmware_initrd" ]; then
|
|
filepath="$firmware_initrd"
|
|
fi
|
|
kexeccmd="$kexeccmd --initrd=$filepath"
|
|
fi
|
|
if [ "$key" = "append" ]; then
|
|
cmdline="$firstval $restval"
|
|
adjust_cmd_line
|
|
kexeccmd="$kexeccmd --append=\"$cmdline\""
|
|
fi
|
|
done << EOF
|
|
$kexecparams
|
|
EOF
|
|
|
|
if [ "$adjusted_cmd_line" = "n" ]; then
|
|
if [ "$kexectype" = "elf" ]; then
|
|
kexeccmd="$kexeccmd --append=\"$cmdadd\""
|
|
else
|
|
die "Failed to add required kernel commands: $cmdadd"
|
|
fi
|
|
fi
|
|
|
|
if [ "$dryrun" = "y" ]; then exit 0; fi
|
|
|
|
echo "Loading the new kernel:"
|
|
echo "$kexeccmd"
|
|
eval "$kexeccmd" \
|
|
|| die "Failed to load the new kernel"
|
|
|
|
if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then
|
|
#Repeat kexec command that will be executed since in debug
|
|
DEBUG "kexeccmd= $kexeccmd"
|
|
|
|
#Ask user if they want to continue booting without echoing back the input (-s)
|
|
read -s -n 1 -p "[DEBUG] Continue booting? [Y/n]: " debug_boot_confirm
|
|
echo
|
|
if [ "${debug_boot_confirm^^}" = N ]; then
|
|
# abort
|
|
die "Boot aborted"
|
|
fi
|
|
fi
|
|
|
|
if [ "$CONFIG_TPM" = "y" ]; then
|
|
tpmr kexec_finalize
|
|
fi
|
|
|
|
if [ -x /bin/io386 -a "$CONFIG_FINALIZE_PLATFORM_LOCKING_PRESKYLAKE" = "y" ]; then
|
|
lock_chip
|
|
fi
|
|
|
|
echo "Starting the new kernel"
|
|
exec kexec -e
|