2019-03-14 18:44:06

by Mimi Zohar

[permalink] [raw]
Subject: [PATCH v4 0/8] selftests/kexec: add kexec tests

The kernel may be configured or an IMA policy specified on the boot
command line requiring the kexec kernel image signature to be verified.
At runtime a custom IMA policy may be loaded, replacing the policy
specified on the boot command line. In addition, the arch specific
policy rules are dynamically defined based on the secure boot mode that
may require the kernel image signature to be verified.

The kernel image may have a PE signature, an IMA signature, or both. In
addition, there are two kexec syscalls - kexec_load and kexec_file_load
- but only the kexec_file_load syscall can verify signatures.

These kexec selftests verify that only properly signed kernel images are
loaded as required, based on the kernel config, the secure boot mode,
and the IMA runtime policy.

Loading a kernel image or kernel module requires root privileges. To
run just the KEXEC selftests: sudo make TARGETS=kexec kselftest

Changelog v4:
- Moved the kexec tests to selftests/kexec, as requested by Dave Young.
- Removed the kernel module selftest from this patch set.
- Rewritten cover letter, removing reference to kernel modules.

Changelog v3:
- Updated tests based on Petr's review, including the defining a common
test to check for root privileges.
- Modified config, removing the CONFIG_KEXEC_VERIFY_SIG requirement.
- Updated the SPDX license to GPL-2.0 based on Shuah's review.
- Updated the secureboot mode test to check the SetupMode as well, based
on David Young's review.


Mimi Zohar (7):
selftests/kexec: move the IMA kexec_load selftest to selftests/kexec
selftests/kexec: cleanup the kexec selftest
selftests/kexec: define a set of common functions
selftests/kexec: define common logging functions
kselftest/kexec: define "require_root_privileges"
selftests/kexec: kexec_file_load syscall test
selftests/kexec: check kexec_load and kexec_file_load are enabled

Petr Vorel (1):
selftests/kexec: Add missing '=y' to config options

tools/testing/selftests/Makefile | 2 +-
tools/testing/selftests/ima/Makefile | 11 --
tools/testing/selftests/ima/config | 4 -
tools/testing/selftests/ima/test_kexec_load.sh | 54 ------
tools/testing/selftests/kexec/Makefile | 12 ++
tools/testing/selftests/kexec/config | 3 +
tools/testing/selftests/kexec/kexec_common_lib.sh | 175 ++++++++++++++++++
.../selftests/kexec/test_kexec_file_load.sh | 195 +++++++++++++++++++++
tools/testing/selftests/kexec/test_kexec_load.sh | 39 +++++
9 files changed, 425 insertions(+), 70 deletions(-)
delete mode 100644 tools/testing/selftests/ima/Makefile
delete mode 100644 tools/testing/selftests/ima/config
delete mode 100755 tools/testing/selftests/ima/test_kexec_load.sh
create mode 100644 tools/testing/selftests/kexec/Makefile
create mode 100644 tools/testing/selftests/kexec/config
create mode 100755 tools/testing/selftests/kexec/kexec_common_lib.sh
create mode 100755 tools/testing/selftests/kexec/test_kexec_file_load.sh
create mode 100755 tools/testing/selftests/kexec/test_kexec_load.sh

--
2.7.5



2019-03-14 18:43:23

by Mimi Zohar

[permalink] [raw]
Subject: [PATCH v4 8/8] selftests/kexec: check kexec_load and kexec_file_load are enabled

Skip the kexec_load and kexec_file_load tests, if they aren't configured
in the kernel. This change adds a new requirement that ikconfig is
configured in the kexec_load test.

Suggested-by: Dave Young <[email protected]>
Signed-off-by: Mimi Zohar <[email protected]>
---
tools/testing/selftests/kexec/test_kexec_file_load.sh | 5 +++++
tools/testing/selftests/kexec/test_kexec_load.sh | 8 ++++++++
2 files changed, 13 insertions(+)

diff --git a/tools/testing/selftests/kexec/test_kexec_file_load.sh b/tools/testing/selftests/kexec/test_kexec_file_load.sh
index 6cf6a99f6a64..1d2e5e799523 100755
--- a/tools/testing/selftests/kexec/test_kexec_file_load.sh
+++ b/tools/testing/selftests/kexec/test_kexec_file_load.sh
@@ -151,6 +151,11 @@ 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
+
# Determine which kernel config options are enabled
kconfig_enabled "CONFIG_IMA_ARCH_POLICY=y" \
"architecture specific policy enabled"
diff --git a/tools/testing/selftests/kexec/test_kexec_load.sh b/tools/testing/selftests/kexec/test_kexec_load.sh
index afd440ee23cb..2a66c8897f55 100755
--- a/tools/testing/selftests/kexec/test_kexec_load.sh
+++ b/tools/testing/selftests/kexec/test_kexec_load.sh
@@ -10,6 +10,14 @@ TEST="$0"
# kexec requires root privileges
require_root_privileges

+# get the kernel config
+get_kconfig
+
+kconfig_enabled "CONFIG_KEXEC=y" "kexec_load is enabled"
+if [ $? -eq 0 ]; then
+ log_skip "kexec_load is not enabled"
+fi
+
get_secureboot_mode
secureboot=$?

--
2.7.5


2019-03-14 18:43:32

by Mimi Zohar

[permalink] [raw]
Subject: [PATCH v4 6/8] selftests/kexec: kexec_file_load syscall test

The kernel can be configured to verify PE signed kernel images, IMA
kernel image signatures, both types of signatures, or none. This test
verifies only properly signed kernel images are loaded into memory,
based on the kernel configuration and runtime policies.

Signed-off-by: Mimi Zohar <[email protected]>
Reviewed-by: Petr Vorel <[email protected]>
---
tools/testing/selftests/kexec/Makefile | 4 +-
tools/testing/selftests/kexec/kexec_common_lib.sh | 99 +++++++++++
.../selftests/kexec/test_kexec_file_load.sh | 190 +++++++++++++++++++++
tools/testing/selftests/kexec/test_kexec_load.sh | 1 -
4 files changed, 291 insertions(+), 3 deletions(-)
create mode 100755 tools/testing/selftests/kexec/test_kexec_file_load.sh

diff --git a/tools/testing/selftests/kexec/Makefile b/tools/testing/selftests/kexec/Makefile
index 1a795861040b..8e9b27a7452f 100644
--- a/tools/testing/selftests/kexec/Makefile
+++ b/tools/testing/selftests/kexec/Makefile
@@ -1,10 +1,10 @@
-# Makefile for kexec_load
+# Makefile for kexec tests

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)
-TEST_PROGS := test_kexec_load.sh
+TEST_PROGS := test_kexec_load.sh test_kexec_file_load.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 1af892cee726..51ae64c79c41 100755
--- a/tools/testing/selftests/kexec/kexec_common_lib.sh
+++ b/tools/testing/selftests/kexec/kexec_common_lib.sh
@@ -4,6 +4,9 @@
# Kselftest framework defines: ksft_pass=0, ksft_fail=1, ksft_skip=4

VERBOSE="${VERBOSE:-1}"
+IKCONFIG="/tmp/config-`uname -r`"
+KERNEL_IMAGE="/boot/vmlinuz-`uname -r`"
+SECURITYFS=$(grep "securityfs" /proc/mounts | awk '{print $2}')

log_info()
{
@@ -74,3 +77,99 @@ require_root_privileges()
log_skip "requires root privileges"
fi
}
+
+# Look for config option in Kconfig file.
+# Return 1 for found and 0 for not found.
+kconfig_enabled()
+{
+ local config="$1"
+ local msg="$2"
+
+ grep -E -q $config $IKCONFIG
+ if [ $? -eq 0 ]; then
+ log_info "$msg"
+ return 1
+ fi
+ return 0
+}
+
+# Attempt to get the kernel config first via proc, and then by
+# extracting it from the kernel image or the configs.ko using
+# scripts/extract-ikconfig.
+# Return 1 for found.
+get_kconfig()
+{
+ local proc_config="/proc/config.gz"
+ local module_dir="/lib/modules/`uname -r`"
+ local configs_module="$module_dir/kernel/kernel/configs.ko"
+
+ if [ ! -f $proc_config ]; then
+ modprobe configs > /dev/null 2>&1
+ fi
+ if [ -f $proc_config ]; then
+ cat $proc_config | gunzip > $IKCONFIG 2>/dev/null
+ if [ $? -eq 0 ]; then
+ return 1
+ fi
+ fi
+
+ local extract_ikconfig="$module_dir/source/scripts/extract-ikconfig"
+ if [ ! -f $extract_ikconfig ]; then
+ log_skip "extract-ikconfig not found"
+ fi
+
+ $extract_ikconfig $KERNEL_IMAGE > $IKCONFIG 2>/dev/null
+ if [ $? -eq 1 ]; then
+ if [ ! -f $configs_module ]; then
+ log_skip "CONFIG_IKCONFIG not enabled"
+ fi
+ $extract_ikconfig $configs_module > $IKCONFIG
+ if [ $? -eq 1 ]; then
+ log_skip "CONFIG_IKCONFIG not enabled"
+ fi
+ fi
+ return 1
+}
+
+# Make sure that securityfs is mounted
+mount_securityfs()
+{
+ if [ -z $SECURITYFS ]; then
+ SECURITYFS=/sys/kernel/security
+ mount -t securityfs security $SECURITYFS
+ fi
+
+ if [ ! -d "$SECURITYFS" ]; then
+ log_fail "$SECURITYFS :securityfs is not mounted"
+ fi
+}
+
+# The policy rule format is an "action" followed by key-value pairs. This
+# function supports up to two key-value pairs, in any order.
+# For example: action func=<keyword> [appraise_type=<type>]
+# Return 1 for found and 0 for not found.
+check_ima_policy()
+{
+ local action="$1"
+ local keypair1="$2"
+ local keypair2="$3"
+ local ret=0
+
+ mount_securityfs
+
+ local ima_policy=$SECURITYFS/ima/policy
+ if [ ! -e $ima_policy ]; then
+ log_fail "$ima_policy not found"
+ fi
+
+ if [ -n $keypair2 ]; then
+ grep -e "^$action.*$keypair1" "$ima_policy" | \
+ grep -q -e "$keypair2"
+ else
+ grep -q -e "^$action.*$keypair1" "$ima_policy"
+ fi
+
+ # invert "grep -q" result, returning 1 for found.
+ [ $? -eq 0 ] && ret=1
+ return $ret
+}
diff --git a/tools/testing/selftests/kexec/test_kexec_file_load.sh b/tools/testing/selftests/kexec/test_kexec_file_load.sh
new file mode 100755
index 000000000000..6cf6a99f6a64
--- /dev/null
+++ b/tools/testing/selftests/kexec/test_kexec_file_load.sh
@@ -0,0 +1,190 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Loading a kernel image via the kexec_file_load syscall can verify either
+# the IMA signature stored in the security.ima xattr or the PE signature,
+# both signatures depending on the IMA policy, or none.
+#
+# To determine whether the kernel image is signed, this test depends
+# on pesign and getfattr. This test also requires the kernel to be
+# built with CONFIG_IKCONFIG enabled and either CONFIG_IKCONFIG_PROC
+# enabled or access to the extract-ikconfig script.
+
+TEST="KEXEC_FILE_LOAD"
+. ./kexec_common_lib.sh
+
+trap "{ rm -f $IKCONFIG ; }" EXIT
+
+# Some of the IMA builtin policies may require the kexec kernel image to
+# be signed, but these policy rules may be replaced with a custom
+# policy. Only CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS persists after
+# loading a custom policy. Check if it is enabled, before reading the
+# IMA runtime sysfs policy file.
+# Return 1 for IMA signature required and 0 for not required.
+is_ima_sig_required()
+{
+ local ret=0
+
+ kconfig_enabled "CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS=y" \
+ "IMA kernel image signature required"
+ if [ $? -eq 1 ]; then
+ log_info "IMA signature required"
+ return 1
+ fi
+
+ # The architecture specific or a custom policy may require the
+ # kexec kernel image be signed. Policy rules are walked
+ # sequentially. As a result, a policy rule may be defined, but
+ # might not necessarily be used. This test assumes if a policy
+ # rule is specified, that is the intent.
+ if [ $ima_read_policy -eq 1 ]; then
+ check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \
+ "appraise_type=imasig"
+ ret=$?
+ [ $ret -eq 1 ] && log_info "IMA signature required";
+ fi
+ return $ret
+}
+
+# The kexec_file_load_test() is complicated enough, require pesign.
+# Return 1 for PE signature found and 0 for not found.
+check_for_pesig()
+{
+ which pesign > /dev/null 2>&1 || log_skip "pesign not found"
+
+ pesign -i $KERNEL_IMAGE --show-signature | grep -q "No signatures"
+ local ret=$?
+ if [ $ret -eq 1 ]; then
+ log_info "kexec kernel image PE signed"
+ else
+ log_info "kexec kernel image not PE signed"
+ fi
+ return $ret
+}
+
+# The kexec_file_load_test() is complicated enough, require getfattr.
+# Return 1 for IMA signature found and 0 for not found.
+check_for_imasig()
+{
+ local ret=0
+
+ which getfattr > /dev/null 2>&1
+ if [ $? -eq 1 ]; then
+ log_skip "getfattr not found"
+ fi
+
+ line=$(getfattr -n security.ima -e hex --absolute-names $KERNEL_IMAGE 2>&1)
+ echo $line | grep -q "security.ima=0x03"
+ if [ $? -eq 0 ]; then
+ ret=1
+ log_info "kexec kernel image IMA signed"
+ else
+ log_info "kexec kernel image not IMA signed"
+ fi
+ return $ret
+}
+
+kexec_file_load_test()
+{
+ local succeed_msg="kexec_file_load succeeded"
+ local failed_msg="kexec_file_load failed"
+ local key_msg="try enabling the CONFIG_INTEGRITY_PLATFORM_KEYRING"
+
+ 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 either an IMA or PE signature exists.
+ if [ $secureboot -eq 1 ] && [ $arch_policy -eq 1 ] && \
+ [ $ima_signed -eq 0 ] && [ $pe_signed -eq 0 ]; then
+ log_fail "$succeed_msg (missing sig)"
+ fi
+
+ if [ $pe_sig_required -eq 1 ] && [ $pe_signed -eq 0 ]; then
+ log_fail "$succeed_msg (missing PE sig)"
+ fi
+
+ if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ]; then
+ log_fail "$succeed_msg (missing IMA sig)"
+ fi
+
+ if [ $pe_sig_required -eq 0 ] && [ $ima_sig_required -eq 0 ] \
+ && [ $ima_read_policy -eq 0 ] && [ $ima_signed -eq 0 ]; then
+ log_fail "$succeed_msg (possibly missing IMA sig)"
+ fi
+
+ log_pass "$succeed_msg"
+ fi
+
+ # Check the reason for the kexec_file_load failure
+ echo $line | grep -q "Required key not available"
+ if [ $? -eq 0 ]; then
+ if [ $platform_keyring -eq 0 ]; then
+ log_pass "$failed_msg (-ENOKEY), $key_msg"
+ else
+ log_pass "$failed_msg (-ENOKEY)"
+ fi
+ fi
+
+ if [ $pe_sig_required -eq 1 ] && [ $pe_signed -eq 0 ]; then
+ log_pass "$failed_msg (missing PE sig)"
+ fi
+
+ if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ]; then
+ log_pass "$failed_msg (missing IMA sig)"
+ fi
+
+ if [ $pe_sig_required -eq 0 ] && [ $ima_sig_required -eq 0 ] \
+ && [ $ima_read_policy -eq 0 ] && [ $ima_signed -eq 0 ]; then
+ log_pass "$failed_msg (possibly missing IMA sig)"
+ fi
+
+ log_pass "$failed_msg"
+ return 0
+}
+
+# kexec requires root privileges
+require_root_privileges
+
+# get the kernel config
+get_kconfig
+
+# Determine which kernel config options are enabled
+kconfig_enabled "CONFIG_IMA_ARCH_POLICY=y" \
+ "architecture specific policy enabled"
+arch_policy=$?
+
+kconfig_enabled "CONFIG_INTEGRITY_PLATFORM_KEYRING=y" \
+ "platform keyring enabled"
+platform_keyring=$?
+
+kconfig_enabled "CONFIG_IMA_READ_POLICY=y" "reading IMA policy permitted"
+ima_read_policy=$?
+
+kconfig_enabled "CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y" \
+ "PE signed kernel image required"
+pe_sig_required=$?
+
+is_ima_sig_required
+ima_sig_required=$?
+
+get_secureboot_mode
+secureboot=$?
+
+if [ $secureboot -eq 0 ] && [ $arch_policy -eq 0 ] && \
+ [ $pe_sig_required -eq 0 ] && [ $ima_sig_required -eq 0 ] && \
+ [ $ima_read_policy -eq 1 ]; then
+ log_skip "No signature verification required"
+fi
+
+# Are there pe and ima signatures
+check_for_pesig
+pe_signed=$?
+
+check_for_imasig
+ima_signed=$?
+
+# Test loading the kernel image via kexec_file_load syscall
+kexec_file_load_test
diff --git a/tools/testing/selftests/kexec/test_kexec_load.sh b/tools/testing/selftests/kexec/test_kexec_load.sh
index 49545fcdc646..afd440ee23cb 100755
--- a/tools/testing/selftests/kexec/test_kexec_load.sh
+++ b/tools/testing/selftests/kexec/test_kexec_load.sh
@@ -14,7 +14,6 @@ get_secureboot_mode
secureboot=$?

# kexec_load should fail in secure boot mode
-KERNEL_IMAGE="/boot/vmlinuz-`uname -r`"
kexec --load $KERNEL_IMAGE > /dev/null 2>&1
if [ $? -eq 0 ]; then
kexec --unload
--
2.7.5


2019-03-14 18:44:10

by Mimi Zohar

[permalink] [raw]
Subject: [PATCH v4 1/8] selftests/kexec: move the IMA kexec_load selftest to selftests/kexec

As requested move the existing kexec_load selftest and subsequent kexec
tests to the selftests/kexec directory.

Suggested-by: Dave Young <[email protected]>
Signed-off-by: Mimi Zohar <[email protected]>
---
tools/testing/selftests/Makefile | 2 +-
tools/testing/selftests/ima/Makefile | 11 -----
tools/testing/selftests/ima/config | 4 --
tools/testing/selftests/ima/test_kexec_load.sh | 54 ------------------------
tools/testing/selftests/kexec/Makefile | 11 +++++
tools/testing/selftests/kexec/config | 4 ++
tools/testing/selftests/kexec/test_kexec_load.sh | 54 ++++++++++++++++++++++++
7 files changed, 70 insertions(+), 70 deletions(-)
delete mode 100644 tools/testing/selftests/ima/Makefile
delete mode 100644 tools/testing/selftests/ima/config
delete mode 100755 tools/testing/selftests/ima/test_kexec_load.sh
create mode 100644 tools/testing/selftests/kexec/Makefile
create mode 100644 tools/testing/selftests/kexec/config
create mode 100755 tools/testing/selftests/kexec/test_kexec_load.sh

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 1a2bd15c5b6e..6da1e32d2b99 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -14,11 +14,11 @@ TARGETS += firmware
TARGETS += ftrace
TARGETS += futex
TARGETS += gpio
-TARGETS += ima
TARGETS += intel_pstate
TARGETS += ipc
TARGETS += ir
TARGETS += kcmp
+TARGETS += kexec
TARGETS += kvm
TARGETS += lib
TARGETS += membarrier
diff --git a/tools/testing/selftests/ima/Makefile b/tools/testing/selftests/ima/Makefile
deleted file mode 100644
index 0b3adf5444b6..000000000000
--- a/tools/testing/selftests/ima/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# Makefile for kexec_load
-
-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)
-TEST_PROGS := test_kexec_load.sh
-
-include ../lib.mk
-
-endif
diff --git a/tools/testing/selftests/ima/config b/tools/testing/selftests/ima/config
deleted file mode 100644
index 6bc86d4d9bb4..000000000000
--- a/tools/testing/selftests/ima/config
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG_IMA_APPRAISE
-CONFIG_IMA_ARCH_POLICY
-CONFIG_SECURITYFS
-CONFIG_KEXEC_VERIFY_SIG
diff --git a/tools/testing/selftests/ima/test_kexec_load.sh b/tools/testing/selftests/ima/test_kexec_load.sh
deleted file mode 100755
index 1c10093fb526..000000000000
--- a/tools/testing/selftests/ima/test_kexec_load.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0+
-# Loading a kernel image via the kexec_load syscall should fail
-# when the kerne is CONFIG_KEXEC_VERIFY_SIG enabled and the system
-# is booted in secureboot mode.
-
-TEST="$0"
-EFIVARFS="/sys/firmware/efi/efivars"
-rc=0
-
-# Kselftest framework requirement - SKIP code is 4.
-ksft_skip=4
-
-# kexec requires root privileges
-if [ $UID != 0 ]; then
- echo "$TEST: must be run as root" >&2
- exit $ksft_skip
-fi
-
-# Make sure that efivars is mounted in the normal location
-if ! grep -q "^\S\+ $EFIVARFS efivarfs" /proc/mounts; then
- echo "$TEST: efivars is not mounted on $EFIVARFS" >&2
- exit $ksft_skip
-fi
-
-# Get secureboot mode
-file="$EFIVARFS/SecureBoot-*"
-if [ ! -e $file ]; then
- echo "$TEST: unknown secureboot mode" >&2
- exit $ksft_skip
-fi
-secureboot=`hexdump $file | awk '{print substr($4,length($4),1)}'`
-
-# kexec_load should fail in secure boot mode
-KERNEL_IMAGE="/boot/vmlinuz-`uname -r`"
-kexec -l $KERNEL_IMAGE &>> /dev/null
-if [ $? == 0 ]; then
- kexec -u
- if [ "$secureboot" == "1" ]; then
- echo "$TEST: kexec_load succeeded [FAIL]"
- rc=1
- else
- echo "$TEST: kexec_load succeeded [PASS]"
- fi
-else
- if [ "$secureboot" == "1" ]; then
- echo "$TEST: kexec_load failed [PASS]"
- else
- echo "$TEST: kexec_load failed [FAIL]"
- rc=1
- fi
-fi
-
-exit $rc
diff --git a/tools/testing/selftests/kexec/Makefile b/tools/testing/selftests/kexec/Makefile
new file mode 100644
index 000000000000..0b3adf5444b6
--- /dev/null
+++ b/tools/testing/selftests/kexec/Makefile
@@ -0,0 +1,11 @@
+# Makefile for kexec_load
+
+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)
+TEST_PROGS := test_kexec_load.sh
+
+include ../lib.mk
+
+endif
diff --git a/tools/testing/selftests/kexec/config b/tools/testing/selftests/kexec/config
new file mode 100644
index 000000000000..6bc86d4d9bb4
--- /dev/null
+++ b/tools/testing/selftests/kexec/config
@@ -0,0 +1,4 @@
+CONFIG_IMA_APPRAISE
+CONFIG_IMA_ARCH_POLICY
+CONFIG_SECURITYFS
+CONFIG_KEXEC_VERIFY_SIG
diff --git a/tools/testing/selftests/kexec/test_kexec_load.sh b/tools/testing/selftests/kexec/test_kexec_load.sh
new file mode 100755
index 000000000000..1c10093fb526
--- /dev/null
+++ b/tools/testing/selftests/kexec/test_kexec_load.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0+
+# Loading a kernel image via the kexec_load syscall should fail
+# when the kerne is CONFIG_KEXEC_VERIFY_SIG enabled and the system
+# is booted in secureboot mode.
+
+TEST="$0"
+EFIVARFS="/sys/firmware/efi/efivars"
+rc=0
+
+# Kselftest framework requirement - SKIP code is 4.
+ksft_skip=4
+
+# kexec requires root privileges
+if [ $UID != 0 ]; then
+ echo "$TEST: must be run as root" >&2
+ exit $ksft_skip
+fi
+
+# Make sure that efivars is mounted in the normal location
+if ! grep -q "^\S\+ $EFIVARFS efivarfs" /proc/mounts; then
+ echo "$TEST: efivars is not mounted on $EFIVARFS" >&2
+ exit $ksft_skip
+fi
+
+# Get secureboot mode
+file="$EFIVARFS/SecureBoot-*"
+if [ ! -e $file ]; then
+ echo "$TEST: unknown secureboot mode" >&2
+ exit $ksft_skip
+fi
+secureboot=`hexdump $file | awk '{print substr($4,length($4),1)}'`
+
+# kexec_load should fail in secure boot mode
+KERNEL_IMAGE="/boot/vmlinuz-`uname -r`"
+kexec -l $KERNEL_IMAGE &>> /dev/null
+if [ $? == 0 ]; then
+ kexec -u
+ if [ "$secureboot" == "1" ]; then
+ echo "$TEST: kexec_load succeeded [FAIL]"
+ rc=1
+ else
+ echo "$TEST: kexec_load succeeded [PASS]"
+ fi
+else
+ if [ "$secureboot" == "1" ]; then
+ echo "$TEST: kexec_load failed [PASS]"
+ else
+ echo "$TEST: kexec_load failed [FAIL]"
+ rc=1
+ fi
+fi
+
+exit $rc
--
2.7.5


2019-03-14 18:44:16

by Mimi Zohar

[permalink] [raw]
Subject: [PATCH v4 7/8] selftests/kexec: Add missing '=y' to config options

From: Petr Vorel <[email protected]>

so the file can be used as kernel config snippet.

Signed-off-by: Petr Vorel <[email protected]>
[[email protected]: remove CONFIG_KEXEC_VERIFY_SIG from config]
Signed-off-by: Mimi Zohar <[email protected]>
---
tools/testing/selftests/kexec/config | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/kexec/config b/tools/testing/selftests/kexec/config
index 6bc86d4d9bb4..8962e862b2b8 100644
--- a/tools/testing/selftests/kexec/config
+++ b/tools/testing/selftests/kexec/config
@@ -1,4 +1,3 @@
-CONFIG_IMA_APPRAISE
-CONFIG_IMA_ARCH_POLICY
-CONFIG_SECURITYFS
-CONFIG_KEXEC_VERIFY_SIG
+CONFIG_IMA_APPRAISE=y
+CONFIG_IMA_ARCH_POLICY=y
+CONFIG_SECURITYFS=y
--
2.7.5


2019-03-14 18:44:27

by Mimi Zohar

[permalink] [raw]
Subject: [PATCH v4 2/8] selftests/kexec: cleanup the kexec selftest

Remove the few bashisms and use the complete option name for clarity.

Signed-off-by: Mimi Zohar <[email protected]>
Reviewed-by: Petr Vorel <[email protected]>
---
tools/testing/selftests/kexec/test_kexec_load.sh | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/tools/testing/selftests/kexec/test_kexec_load.sh b/tools/testing/selftests/kexec/test_kexec_load.sh
index 1c10093fb526..82a01a4d5c8d 100755
--- a/tools/testing/selftests/kexec/test_kexec_load.sh
+++ b/tools/testing/selftests/kexec/test_kexec_load.sh
@@ -1,7 +1,7 @@
#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0+
+# SPDX-License-Identifier: GPL-2.0
# Loading a kernel image via the kexec_load syscall should fail
-# when the kerne is CONFIG_KEXEC_VERIFY_SIG enabled and the system
+# when the kernel is CONFIG_KEXEC_VERIFY_SIG enabled and the system
# is booted in secureboot mode.

TEST="$0"
@@ -12,8 +12,8 @@ rc=0
ksft_skip=4

# kexec requires root privileges
-if [ $UID != 0 ]; then
- echo "$TEST: must be run as root" >&2
+if [ $(id -ru) -ne 0 ]; then
+ echo "$TEST: requires root privileges" >&2
exit $ksft_skip
fi

@@ -33,17 +33,17 @@ secureboot=`hexdump $file | awk '{print substr($4,length($4),1)}'`

# kexec_load should fail in secure boot mode
KERNEL_IMAGE="/boot/vmlinuz-`uname -r`"
-kexec -l $KERNEL_IMAGE &>> /dev/null
-if [ $? == 0 ]; then
- kexec -u
- if [ "$secureboot" == "1" ]; then
+kexec --load $KERNEL_IMAGE > /dev/null 2>&1
+if [ $? -eq 0 ]; then
+ kexec --unload
+ if [ $secureboot -eq 1 ]; then
echo "$TEST: kexec_load succeeded [FAIL]"
rc=1
else
echo "$TEST: kexec_load succeeded [PASS]"
fi
else
- if [ "$secureboot" == "1" ]; then
+ if [ $secureboot -eq 1 ]; then
echo "$TEST: kexec_load failed [PASS]"
else
echo "$TEST: kexec_load failed [FAIL]"
--
2.7.5


2019-03-14 18:45:06

by Mimi Zohar

[permalink] [raw]
Subject: [PATCH v4 5/8] kselftest/kexec: define "require_root_privileges"

Many tests require root privileges. Define a common function.

Suggested-by: Petr Vorel <[email protected]>
Signed-off-by: Mimi Zohar <[email protected]>
Reviewed-by: Petr Vorel <[email protected]>
---
tools/testing/selftests/kexec/kexec_common_lib.sh | 7 +++++++
tools/testing/selftests/kexec/test_kexec_load.sh | 4 +---
2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kexec/kexec_common_lib.sh b/tools/testing/selftests/kexec/kexec_common_lib.sh
index d108ac538f14..1af892cee726 100755
--- a/tools/testing/selftests/kexec/kexec_common_lib.sh
+++ b/tools/testing/selftests/kexec/kexec_common_lib.sh
@@ -67,3 +67,10 @@ get_secureboot_mode()
log_info "secure boot mode not enabled"
return 0;
}
+
+require_root_privileges()
+{
+ if [ $(id -ru) -ne 0 ]; then
+ log_skip "requires root privileges"
+ fi
+}
diff --git a/tools/testing/selftests/kexec/test_kexec_load.sh b/tools/testing/selftests/kexec/test_kexec_load.sh
index cbf598a380d2..49545fcdc646 100755
--- a/tools/testing/selftests/kexec/test_kexec_load.sh
+++ b/tools/testing/selftests/kexec/test_kexec_load.sh
@@ -8,9 +8,7 @@ TEST="$0"
. ./kexec_common_lib.sh

# kexec requires root privileges
-if [ $(id -ru) -ne 0 ]; then
- log_skip "requires root privileges"
-fi
+require_root_privileges

get_secureboot_mode
secureboot=$?
--
2.7.5


2019-03-14 18:45:12

by Mimi Zohar

[permalink] [raw]
Subject: [PATCH v4 4/8] selftests/kexec: define common logging functions

Define log_info, log_pass, log_fail, and log_skip functions.

Suggested-by: Petr Vorel <[email protected]>
Signed-off-by: Mimi Zohar <[email protected]>
Reviewed-by: Petr Vorel <[email protected]>
---
tools/testing/selftests/kexec/kexec_common_lib.sh | 31 +++++++++++++++++++++++
tools/testing/selftests/kexec/test_kexec_load.sh | 19 ++++----------
2 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/tools/testing/selftests/kexec/kexec_common_lib.sh b/tools/testing/selftests/kexec/kexec_common_lib.sh
index 05376be6a6f7..d108ac538f14 100755
--- a/tools/testing/selftests/kexec/kexec_common_lib.sh
+++ b/tools/testing/selftests/kexec/kexec_common_lib.sh
@@ -1,5 +1,36 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
+#
+# Kselftest framework defines: ksft_pass=0, ksft_fail=1, ksft_skip=4
+
+VERBOSE="${VERBOSE:-1}"
+
+log_info()
+{
+ [ $VERBOSE -ne 0 ] && echo "[INFO] $1"
+}
+
+# The ksefltest framework requirement returns 0 for PASS.
+log_pass()
+{
+
+ [ $VERBOSE -ne 0 ] && echo "$1 [PASS]"
+ exit 0
+}
+
+# The ksefltest framework requirement returns 1 for FAIL.
+log_fail()
+{
+ [ $VERBOSE -ne 0 ] && echo "$1 [FAIL]"
+ exit 1
+}
+
+# The ksefltest framework requirement returns 4 for SKIP.
+log_skip()
+{
+ [ $VERBOSE -ne 0 ] && echo "$1"
+ exit 4
+}

# Check efivar SecureBoot-$(the UUID) and SetupMode-$(the UUID).
# The secure boot mode can be accessed either as the last integer
diff --git a/tools/testing/selftests/kexec/test_kexec_load.sh b/tools/testing/selftests/kexec/test_kexec_load.sh
index 86625c3f1e5d..cbf598a380d2 100755
--- a/tools/testing/selftests/kexec/test_kexec_load.sh
+++ b/tools/testing/selftests/kexec/test_kexec_load.sh
@@ -6,15 +6,10 @@

TEST="$0"
. ./kexec_common_lib.sh
-rc=0
-
-# Kselftest framework requirement - SKIP code is 4.
-ksft_skip=4

# kexec requires root privileges
if [ $(id -ru) -ne 0 ]; then
- echo "$TEST: requires root privileges" >&2
- exit $ksft_skip
+ log_skip "requires root privileges"
fi

get_secureboot_mode
@@ -26,18 +21,14 @@ kexec --load $KERNEL_IMAGE > /dev/null 2>&1
if [ $? -eq 0 ]; then
kexec --unload
if [ $secureboot -eq 1 ]; then
- echo "$TEST: kexec_load succeeded [FAIL]"
- rc=1
+ log_fail "kexec_load succeeded"
else
- echo "$TEST: kexec_load succeeded [PASS]"
+ log_pass "kexec_load succeeded"
fi
else
if [ $secureboot -eq 1 ]; then
- echo "$TEST: kexec_load failed [PASS]"
+ log_pass "kexec_load failed"
else
- echo "$TEST: kexec_load failed [FAIL]"
- rc=1
+ log_fail "kexec_load failed"
fi
fi
-
-exit $rc
--
2.7.5


2019-03-14 18:45:22

by Mimi Zohar

[permalink] [raw]
Subject: [PATCH v4 3/8] selftests/kexec: define a set of common functions

Define, update and move get_secureboot_mode() to a common file for use
by other tests.

Updated to check both the efivar SecureBoot-$(UUID) and
SetupMode-$(UUID), based on Dave Young's review.

Signed-off-by: Mimi Zohar <[email protected]>
Reviewed-by: Petr Vorel <[email protected]>
Cc: Dave Young <[email protected]>
---
tools/testing/selftests/kexec/Makefile | 1 +
tools/testing/selftests/kexec/kexec_common_lib.sh | 38 +++++++++++++++++++++++
tools/testing/selftests/kexec/test_kexec_load.sh | 17 ++--------
3 files changed, 42 insertions(+), 14 deletions(-)
create mode 100755 tools/testing/selftests/kexec/kexec_common_lib.sh

diff --git a/tools/testing/selftests/kexec/Makefile b/tools/testing/selftests/kexec/Makefile
index 0b3adf5444b6..1a795861040b 100644
--- a/tools/testing/selftests/kexec/Makefile
+++ b/tools/testing/selftests/kexec/Makefile
@@ -5,6 +5,7 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)

ifeq ($(ARCH),x86)
TEST_PROGS := test_kexec_load.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
new file mode 100755
index 000000000000..05376be6a6f7
--- /dev/null
+++ b/tools/testing/selftests/kexec/kexec_common_lib.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+# 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
+# "od -An -t u1 /sys/firmware/efi/vars/SecureBoot-*/data". The efi
+# SetupMode can be similarly accessed.
+# Return 1 for SecureBoot mode enabled and SetupMode mode disabled.
+get_secureboot_mode()
+{
+ local efivarfs="/sys/firmware/efi/efivars"
+ local secure_boot_file="$efivarfs/../vars/SecureBoot-*/data"
+ local setup_mode_file="$efivarfs/../vars/SetupMode-*/data"
+ local secureboot_mode=0
+ local setup_mode=0
+
+ # Make sure that efivars is mounted in the normal location
+ if ! grep -q "^\S\+ $efivarfs efivarfs" /proc/mounts; then
+ log_skip "efivars is not mounted on $efivarfs"
+ fi
+
+ # Due to globbing, quoting "secure_boot_file" and "setup_mode_file"
+ # is not possible. (Todo: initialize variables using find or ls.)
+ if [ ! -e $secure_boot_file ] || [ ! -e $setup_mode_file ]; then
+ log_skip "unknown secureboot/setup mode"
+ fi
+
+ secureboot_mode=`od -An -t u1 $secure_boot_file`
+ setup_mode=`od -An -t u1 $setup_mode_file`
+
+ if [ $secureboot_mode -eq 1 ] && [ $setup_mode -eq 0 ]; then
+ log_info "secure boot mode enabled"
+ return 1;
+ fi
+ log_info "secure boot mode not enabled"
+ return 0;
+}
diff --git a/tools/testing/selftests/kexec/test_kexec_load.sh b/tools/testing/selftests/kexec/test_kexec_load.sh
index 82a01a4d5c8d..86625c3f1e5d 100755
--- a/tools/testing/selftests/kexec/test_kexec_load.sh
+++ b/tools/testing/selftests/kexec/test_kexec_load.sh
@@ -5,7 +5,7 @@
# is booted in secureboot mode.

TEST="$0"
-EFIVARFS="/sys/firmware/efi/efivars"
+. ./kexec_common_lib.sh
rc=0

# Kselftest framework requirement - SKIP code is 4.
@@ -17,19 +17,8 @@ if [ $(id -ru) -ne 0 ]; then
exit $ksft_skip
fi

-# Make sure that efivars is mounted in the normal location
-if ! grep -q "^\S\+ $EFIVARFS efivarfs" /proc/mounts; then
- echo "$TEST: efivars is not mounted on $EFIVARFS" >&2
- exit $ksft_skip
-fi
-
-# Get secureboot mode
-file="$EFIVARFS/SecureBoot-*"
-if [ ! -e $file ]; then
- echo "$TEST: unknown secureboot mode" >&2
- exit $ksft_skip
-fi
-secureboot=`hexdump $file | awk '{print substr($4,length($4),1)}'`
+get_secureboot_mode
+secureboot=$?

# kexec_load should fail in secure boot mode
KERNEL_IMAGE="/boot/vmlinuz-`uname -r`"
--
2.7.5


2019-03-15 10:07:11

by Petr Vorel

[permalink] [raw]
Subject: Re: [PATCH v4 0/8] selftests/kexec: add kexec tests

Hi Mimi,

...
> Changelog v4:
> - Moved the kexec tests to selftests/kexec, as requested by Dave Young.
> - Removed the kernel module selftest from this patch set.
> - Rewritten cover letter, removing reference to kernel modules.

LGTM, to whole patch-set:
Reviewed-by: Petr Vorel <[email protected]>

Kind regards,
Petr

2019-03-20 09:05:04

by Dave Young

[permalink] [raw]
Subject: Re: [PATCH v4 0/8] selftests/kexec: add kexec tests

Hi Mimi,

Thank you for help about the pointer about IMA testing.
Probably I should cc list as well since we are talking about the patch
itself. For the ima test itself I could still ask for help in a private
email thread.

On 03/18/19 at 02:09pm, Mimi Zohar wrote:
> On Mon, 2019-03-18 at 22:06 +0800, Dave Young wrote:
> > Hi Mimi,
> >
> > On 03/14/19 at 02:41pm, Mimi Zohar wrote:
> > > The kernel may be configured or an IMA policy specified on the boot
> > > command line requiring the kexec kernel image signature to be verified.
> > > At runtime a custom IMA policy may be loaded, replacing the policy
> > > specified on the boot command line. In addition, the arch specific
> > > policy rules are dynamically defined based on the secure boot mode that
> > > may require the kernel image signature to be verified.
> > >
> > > The kernel image may have a PE signature, an IMA signature, or both. In
> > > addition, there are two kexec syscalls - kexec_load and kexec_file_load
> > > - but only the kexec_file_load syscall can verify signatures.
> > >
> > > These kexec selftests verify that only properly signed kernel images are
> > > loaded as required, based on the kernel config, the secure boot mode,
> > > and the IMA runtime policy.
> > >
> > > Loading a kernel image or kernel module requires root privileges. To
> > > run just the KEXEC selftests: sudo make TARGETS=kexec kselftest
> > >
> > > Changelog v4:
> > > - Moved the kexec tests to selftests/kexec, as requested by Dave Young.
> > > - Removed the kernel module selftest from this patch set.
> > > - Rewritten cover letter, removing reference to kernel modules.
> > >
> > > Changelog v3:
> > > - Updated tests based on Petr's review, including the defining a common
> > > test to check for root privileges.
> > > - Modified config, removing the CONFIG_KEXEC_VERIFY_SIG requirement.
> > > - Updated the SPDX license to GPL-2.0 based on Shuah's review.
> > > - Updated the secureboot mode test to check the SetupMode as well, based
> > > on David Young's review.
> > >
> > >
> > I was trying to review the patches although I'm slow due to something
> > else.
> >
> > But I still did not setup a IMA testable system, need check your old
> > email about how to setup it.
>
> (The ima-evm-utils package contains a README with directions.)
>
> >
> > A quick testing gives me below results
> >
> > /* test #1, my default kconfig
> > # NO CONFIG_INTEGRITY compiled in
> > */
> >
> > make[1]: Nothing to be done for 'all'.
> > make[1]: Leaving directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > make[1]: Entering directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > TAP version 13
> > selftests: kexec: test_kexec_load.sh
> > ========================================
> > selftests: kexec: test_kexec_load.sh: Warning: file
> > test_kexec_load.sh is not executable, correct this.
> > not ok 1..1 selftests: kexec: test_kexec_load.sh [FAIL]
>
> That's really weird. ?Both before and after applying these patches
> test_kexec_load.sh is executable (stable linux-5.0.y). ?Could
> something else be preventing it from executing?
>
> > selftests: kexec: test_kexec_file_load.sh
> > ========================================
> > [INFO] kexec_file_load is enabled
> > [INFO] secure boot mode not enabled
> > [INFO] kexec kernel image PE signed
> > [INFO] kexec kernel image not IMA signed
> > kexec_file_load succeeded (possibly missing IMA sig) [FAIL]
> > not ok 1..2 selftests: kexec: test_kexec_file_load.sh [FAIL]
> > make[1]: Leaving directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > make: Leaving directory '/home/dyoung/git/github/linux/tools/testing/selftests'
>
> This message is because neither CONFIG_KEXEC_BZIMAGE_VERIFY_SIG or an
> IMA signature is required. ?It couldn't read the IMA runtime policy
> rules to determine if an IMA signature is required. ?So, it's trying
> to provide a hint as to what happened.
>
> I'll update the test to see if CONFIG_IMA_APPRAISE is enabled, before
> emitting this message.
>
> >
> > /* test #2, enabled IMA kconfigs, simply test without other ima
> > setup eg. use a policy etc. need to follow up some guide to test the
> > ima functionality (TODO..)
> > */
> >
> >
> > [root@dhcp-128-65 linux-x86]# make -C tools/testing/selftests TARGETS=kexec run_tests
> > make: Entering directory '/home/dyoung/git/github/linux/tools/testing/selftests'
> > make[1]: Entering directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > make[1]: Nothing to be done for 'all'.
> > make[1]: Leaving directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > make[1]: Entering directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > TAP version 13
> > selftests: kexec: test_kexec_load.sh
> > ========================================
> > selftests: kexec: test_kexec_load.sh: Warning: file test_kexec_load.sh is not executable, correct this.
> > not ok 1..1 selftests: kexec: test_kexec_load.sh [FAIL]
> > selftests: kexec: test_kexec_file_load.sh
> > ========================================
> > [INFO] kexec_file_load is enabled
> > [INFO] reading IMA policy permitted
> > [INFO] secure boot mode not enabled
> > No signature verification required
> > not ok 1..2 selftests: kexec: test_kexec_file_load.sh [SKIP]
> > make[1]: Leaving directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > make: Leaving directory '/home/dyoung/git/github/linux/tools/testing/selftests'
>
> The purpose of these tests was to coordinate kernel image signature
> verification.
>
> If you require a PE signature, load an IMA policy requiring an IMA
> signature, or even enable CONFIG_IMA_ARCH_POLICY, the test would
> require some form of signature verification.

Did a test with a embedded ima key in kernel, with secure boot disabled,
but with Secure Boot enabled, but failed to sign the kernel with both
pesign and evmctl, will continue to see how to work on it and ask in
private email if needed :)

About the patch itself, as we talked in another email, I would expect it
can work with other test cases eg. without IMA/secure boot. But if that
is not easy, maybe you can change the test script filename to something
like: test_kexec_load_sigcheck.sh and test_kexec_file_load_sigcheck.sh
then we can add other non-sigcheck related cases to other test scripts
later. But ideally if we can handle them in current files it would be
better.

Another issue I noticed is even if boot with ima_appraise=off, kexec
load still checking the conditions. Will see if I'm having something
wrong in test steps.

Thanks
Dave

2019-03-20 12:05:35

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v4 0/8] selftests/kexec: add kexec tests

On Wed, 2019-03-20 at 17:04 +0800, Dave Young wrote:
> Hi Mimi,
>
> Thank you for help about the pointer about IMA testing.
> Probably I should cc list as well since we are talking about the patch
> itself. For the ima test itself I could still ask for help in a private
> email thread.

Thank you for bringing the discussion back online!

>
> On 03/18/19 at 02:09pm, Mimi Zohar wrote:
> > On Mon, 2019-03-18 at 22:06 +0800, Dave Young wrote:
> > > Hi Mimi,
> > >
> > > On 03/14/19 at 02:41pm, Mimi Zohar wrote:
> > > > The kernel may be configured or an IMA policy specified on the boot
> > > > command line requiring the kexec kernel image signature to be verified.
> > > > At runtime a custom IMA policy may be loaded, replacing the policy
> > > > specified on the boot command line. In addition, the arch specific
> > > > policy rules are dynamically defined based on the secure boot mode that
> > > > may require the kernel image signature to be verified.
> > > >
> > > > The kernel image may have a PE signature, an IMA signature, or both. In
> > > > addition, there are two kexec syscalls - kexec_load and kexec_file_load
> > > > - but only the kexec_file_load syscall can verify signatures.
> > > >
> > > > These kexec selftests verify that only properly signed kernel images are
> > > > loaded as required, based on the kernel config, the secure boot mode,
> > > > and the IMA runtime policy.
> > > >
> > > > Loading a kernel image or kernel module requires root privileges. To
> > > > run just the KEXEC selftests: sudo make TARGETS=kexec kselftest
> > > >
> > > > Changelog v4:
> > > > - Moved the kexec tests to selftests/kexec, as requested by Dave Young.
> > > > - Removed the kernel module selftest from this patch set.
> > > > - Rewritten cover letter, removing reference to kernel modules.
> > > >
> > > > Changelog v3:
> > > > - Updated tests based on Petr's review, including the defining a common
> > > > test to check for root privileges.
> > > > - Modified config, removing the CONFIG_KEXEC_VERIFY_SIG requirement.
> > > > - Updated the SPDX license to GPL-2.0 based on Shuah's review.
> > > > - Updated the secureboot mode test to check the SetupMode as well, based
> > > > on David Young's review.
> > > >
> > > >
> > > I was trying to review the patches although I'm slow due to something
> > > else.
> > >
> > > But I still did not setup a IMA testable system, need check your old
> > > email about how to setup it.
> >
> > (The ima-evm-utils package contains a README with directions.)

Suggesting using the EVM README might not have been the best idea, as
we're only interested, at the moment, in enabling IMA-appraisal for
now.

You need to create 2 public keys - a local CA and an IMA key.  The
local CA public key needs to be loaded onto the builtin trusted keys
keyring.  There are a number of different methods of doing this.  The
simplest method, for those building their own kernel, is to add the
local CA public key to the certs signing_key.x509 (PEM) or to the
x509_certificate_list (DER).

Create the IMA key and then sign the IMA certificate with the local CA
key.  After rebooting the kernel with the local CA key loaded onto the
builtin trusted keyring, you'll be able to import the IMA key onto the
IMA trusted keyring.

To manually load the IMA key, without relying on dracut/systemd:

# id=`sudo keyctl describe %keyring:.ima | awk -F ':' '{print $1}';`
# evmctl import examples/x509_ima.der $id

(The evm utils package contains two sample scripts in the examples
directory to create the local CA and the IMA key.)

> >
> > >
> > > A quick testing gives me below results
> > >
> > > /* test #1, my default kconfig
> > > # NO CONFIG_INTEGRITY compiled in
> > > */
> > >
> > > make[1]: Nothing to be done for 'all'.
> > > make[1]: Leaving directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > > make[1]: Entering directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > > TAP version 13
> > > selftests: kexec: test_kexec_load.sh
> > > ========================================
> > > selftests: kexec: test_kexec_load.sh: Warning: file
> > > test_kexec_load.sh is not executable, correct this.
> > > not ok 1..1 selftests: kexec: test_kexec_load.sh [FAIL]
> >
> > That's really weird.  Both before and after applying these patches
> > test_kexec_load.sh is executable (stable linux-5.0.y).  Could
> > something else be preventing it from executing?
> >
> > > selftests: kexec: test_kexec_file_load.sh
> > > ========================================
> > > [INFO] kexec_file_load is enabled
> > > [INFO] secure boot mode not enabled
> > > [INFO] kexec kernel image PE signed
> > > [INFO] kexec kernel image not IMA signed
> > > kexec_file_load succeeded (possibly missing IMA sig) [FAIL]
> > > not ok 1..2 selftests: kexec: test_kexec_file_load.sh [FAIL]
> > > make[1]: Leaving directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > > make: Leaving directory '/home/dyoung/git/github/linux/tools/testing/selftests'
> >
> > This message is because neither CONFIG_KEXEC_BZIMAGE_VERIFY_SIG or an
> > IMA signature is required.  It couldn't read the IMA runtime policy
> > rules to determine if an IMA signature is required.  So, it's trying
> > to provide a hint as to what happened.
> >
> > I'll update the test to see if CONFIG_IMA_APPRAISE is enabled, before
> > emitting this message.
> >
> > >
> > > /* test #2, enabled IMA kconfigs, simply test without other ima
> > > setup eg. use a policy etc. need to follow up some guide to test the
> > > ima functionality (TODO..)
> > > */
> > >
> > >
> > > [root@dhcp-128-65 linux-x86]# make -C tools/testing/selftests TARGETS=kexec run_tests
> > > make: Entering directory '/home/dyoung/git/github/linux/tools/testing/selftests'
> > > make[1]: Entering directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > > make[1]: Nothing to be done for 'all'.
> > > make[1]: Leaving directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > > make[1]: Entering directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > > TAP version 13
> > > selftests: kexec: test_kexec_load.sh
> > > ========================================
> > > selftests: kexec: test_kexec_load.sh: Warning: file test_kexec_load.sh is not executable, correct this.
> > > not ok 1..1 selftests: kexec: test_kexec_load.sh [FAIL]
> > > selftests: kexec: test_kexec_file_load.sh
> > > ========================================
> > > [INFO] kexec_file_load is enabled
> > > [INFO] reading IMA policy permitted
> > > [INFO] secure boot mode not enabled
> > > No signature verification required
> > > not ok 1..2 selftests: kexec: test_kexec_file_load.sh [SKIP]
> > > make[1]: Leaving directory '/home/dyoung/git/github/linux/tools/testing/selftests/kexec'
> > > make: Leaving directory '/home/dyoung/git/github/linux/tools/testing/selftests'
> >
> > The purpose of these tests was to coordinate kernel image signature
> > verification.
> >
> > If you require a PE signature, load an IMA policy requiring an IMA
> > signature, or even enable CONFIG_IMA_ARCH_POLICY, the test would
> > require some form of signature verification.
>
> Did a test with a embedded ima key in kernel, with secure boot disabled,
> but with Secure Boot enabled, but failed to sign the kernel with both
> pesign and evmctl, will continue to see how to work on it and ask in
> private email if needed :)

"with secure boot disabled, but with Secure Boot enabled" - I'm
missing the nuance between upper and lower case "secure boot".

>
> About the patch itself, as we talked in another email, I would expect it
> can work with other test cases eg. without IMA/secure boot. But if that
> is not easy, maybe you can change the test script filename to something
> like: test_kexec_load_sigcheck.sh and test_kexec_file_load_sigcheck.sh
> then we can add other non-sigcheck related cases to other test scripts
> later. But ideally if we can handle them in current files it would be
> better.

Ok

> Another issue I noticed is even if boot with ima_appraise=off, kexec
> load still checking the conditions. Will see if I'm having something
> wrong in test steps.

Enabling the arch policy disables the "ima_appraise=" boot command
line option.  You're right, if the arch policy isn't enabled, this
test needs to detect the "ima_appraise" mode.

Mimi