linux-integrity.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: djacobs7@binghamton.edu
To: linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: zohar@linux.ibm.com, pvorel@suse.cz, vt@altlinux.org,
	David Jacobson <djacobs7@binghamton.edu>
Subject: [PATCH v2 4/8] evmtest: test kexec signature policy
Date: Fri, 22 Mar 2019 04:34:37 -0400	[thread overview]
Message-ID: <20190322083441.31084-4-djacobs7@binghamton.edu> (raw)
In-Reply-To: <20190322083441.31084-1-djacobs7@binghamton.edu>

From: David Jacobson <djacobs7@binghamton.edu>

With secure boot enabled, the bootloader verifies the kernel image's
signature before transferring control to it. With Linux as the
bootloader running with secure boot enabled, kexec needs to verify the
kernel image's signature.

This patch defined a new test named "kexec_sig", which first attempts to
kexec an unsigned kernel image with an IMA policy that requires
signatures on any kernel image. Then, the test attempts to kexec the
signed kernel image, which should succeed.

Signed-off-by: David Jacobson <djacobs7@binghamton.edu>

Changelog:
* Added policy_sig to test list
* shellcheck compliant
* move from functions to tests
* suggestions from Mimi
* checkbashisms complaint
* removed begin
* removed long opts
* restructed to use functions
---
 evmtest/README                      |   3 +-
 evmtest/evmtest                     |   1 +
 evmtest/files/policies/kexec_policy |   3 +
 evmtest/tests/kexec_sig.sh          | 167 ++++++++++++++++++++++++++++
 4 files changed, 173 insertions(+), 1 deletion(-)
 create mode 100644 evmtest/files/policies/kexec_policy
 create mode 100755 evmtest/tests/kexec_sig.sh

diff --git a/evmtest/README b/evmtest/README
index 8c63630..91c8cda 100644
--- a/evmtest/README
+++ b/evmtest/README
@@ -39,7 +39,8 @@ TEST NAMES
  env_validate - verify kernel build
  example_test - example test
  policy_sig - verify loading IMA policies
- policy_sig - test IMA-appraise on policies
+ kexec_sig - test IMA-appraise on kexec image loading
+ kmod_sig - test IMA-appraise on kernel module loading
 
 
 Introduction
diff --git a/evmtest/evmtest b/evmtest/evmtest
index 49b162d..cd5e238 100755
--- a/evmtest/evmtest
+++ b/evmtest/evmtest
@@ -28,6 +28,7 @@ usage (){
 	# placement of a script in tests/
 	echo "[R]	env_validate"
 	echo "[ ]	examples_test"
+	echo "[R]	kexec_sig"
 	echo "[R]	kmod_sig"
 	echo "[R]	policy_sig"
 
diff --git a/evmtest/files/policies/kexec_policy b/evmtest/files/policies/kexec_policy
new file mode 100644
index 0000000..dc00fa7
--- /dev/null
+++ b/evmtest/files/policies/kexec_policy
@@ -0,0 +1,3 @@
+appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig
+measure func=KEXEC_KERNEL_CHECK
+audit func=KEXEC_KERNEL_CHECK
diff --git a/evmtest/tests/kexec_sig.sh b/evmtest/tests/kexec_sig.sh
new file mode 100755
index 0000000..3a9459d
--- /dev/null
+++ b/evmtest/tests/kexec_sig.sh
@@ -0,0 +1,167 @@
+#!/bin/bash
+# Author: David Jacobson <davidj@linux.ibm.com>
+TEST="kexec_sig"
+ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.."
+source "$ROOT"/files/common.sh
+VERBOSE=0
+POLICY_LOAD="$ROOT"/files/load_policy.sh
+
+# This test validates that IMA measures and appraises signatures on kernel
+# images when trying to kexec, if the current policy requires that.
+usage() {
+	echo ""
+	echo "kexec_sig -k <key> [-i <kernel_image]"
+	echo "	[-vh]"
+	echo ""
+	echo "	This test must be run as root"
+	echo ""
+	echo "	This test validates that IMA prevents kexec-ing to an"
+	echo "	unsigned kernel image."
+	echo ""
+	echo ""
+	echo "	-k	The key for the certificate on the IMA keyring"
+	echo "	-i	An unsigned kernel image"
+	echo "	-h	Display this help message"
+	echo "	-v	Verbose logging"
+	echo ""
+	echo "	Note: kexec may require PECOFF signature"
+}
+
+parse_args () {
+	TEMP=$(getopt -o 'k:i:hv' -n 'kexec_sig' -- "$@")
+	eval set -- "$TEMP"
+
+	while true ; do
+		case "$1" in
+			-h) usage; exit 0 ; shift;;
+			-i) KERNEL_IMAGE=$2; shift 2;;
+			-k) IMA_KEY=$2; shift 2;;
+			-v) VERBOSE=1; shift;;
+			--) shift; break;;
+			*) echo "[*] Unrecognized option $1"; exit 1;;
+		esac
+	done
+
+	if [ -z "$IMA_KEY" ]; then
+		usage
+		exit 1
+	else
+		if [ ! -e "$IMA_KEY" ]; then
+			fail "Please provide valid keys"
+		fi
+	fi
+}
+
+
+
+# If the user doesn't provide a kernel image for kexec, get the current
+get_image () {
+	if [ -z "$KERNEL_IMAGE" ]; then
+		v_out "No kernel provided, looking for running kernel"
+		RUNNING_KERNEL=$(uname -r)
+		if [ -e /boot/vmlinuz-"$RUNNING_KERNEL" ]; then
+			KERNEL_IMAGE=/boot/vmlinuz-"$RUNNING_KERNEL"
+			TEMP_LOCATION=$(mktemp)
+			v_out "Copying kernel ($KERNEL_IMAGE) to $TEMP_LOCATION"
+			cp "$KERNEL_IMAGE" "$TEMP_LOCATION"
+			KERNEL_IMAGE="$TEMP_LOCATION"
+		fi
+	else
+		if [ ! -e "$KERNEL_IMAGE" ]; then
+			fail "Kernel image not found..."
+		else
+			v_out "Valid Kernel provided, continuing"
+		fi
+	fi
+}
+
+write_hash () {
+	v_out "Writing file hash on kernel image"
+	evmctl ima_hash -a sha256 -f "$KERNEL_IMAGE"
+}
+
+load_policy () {
+	v_out "Attempting to sign policy..."
+	evmctl ima_sign -f "$ROOT"/files/policies/kexec_policy -k "$IMA_KEY"
+
+	v_out "Loading kexec policy..."
+	if ! "$POLICY_LOAD" kexec_policy &>> /dev/null; then
+		fail "Could not update policy - verify keys"
+	fi
+}
+
+check_unsigned_KEXEC_FILE_LOAD () {
+	v_out "Testing loading an unsigned kernel image using KEXEC_FILE_LOAD"\
+		"syscall"
+	# -s uses the kexec_file_load syscall
+	if ! kexec -s -l "$KERNEL_IMAGE" &>> /dev/null; then
+		v_out "Correctly prevented kexec of an unsigned image"
+	else
+		kexec -s -u
+		fail "kexec loaded instead of rejecting. Unloading and exiting."
+	fi
+}
+
+check_unsigned_KEXEC_LOAD () {
+	v_out "Testing loading an unsigned kernel image using KEXEC_LOAD"\
+		"syscall"
+	if kexec -l "$KERNEL_IMAGE" &>> /dev/null; then
+		kexec -u
+		fail "Kexec loaded unsigned image - unloading"
+	else
+		v_out "Correctly prevented kexec of an unsigned image"
+	fi
+}
+
+sign_image () {
+	v_out "Signing kernel image with provided key..."
+	evmctl ima_sign -f "$KERNEL_IMAGE" -k "$IMA_KEY"
+}
+
+check_signed_KEXEC_FILE_LOAD () {
+	v_out "Testing loading a signed kernel image using KEXEC_FILE_LOAD"\
+		"syscall"
+	if ! kexec -s -l "$KERNEL_IMAGE" &>> /dev/null; then
+		fail "kexec rejected a signed image - possibly due to PECOFF"\
+			"signature"
+	else
+		v_out "kexec correctly loaded signed image...unloading"
+	fi
+
+	kexec -s -u
+}
+
+check_signed_KEXEC_LOAD () {
+	v_out "Testing loading a signed kernel image \
+	(without file descriptor) using KEXEC_LOAD syscall"
+
+	if kexec -l "$KERNEL_IMAGE" &>> /dev/null; then
+		kexec -u
+		fail "Signed image was allowed to load without file descriptor"\
+		"for appraisal. Unloading."
+	fi
+
+	v_out "Correctly prevented loading"
+}
+
+cleanup () {
+v_out "Cleaning up..."
+if [ -n "$TEMP_LOCATION" ]; then
+	rm "$TEMP_LOCATION"
+fi
+}
+
+
+EVMTEST_require_root
+echo "[*] Starting test: $TEST"
+parse_args "$@"
+get_image
+write_hash
+load_policy
+check_unsigned_KEXEC_FILE_LOAD
+check_unsigned_KEXEC_LOAD
+sign_image
+check_signed_KEXEC_FILE_LOAD
+check_signed_KEXEC_LOAD
+cleanup
+passed
-- 
2.20.1


  parent reply	other threads:[~2019-03-22  8:35 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-22  8:34 [PATCH v2 1/8] evmtest: Regression testing integrity subsystem djacobs7
2019-03-22  8:34 ` [PATCH v2 2/8] evmtest: test loading IMA policies djacobs7
2019-03-22  8:34 ` [PATCH v2 3/8] evmtest: test kernel module loading djacobs7
2019-03-22  8:34 ` djacobs7 [this message]
2019-03-22  8:34 ` [PATCH v2 5/8] evmtest: validate boot record djacobs7
2019-03-22  8:34 ` [PATCH v2 6/8] evmtest: test the preservation of extended attributes djacobs7
2019-03-22  8:34 ` [PATCH v2 7/8] emvtest: Add ability to run all tests djacobs7
2019-03-22  8:34 ` [PATCH v2 8/8] evmtest: virtual machine compatibility djacobs7
2019-03-22 12:18 ` [PATCH v2 1/8] evmtest: Regression testing integrity subsystem Petr Vorel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190322083441.31084-4-djacobs7@binghamton.edu \
    --to=djacobs7@binghamton.edu \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pvorel@suse.cz \
    --cc=vt@altlinux.org \
    --cc=zohar@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).