kexec-parse-boot: Ensure kernel/initrd paths exist in boot option

If a boot option doesn't refer to a valid file for the kernel/initrd,
ignore it.  Such an option is never bootable, because we would fail to
find the kernel/initrd.  This could happen if the path contained GRUB
variables, or specified a device that wasn't /boot, etc.

This is checked before expanding GRUB variables.  It's unlikely that
any kernel/initrd path containing variables would end up working when
all variables expand to nothing (since we do not handle GRUB
variables).

Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
This commit is contained in:
Jonathon Hall 2022-11-10 10:13:38 -05:00
parent 2a8a7655d3
commit 698360199c
No known key found for this signature in database
GPG Key ID: 1E9C3CA91AE25114

View File

@ -28,15 +28,31 @@ fix_path() {
fi fi
} }
# GRUB kernel lines (linux/multiboot) can include a command line. Check whether
# the file path exists in $bootdir.
check_path() {
local checkpath firstval
checkpath="$1"
firstval="$(echo "$checkpath" | cut -d\ -f1)"
if ! [ -r "$bootdir$firstval" ]; then return 1; fi
return 0
}
echo_entry() { echo_entry() {
if [ "$kexectype" = "elf" ]; then if [ "$kexectype" = "elf" ]; then
if [ -z "$kernel" ]; then return; fi if [ -z "$kernel" ]; then return; fi
fix_path $kernel fix_path $kernel
# The kernel must exist - if it doesn't, ignore this entry, it
# wouldn't work anyway. This could happen if there was a
# GRUB variable in the kernel path, etc.
if ! check_path "$path"; then return; fi
entry="$name|$kexectype|kernel $path" entry="$name|$kexectype|kernel $path"
if [ -n "$initrd" ]; then if [ -n "$initrd" ]; then
for init in $(echo $initrd | tr ',' ' '); do for init in $(echo $initrd | tr ',' ' '); do
fix_path $init fix_path $init
# The initrd must also exist
if ! check_path "$path"; then return; fi
entry="$entry|initrd $path" entry="$entry|initrd $path"
done done
fi fi
@ -44,12 +60,18 @@ echo_entry() {
entry="$entry|append $append" entry="$entry|append $append"
fi fi
# Double-expand here in case there are variables in the kernel
# parameters - some configs do this and can boot with empty
# expansions (Debian Live ISOs use this for loopback boots)
echo $(eval "echo \"$entry\"") echo $(eval "echo \"$entry\"")
fi fi
if [ "$kexectype" = "multiboot" -o "$kexectype" = "xen" ]; then if [ "$kexectype" = "multiboot" -o "$kexectype" = "xen" ]; then
if [ -z "$kernel" ]; then return; fi if [ -z "$kernel" ]; then return; fi
fix_path $kernel fix_path $kernel
# The kernel must exist
if ! check_path "$path"; then return; fi
# Double-expand to clear variable expansions
echo $(eval "echo \"$name|$kexectype|kernel $path$modules\"") echo $(eval "echo \"$name|$kexectype|kernel $path$modules\"")
fi fi
} }