@@ -5,7 +5,8 @@ uname_M := $(shell uname -m 2>/dev/null || echo not)
ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
ifeq ($(ARCH),$(filter $(ARCH),x86 ppc64le))
-TEST_PROGS := test_kexec_load.sh test_kexec_file_load.sh
+TEST_PROGS := test_kexec_load.sh test_kexec_file_load.sh test_kexec_dbx_bk.sh\
+ test_kexec_dbx_nbk.sh
TEST_FILES := kexec_common_lib.sh
include ../lib.mk
@@ -7,6 +7,7 @@ VERBOSE="${VERBOSE:-1}"
IKCONFIG="/tmp/config-`uname -r`"
KERNEL_IMAGE="/boot/vmlinuz-`uname -r`"
SECURITYFS=$(grep "securityfs" /proc/mounts | awk '{print $2}')
+BLACKLIST_BIN_HASH=""
log_info()
{
@@ -244,3 +245,73 @@ check_ima_policy()
[ $? -eq 0 ] && ret=1
return $ret
}
+
+# Look for check_blacklist in IMA Policy
+# Return 1 for found and 0 for not found.
+check_for_ima_policy_blacklist()
+{
+ local ret=0
+
+ check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \
+ "appraise_flag=check_blacklist"
+ ret=$?
+ [ $ret -eq 1 ] && log_info "Found IMA blacklist policy rule"
+
+ return $ret
+}
+
+# Look for blacklist_binary from blacklist keyring
+# Return 1 for found and 0 for not found.
+check_for_dbx_bin()
+{
+ local ret=0
+
+ which keyctl > /dev/null 2>&1 || log_skip "keyctl not found"
+ cmd=$(keyctl show %keyring:.blacklist | grep "blacklist: bin" | wc -l)
+ if [ $cmd -ge 1 ]; then
+ BLACKLIST_BIN_HASH=$(keyctl show %keyring:.blacklist | grep \
+ "blacklist: bin" | cut -d":" -f3)
+ log_info "Found DBX blacklist binary from keyring"
+ ret=1
+ fi
+ return $ret
+}
+
+common_steps_for_dbx()
+{
+ ima_policy=0
+ dbx=0
+ secureboot=0
+
+ # kexec requires root privileges
+ require_root_privileges
+
+ # get the kernel config
+ get_kconfig
+
+ kconfig_enabled "CONFIG_KEXEC_FILE=y" "kexec_file_load is enabled"
+ if [ $? -eq 0 ]; then
+ log_skip "kexec_file_load is not enabled"
+ fi
+
+ kconfig_enabled "CONFIG_SYSTEM_BLACKLIST_KEYRING=y" \
+ "Kernel config blacklist_keyring is enabled"
+ if [ $? -eq 0 ]; then
+ log_skip "Kernel config blacklist_keyring is not enabled"
+ fi
+
+ check_for_ima_policy_blacklist
+ ima_policy=$?
+ if [ $ima_policy -eq 0 ];then
+ log_skip "Not found IMA blacklist policy rule"
+ fi
+
+ check_for_dbx_bin
+ dbx=$?
+ if [ $dbx -eq 0 ]; then
+ log_skip "Not found blacklisted kernel"
+ fi
+
+ get_secureboot_mode
+ secureboot=$?
+}
new file mode 100755
@@ -0,0 +1,90 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Loading a dbx black listed kernel image via the kexec_file_load syscall
+
+. ./kexec_common_lib.sh
+
+TEST="KEXEC_FILE_LOAD_DBX"
+
+# Read KERNEL_DBX_IMAGE from the environment variable
+KERNEL_DBX_IMAGE=$(printenv | grep KERNEL_DBX_IMAGE | cut -d"=" -f2)
+if [ -z $KERNEL_DBX_IMAGE ]; then
+ env_var="KERNEL_DBX_IMAGE"
+ log_skip "$env_var not found, set using 'export $env_var=value'"
+# KERNEL_DBX_IMAGE=$KERNEL_IMAGE
+# log_info "Continuing with booted kernel"
+fi
+
+# Look for kernel matching with blacklisted binary hash
+check_for_blacklist_kernel()
+{
+ local module_sig_string="~Module signature appended~"
+ local ret=0
+
+ tail --bytes $((${#module_sig_string} + 1)) $KERNEL_DBX_IMAGE | \
+ grep -q "$module_sig_string"
+ if [ $? -eq 0 ]; then
+ log_info "Found $KERNEL_DBX_IMAGE with Module signature"
+ # Remove the signature
+ local hash=$(../../../../scripts/extract-module-sig.pl -0\
+ ${KERNEL_DBX_IMAGE} 2> /dev/null | sha256sum -\
+ |awk -F" " '{print $1}')
+ for b_hash in $BLACKLIST_BIN_HASH
+ do
+ # Make sure test is not going to run on booted kernel
+ if [ "$hash" == "$b_hash" -a \
+ "$KERNEL_IMAGE" != "$KERNEL_DBX_IMAGE" ]; then
+ KERNEL_IMAGE=$KERNEL_DBX_IMAGE
+ ret=1
+ fi
+ done
+ fi
+ return $ret
+}
+
+kexec_file_load_dbx_test()
+{
+ local succeed_msg=$1
+ local failed_msg=$2
+
+ line=$(kexec --load --kexec-file-syscall $KERNEL_IMAGE 2>&1)
+
+ if [ $? -eq 0 ]; then
+ kexec --unload --kexec-file-syscall
+
+ # In secureboot mode with an architecture specific
+ # policy, make sure dbx blacklist exists
+ if [ $secureboot -eq 1 ] && [ $dbx -eq 1 ]; then
+ log_fail "$succeed_msg (secureboot and dbx enabled)"
+ # secureboot mode disabled, and dbx blacklist exists
+ elif [ $dbx -eq 1 ]; then
+ log_fail "$succeed_msg (dbx enabled)"
+ fi
+ fi
+
+ # Check the reason for the kexec_file_load failure
+ if (echo $line | grep -q "Permission denied"); then
+ if [ $dbx -eq 1 ]; then
+ log_pass "$failed_msg (Permission denied)"
+ else
+ log_fail "$succeed_msg"
+ fi
+ fi
+
+ return 0
+}
+
+common_steps_for_dbx
+
+check_for_blacklist_kernel
+bk=$?
+
+if [ $bk -eq 0 ]; then
+ log_skip "Not found blacklisted hash matching kernel"
+fi
+
+# Loading the black listed kernel image via kexec_file_load syscall should fail
+succeed_msg="kexec blacklisted kernel image succeeded"
+failed_msg="kexec blacklisted kernel image failed"
+kexec_file_load_dbx_test "$succeed_msg" "$failed_msg"
new file mode 100755
@@ -0,0 +1,62 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Loading a dbx black listed kernel image via the kexec_file_load syscall
+
+. ./kexec_common_lib.sh
+
+TEST="KEXEC_FILE_LOAD_DBX_NB"
+
+# Look for kernel matching with blacklisted binary hash
+check_for_non_blacklist_kernel()
+{
+ local module_sig_string="~Module signature appended~"
+ local ret=0
+
+ tail --bytes $((${#module_sig_string} + 1)) $KERNEL_IMAGE | \
+ grep -q "$module_sig_string"
+ if [ $? -eq 0 ]; then
+ log_info "Found $KERNEL_IMAGE with Module signature"
+ # Remove the signature
+ local hash=$(../../../../scripts/extract-module-sig.pl -0\
+ ${KERNEL_IMAGE} 2> /dev/null | sha256sum -\
+ |awk -F" " '{print $1}')
+ for b_hash in $BLACKLIST_BIN_HASH
+ do
+ if ! [ "$hash" == "$b_hash" ]; then
+ ret=1
+ fi
+ done
+ fi
+ return $ret
+}
+
+kexec_file_load_nbk_test()
+{
+ local succeed_msg=$1
+ local failed_msg=$2
+
+ line=$(kexec --load --kexec-file-syscall $KERNEL_IMAGE 2>&1)
+
+ if [ $? -eq 0 -a $secureboot -eq 1 ]; then
+ kexec --unload --kexec-file-syscall
+ log_pass "$succeed_msg (secureboot enabled)"
+ elif (echo $line | grep -q "Permission denied"); then
+ log_fail "$failed_msg (Permission denied)"
+ fi
+
+}
+
+common_steps_for_dbx
+
+check_for_non_blacklist_kernel
+bk=$?
+
+if [ $bk -eq 0 ]; then
+ log_skip "Found blacklisted hash matching kernel"
+fi
+
+# Loading the black listed kernel image via kexec_file_load syscall should fail
+succeed_msg="kexec non blacklisted kernel image succeeded"
+failed_msg="kexec non blacklisted kernel image failed"
+kexec_file_load_nbk_test "$succeed_msg" "$failed_msg"
Add new tests to verify kexec of blacklisted and non blacklisted kernel based on ima policy and secureboot state. Signed-off-by: Nageswara R Sastry <rnsastry@linux.ibm.com> --- tools/testing/selftests/kexec/Makefile | 3 +- .../selftests/kexec/kexec_common_lib.sh | 71 +++++++++++++++ .../selftests/kexec/test_kexec_dbx_bk.sh | 90 +++++++++++++++++++ .../selftests/kexec/test_kexec_dbx_nbk.sh | 62 +++++++++++++ 4 files changed, 225 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/kexec/test_kexec_dbx_bk.sh create mode 100755 tools/testing/selftests/kexec/test_kexec_dbx_nbk.sh