From 6a20bd54473e11011bf2b47efb52d0759d412854 Mon Sep 17 00:00:00 2001 From: Lianbo Jiang Date: Thu, 16 Jan 2020 13:47:35 +0800 Subject: [PATCH] kdump-lib: switch to the kexec_file_load() syscall on x86_64 by default UEFI Secure boot is a signature verification mechanism, designed to prevent malicious code being loaded and executed at the early boot stage. This makes sure that code executed is trusted by firmware. Previously, with kexec_file_load() interface, kernel prevents unsigned kernel image from being loaded if secure boot is enabled. So kdump will detect whether secure boot is enabled firstly, then decide which interface is chosen to execute, kexec_load() or kexec_file_load(). Otherwise unsigned kernel loading will fail if secure boot enabled, and kexec_file_load() is entered. Now, the implementation of kexec_file_load() is adjusted in below commit. With this change, if CONFIG_KEXEC_SIG_FORCE is not set, unsigned kernel still has a chance to be allowed to load under some conditions. commit 99d5cadfde2b ("kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE") And in the current Fedora, the CONFIG_KEXEC_SIG_FORCE is not set, only the CONFIG_KEXEC_SIG and CONFIG_BZIMAGE_VERIFY_SIG are set on x86_64 by default. It's time to spread kexec_file_load() onto all systems of x86_64, including Secure-boot platforms and legacy platforms. Please refer to the following form. .----------------------------------------------------------------------. | . | signed kernel | unsigned kernel | | . types |-----------------------|-----------------------| | . |Secure boot| Legacy |Secure boot| Legacy | | . |-----------|-----------|-----------|-----------| | options . | prev| now | prev| now | | | prev| now | | . |(file|(file|(only|(file| prev| now |(only|(file| | . |load)|load)|load)|load)| | |load)|load)| |----------------------|-----|-----|-----|-----|-----|-----|-----|-----| |KEXEC_SIG=y | | | | | | | | | |SIG_FORCE is not set |succ |succ |succ |succ | X | X |succ |succ | |BZIMAGE_VERIFY_SIG=y | | | | | | | | | |----------------------|-----|-----|-----|-----|-----|-----|-----|-----| |KEXEC_SIG=y | | | | | | | | | |SIG_FORCE is not set | | | | | | | | | |BZIMAGE_VERIFY_SIG is |fail |fail |succ |fail | X | X |succ |fail | |not set | | | | | | | | | |----------------------|-----|-----|-----|-----|-----|-----|-----|-----| |KEXEC_SIG=y | | | | | | | | | |SIG_FORCE=y |succ |succ |succ |fail | X | X |succ |fail | |BZIMAGE_VERIFY_SIG=y | | | | | | | | | |----------------------|-----|-----|-----|-----|-----|-----|-----|-----| |KEXEC_SIG=y | | | | | | | | | |SIG_FORCE=y | | | | | | | | | |BZIMAGE_VERIFY_SIG is |fail |fail |succ |fail | X | X |succ |fail | |not set | | | | | | | | | |----------------------|-----|-----|-----|-----|-----|-----|-----|-----| |KEXEC_SIG is not set | | | | | | | | | |SIG_FORCE is not set | | | | | | | | | |BZIMAGE_VERIFY_SIG is |fail |fail |succ |succ | X | X |succ |succ | |not set | | | | | | | | | ---------------------------------------------------------------------- Note: [1] The 'X' indicates that the 1st kernel(unsigned) can not boot when the Secure boot is enabled. Hence, in this patch, if on x86_64, let's use the kexec_file_load() only. See if anything wrong happened in this case, in Fedora firstly for the time being. Signed-off-by: Lianbo Jiang Acked-by: Kairui Song --- dracut-early-kdump.sh | 5 +++-- kdump-lib.sh | 29 ----------------------------- kdump.sysconfig.x86_64 | 6 ++++++ kdumpctl | 13 +++++++------ 4 files changed, 16 insertions(+), 37 deletions(-) diff --git a/dracut-early-kdump.sh b/dracut-early-kdump.sh index 69a34eb..6788a6b 100755 --- a/dracut-early-kdump.sh +++ b/dracut-early-kdump.sh @@ -2,6 +2,7 @@ KEXEC=/sbin/kexec standard_kexec_args="-p" +KDUMP_FILE_LOAD="" EARLY_KDUMP_INITRD="" EARLY_KDUMP_KERNEL="" @@ -43,8 +44,8 @@ early_kdump_load() EARLY_KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}") - if is_secure_boot_enforced; then - echo "Secure Boot is enabled. Using kexec file based syscall." + if [ "$KDUMP_FILE_LOAD" == "on" ]; then + echo "Using kexec file based syscall." EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS -s" fi diff --git a/kdump-lib.sh b/kdump-lib.sh index 8aad556..2428b5d 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -596,35 +596,6 @@ need_64bit_headers() print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'` } -# Check if secure boot is being enforced. -# -# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and -# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four -# bytes are the attributes associated with the variable and can safely be -# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot -# is 1 and SetupMode is 0, then secure boot is being enforced. -# -# Assume efivars is mounted at /sys/firmware/efi/efivars. -is_secure_boot_enforced() -{ - local secure_boot_file setup_mode_file - local secure_boot_byte setup_mode_byte - - secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null) - setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null) - - if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then - secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5) - setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5) - - if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then - return 0 - fi - fi - - return 1 -} - # # prepare_kexec_args # This function prepares kexec argument. diff --git a/kdump.sysconfig.x86_64 b/kdump.sysconfig.x86_64 index 09de2eb..a43a970 100644 --- a/kdump.sysconfig.x86_64 +++ b/kdump.sysconfig.x86_64 @@ -38,3 +38,9 @@ KDUMP_IMG="vmlinuz" #What is the images extension. Relocatable kernels don't have one KDUMP_IMG_EXT="" + +# Using kexec file based syscall by default +# +# Here, the "on" is the only valid value to enable the kexec file load and +# anything else is equal to the "off"(disable). +KDUMP_FILE_LOAD="on" diff --git a/kdumpctl b/kdumpctl index 2d21a41..97fe541 100755 --- a/kdumpctl +++ b/kdumpctl @@ -4,6 +4,7 @@ KEXEC=/sbin/kexec KDUMP_KERNELVER="" KDUMP_COMMANDLINE="" KEXEC_ARGS="" +KDUMP_FILE_LOAD="" KDUMP_CONFIG_FILE="/etc/kdump.conf" MKDUMPRD="/sbin/mkdumprd -f" DRACUT_MODULES_FILE="/usr/lib/dracut/modules.txt" @@ -678,11 +679,8 @@ load_kdump() KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}") KDUMP_COMMANDLINE=$(prepare_cmdline "${KDUMP_COMMANDLINE}" "${KDUMP_COMMANDLINE_REMOVE}" "${KDUMP_COMMANDLINE_APPEND}") - # For secureboot enabled machines, use new kexec file based syscall. - # Old syscall will always fail as it does not have capability to - # to kernel signature verification. - if is_secure_boot_enforced; then - echo "Secure Boot is enabled. Using kexec file based syscall." + if [ "$KDUMP_FILE_LOAD" == "on" ]; then + echo "Using kexec file based syscall." KEXEC_ARGS="$KEXEC_ARGS -s" fi @@ -694,6 +692,9 @@ load_kdump() return 0 else echo "kexec: failed to load kdump kernel" >&2 + if [ "$KDUMP_FILE_LOAD" == "on" ]; then + echo "kexec_file_load() failed, please try kexec_load()" >&2 + fi return 1 fi } @@ -1162,7 +1163,7 @@ stop_fadump() stop_kdump() { - if is_secure_boot_enforced; then + if [ "$KDUMP_FILE_LOAD" == "on" ]; then $KEXEC -s -p -u else $KEXEC -p -u