From: Mimi Zohar zohar@linux.ibm.com
Instead of assigning the string to a variable, which might contain a null character, redirect the output and grep for the string directly.
Signed-off-by: Mimi Zohar zohar@linux.ibm.com --- tools/testing/selftests/kexec/test_kexec_file_load.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/kexec/test_kexec_file_load.sh b/tools/testing/selftests/kexec/test_kexec_file_load.sh index 2ff600388c30..99f6fc23ee31 100755 --- a/tools/testing/selftests/kexec/test_kexec_file_load.sh +++ b/tools/testing/selftests/kexec/test_kexec_file_load.sh @@ -97,10 +97,11 @@ check_for_imasig() check_for_modsig() { local module_sig_string="~Module signature appended~" - local sig="$(tail --bytes $((${#module_sig_string} + 1)) $KERNEL_IMAGE)" local ret=0
- if [ "$sig" == "$module_sig_string" ]; then + tail --bytes $((${#module_sig_string} + 1)) $KERNEL_IMAGE | \ + grep -q "$module_sig_string" + if [ $? -eq 0 ]; then ret=1 log_info "kexec kernel image modsig signed" else
Existing test cases determine secureboot state using efi variable, which is available only on x86 architecture. Add support for determining secureboot state using device tree property on PowerPC architecture.
Signed-off-by: Nageswara R Sastry rnsastry@linux.ibm.com --- tools/testing/selftests/kexec/Makefile | 2 +- .../selftests/kexec/kexec_common_lib.sh | 38 ++++++++++++++++--- .../selftests/kexec/test_kexec_file_load.sh | 8 +++- 3 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/kexec/Makefile b/tools/testing/selftests/kexec/Makefile index aa91d2063249..806a150648c3 100644 --- a/tools/testing/selftests/kexec/Makefile +++ b/tools/testing/selftests/kexec/Makefile @@ -4,7 +4,7 @@ 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),x86) +ifeq ($(ARCH),$(filter $(ARCH),x86 ppc64le)) TEST_PROGS := test_kexec_load.sh test_kexec_file_load.sh TEST_FILES := kexec_common_lib.sh
diff --git a/tools/testing/selftests/kexec/kexec_common_lib.sh b/tools/testing/selftests/kexec/kexec_common_lib.sh index 43017cfe88f7..e907c3030eb3 100755 --- a/tools/testing/selftests/kexec/kexec_common_lib.sh +++ b/tools/testing/selftests/kexec/kexec_common_lib.sh @@ -91,6 +91,27 @@ get_efi_var_secureboot_mode() return 0; }
+# On powerpc platform, check device-tree property +# /proc/device-tree/ibm,secureboot/os-secureboot-enforcing +# to detect secureboot state. +get_ppc64_secureboot_mode() +{ + local secure_boot_file="/proc/device-tree/ibm,secureboot/os-secureboot-enforcing" + # Check for secure boot file existence + if [ -f $secure_boot_file ]; then + log_info "Secureboot is enabled (Device tree)" + return 1; + fi + log_info "Secureboot is not enabled (Device tree)" + return 0; +} + +# Return the architecture of the system +get_arch() +{ + echo $(arch) +} + # Check efivar SecureBoot-$(the UUID) and SetupMode-$(the UUID). # The secure boot mode can be accessed either as the last integer # of "od -An -t u1 /sys/firmware/efi/efivars/SecureBoot-*" or from @@ -100,14 +121,19 @@ get_efi_var_secureboot_mode() get_secureboot_mode() { local secureboot_mode=0 + local system_arch=$(get_arch)
- get_efivarfs_secureboot_mode - secureboot_mode=$? - - # fallback to using the efi_var files - if [ $secureboot_mode -eq 0 ]; then - get_efi_var_secureboot_mode + if [ "$system_arch" == "ppc64le" ]; then + get_ppc64_secureboot_mode secureboot_mode=$? + else + get_efivarfs_secureboot_mode + secureboot_mode=$? + # fallback to using the efi_var files + if [ $secureboot_mode -eq 0 ]; then + get_efi_var_secureboot_mode + secureboot_mode=$? + fi fi
if [ $secureboot_mode -eq 0 ]; then diff --git a/tools/testing/selftests/kexec/test_kexec_file_load.sh b/tools/testing/selftests/kexec/test_kexec_file_load.sh index 99f6fc23ee31..c9ccb3c93d72 100755 --- a/tools/testing/selftests/kexec/test_kexec_file_load.sh +++ b/tools/testing/selftests/kexec/test_kexec_file_load.sh @@ -226,8 +226,12 @@ get_secureboot_mode secureboot=$?
# Are there pe and ima signatures -check_for_pesig -pe_signed=$? +if [ "$(get_arch)" == 'ppc64le' ]; then + pe_signed=0 +else + check_for_pesig + pe_signed=$? +fi
check_for_imasig ima_signed=$?
Hi Nageswara,
On Wed, 2021-11-24 at 12:38 +0530, Nageswara R Sastry wrote:
Existing test cases determine secureboot state using efi variable, which is available only on x86 architecture. Add support for determining secureboot state using device tree property on PowerPC architecture.
Signed-off-by: Nageswara R Sastry rnsastry@linux.ibm.com
This patch looks fine. I can pick this one up, once I get a Tested-by tag.
thanks,
Mimi
On 11/24/21 02:08, Nageswara R Sastry wrote:
Existing test cases determine secureboot state using efi variable, which is available only on x86 architecture. Add support for determining secureboot state using device tree property on PowerPC architecture.
Please replace 'PowerPC' with 'PowerNV'.
Rest looks good.
Reviewed-by: Nayna Jain nayna@linux.ibm.com
Tested-by: Nayna Jain nayna@linux.ibm.com
Thanks & Regards,
- Nayna
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
diff --git a/tools/testing/selftests/kexec/Makefile b/tools/testing/selftests/kexec/Makefile index 806a150648c3..ac1e998e0158 100644 --- a/tools/testing/selftests/kexec/Makefile +++ b/tools/testing/selftests/kexec/Makefile @@ -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 diff --git a/tools/testing/selftests/kexec/kexec_common_lib.sh b/tools/testing/selftests/kexec/kexec_common_lib.sh index e907c3030eb3..9f9383940a93 100755 --- a/tools/testing/selftests/kexec/kexec_common_lib.sh +++ b/tools/testing/selftests/kexec/kexec_common_lib.sh @@ -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=$? +} diff --git a/tools/testing/selftests/kexec/test_kexec_dbx_bk.sh b/tools/testing/selftests/kexec/test_kexec_dbx_bk.sh new file mode 100755 index 000000000000..212a86be290d --- /dev/null +++ b/tools/testing/selftests/kexec/test_kexec_dbx_bk.sh @@ -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" diff --git a/tools/testing/selftests/kexec/test_kexec_dbx_nbk.sh b/tools/testing/selftests/kexec/test_kexec_dbx_nbk.sh new file mode 100755 index 000000000000..8cd09dd79d01 --- /dev/null +++ b/tools/testing/selftests/kexec/test_kexec_dbx_nbk.sh @@ -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"
linux-kselftest-mirror@lists.linaro.org