Skip to contentSkip to conversation

evmtest: Regression testing Integrity Subsystem

PATCH In review David Jacobson 3 participants 9 messages Aug 14, 2018 – Aug 22, 2018

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/7 evmtest: Regression testing Integrity Subsystem

As the existing IMA/EVM features of the kernel mature, and new features are being added, the number of kernel configuration options (Kconfig) and methods for loading policies have been increasing. Rigorous testing of the various IMA/EVM features is needed to ensure correct behavior and to help avoid regressions.

Currently, only IMA-measurement can be tested (via LTP), a feature introduced in Linux 2.6.30. Since then, IMA has grown to support IMA-appraisal and IMA-audit. There are no LTP modules to test either of these features.

This patchset introduces evmtest — a stand alone tool for regression testing IMA. evmtest can be used to validate individual behaviors by exercising execve, kexec, module load, and other LSM hooks. evmtest uses a combination of invalid signatures, invalid hashes, and unsigned files to check that IMA-Appraisal catches all cases a running policy has set. evmtest can also be used to validate that the kernel is properly configured. For example, there are a number of Kconfig options that need to be set, in addition to a local CA certificate being built-in or memory reserved for embedding the certificate post-build. evmtest output is consistent. Consistent output allows evmtest to be plugged into a testing framework/harness. Testing frameworks (such as xfstests) require deterministic output. XFStests runs a test and compares its output to a predefined value, created by running the test script under conditions where it passes. evmtest provides output that can easily be integrated with xfstests. All tests have a verbose mode (-v) that outputs more information for debugging purposes.

New tests can be defined by placing them in the functions/ directory. An "example_test.sh" script is provided for reference.

Example 1:
Successful example test output

$ evmtest runtest example_test -e /bin/bash
[*] Starting test: example_test
[*] TEST: PASSED

Example 1a: successful verbose example test output

$ evmtest runtest example_test -e /bin/bash -v
[*] Starting test: example_test
[*] Example file exists
[*] TEST: PASSED

Example 1b: failed verbose example test output

$ evmtest runtest example_test -e /bin/foo -v
[*] Starting test: example_test
[!] Example file does not exist
[!] TEST: FAILED

SYNOPSIS:
evmtest [runtest|help] test_name [test options]
options:
-h,--help Displays a help message
-v,--verbose Verbose logging for debugging

---
 Makefile.am                         |   5 +-
 configure.ac                        |   1 +
 evmtest/INSTALL                     |  11 ++
 evmtest/Makefile.am                 |  23 ++++
 evmtest/README                      | 190 ++++++++++++++++++++++++++
 evmtest/evmtest                     |  74 ++++++++++
 evmtest/files/common.sh             |  49 +++++++
 evmtest/files/load_policy.sh        |  38 ++++++
 evmtest/functions/example_test.sh   |  75 ++++++++++
 evmtest/functions/r_env_validate.sh | 205 ++++++++++++++++++++++++++++
 10 files changed, 670 insertions(+), 1 deletion(-)
 create mode 100644 evmtest/INSTALL
 create mode 100644 evmtest/Makefile.am
 create mode 100644 evmtest/README
 create mode 100755 evmtest/evmtest
 create mode 100755 evmtest/files/common.sh
 create mode 100755 evmtest/files/load_policy.sh
 create mode 100755 evmtest/functions/example_test.sh
 create mode 100755 evmtest/functions/r_env_validate.sh
Makefile.am +4 -1
index dba408d..0cb4111 100644
@@ -36,4 +36,7 @@ rmman:
 
 doc: evmctl.1.html rmman evmctl.1
 
-.PHONY: $(tarname)
+evmtest:
+	$(MAKE) -C evmtest
+
+.PHONY: $(tarname) evmtest
configure.ac +1 -0
index a5b4288..59ec1d1 100644
@@ -52,6 +52,7 @@ EVMCTL_MANPAGE_DOCBOOK_XSL
 AC_CONFIG_FILES([Makefile
 		src/Makefile
 		packaging/ima-evm-utils.spec
+		evmtest/Makefile
 		])
 AC_OUTPUT
 
evmtest/INSTALL new file +11 -0
new file mode 100644
index 0000000..699853e
@@ -0,0 +1,11 @@
+Installation Instructions
+-------------------------
+
+Basic Installation
+------------------
+
+From the root directory of ima-evm-utils, run the commands: `./autogen.sh`
+followed by `./configure`. `cd` to evmtest directory, execute `make`, and
+`sudo make install`.
+For details on how to use `evmtest` See the installed manpage or the README.
+There is an evmtest.html provided as well.
evmtest/Makefile.am new file +23 -0
new file mode 100644
index 0000000..388ead1
@@ -0,0 +1,23 @@
+prefix=@prefix@
+datarootdir=@datarootdir@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+
+all: evmtest.1
+
+evmtest.1:
+	asciidoc -d manpage -b docbook -o evmtest.1.xsl README
+	asciidoc INSTALL
+	xsltproc --nonet -o $@ $(MANPAGE_DOCBOOK_XSL) evmtest.1.xsl
+	asciidoc -o evmtest.html README
+	rm -f evmtest.1.xsl
+install:
+	install -m 755 evmtest $(bindir)
+	install -d $(datarootdir)/evmtest/files/
+	install -d $(datarootdir)/evmtest/functions/
+	install -D $$(find ./files/ -not -type d)  $(datarootdir)/evmtest/files/
+	install -D ./functions/* $(datarootdir)/evmtest/functions/
+	cp evmtest.1 $(datarootdir)/man/man1
+	mandb -q
+
+.PHONY: install evmtest.1
evmtest/README new file +190 -0

190 lines not on this page · raw message

evmtest/evmtest new file +74 -0

74 lines not on this page · raw message

evmtest/files/common.sh new file +49 -0

49 lines not on this page · raw message

evmtest/files/load_policy.sh new file +38 -0
new file mode 100755
index 0000000..e22ea21
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.."
+source $ROOT/files/common.sh
+EVMTEST_require_root
+
+#This script loads the IMA policy either by replacing the builtin
+#policies specified on the boot command line or by appending the policy
+#rules to the existing custom policy.
+
+# This program assumes that the running kernel has been compiled with
+# CONFIG_IMA_WRITE_POLICY=y
+# To validate this, run env_validate <path_to_kernel_build>
+# Otherwise, this will fail
+
+if [[ "$#" !=  1 || "$1" == "-h" ]]; then
+	echo "load_policy - load an IMA policy."
+	echo "Usage: load_pol <policy pathname>"
+	exit
+fi
+
+IMA_POLICY_LOCATION=$EVMTEST_SECFS/ima/policy
+EVMTEST_POLICY_LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" \
+	>/dev/null && pwd )/policies"
+if [[ ! -e $EVMTEST_POLICY_LOCATION/$1 ]]; then
+	echo "[!] Policy: $1 not found, ensure it is in files/policies"
+	exit 1
+fi
+TO_LOAD=$EVMTEST_POLICY_LOCATION/$1
+echo $TO_LOAD > $IMA_POLICY_LOCATION
+if [[ $? != 0 ]]; then
+	echo "[!] Load failed - see dmesg"
+	exit 1
+else
+	echo "[*] Policy update completed"
+fi
+
+exit 0
evmtest/functions/example_test.sh new file +75 -0

75 lines not on this page · raw message

evmtest/functions/r_env_validate.sh new file +205 -0

205 lines not on this page · raw message

Signature · 1 line
2.17.1
#1 lore raw

PATCH 2/7 evmtest: test appraisal on policy loading with signature

IMA can be configured to require signatures on policies before loading them. This test verifies that IMA correctly validates signatures, and rejects policies that lack signatures or have been signed by an unauthorized party (i.e. certificate is not on the appropriate keyring).

This test requires root privileges in order to write to securityfs files.

---
 evmtest/Makefile.am                          |  4 +-
 evmtest/files/Notes                          | 25 ++++++
 evmtest/files/bad_privkey_ima.pem            | 16 ++++
 evmtest/files/policies/signed_policy         |  2 +
 evmtest/files/policies/unknown_signed_policy |  1 +
 evmtest/files/policies/unsigned_policy       |  1 +
 evmtest/functions/r_policy_sig.sh            | 93 ++++++++++++++++++++
 7 files changed, 141 insertions(+), 1 deletion(-)
 create mode 100644 evmtest/files/Notes
 create mode 100644 evmtest/files/bad_privkey_ima.pem
 create mode 100644 evmtest/files/policies/signed_policy
 create mode 100644 evmtest/files/policies/unknown_signed_policy
 create mode 100644 evmtest/files/policies/unsigned_policy
 create mode 100755 evmtest/functions/r_policy_sig.sh
evmtest/Makefile.am +3 -1
index 388ead1..b537e78 100644
@@ -14,9 +14,11 @@ evmtest.1:
 install:
 	install -m 755 evmtest $(bindir)
 	install -d $(datarootdir)/evmtest/files/
+	install -d $(datarootdir)/evmtest/files/policies
 	install -d $(datarootdir)/evmtest/functions/
-	install -D $$(find ./files/ -not -type d)  $(datarootdir)/evmtest/files/
+	install -D $$(find ./files/ -not -type d -not -path "./files/policies/*")  $(datarootdir)/evmtest/files/
 	install -D ./functions/* $(datarootdir)/evmtest/functions/
+	install -D ./files/policies/* $(datarootdir)/evmtest/files/policies/
 	cp evmtest.1 $(datarootdir)/man/man1
 	mandb -q
 
evmtest/files/Notes new file +25 -0
new file mode 100644
index 0000000..6b75263
@@ -0,0 +1,25 @@
+This file contains a description of the contents of this directory.
+
+1. bad_privkey_ima.pem
+
+This file was generated such that its corresponding public key could be placed
+on the IMA Trusted Keyring, however, it has not. Therefore, any policy (or file)
+signed by this key cannot be verified, and is untrusted.
+
+2. basic_mod.ko
+
+This is a kernel module that logs (to dmesg) the syscall that was used to load
+it.
+
+3. common.sh
+
+This file contains useful functions and variables for evmtest scripts.
+
+4. load_policy.sh
+
+This is a script to load policies. The first time this is called, it will
+replace the existing policy. Subsequent calls will append the running policy.
+
+5. policies/
+
+This is a directory that contains IMA policies with self explanatory names.
evmtest/files/bad_privkey_ima.pem new file +16 -0
new file mode 100644
index 0000000..dcc0e24
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMOnki6OKMHExpH1
+IWgUlPWWSbsDpW1lpqXMj0/ZWo9xU5W2xZC53TVArUGOImQ5PcMNkw1VcHhKbFKO
+jYT0gEE0Sv+VbePiEnhUheFOWUxNNFE3DVQaOpBN0OzsUCSGX9RKIIwkIAwJkvWA
+MHzR4ZPQGGM9hMJKhEvlTG4PP96LAgMBAAECgYBKVKVCrptpUhqmZNx2MCuPSbNl
+KzNz5kRzhM2FZmvzRvicTj2siBA0JQgteZQzQ1PlgIi3bhg2ev/ANYwqUMFQWZv9
+zm5d4P7Zsdyle15MDTSrQIaroeb1nbfNvaB0L4D4Inv0p6ksyIFp7TR5MLVenC5k
+bxfESVWVPDseiAFKUQJBAPQ/x3LmnT0RiMeX6quCGAON7DGpV5KFwL97luWO6vH+
+qZ2W1/J0UxTbruv7rA+tj3ZXpdNOxfmq+JStY0jrJV0CQQDNEUqomnA183rX0dv8
+MWyOPmX0Z9SMSTRvflNRW85Bzbosq68uLTq3qOBj+td9zUlopsLpJlfF0Vc+moff
+uq0HAkEAi/Sz47oTZXfTqZL6TBZ6jibXrck8PeBYhyBZYebX55ymMn/J88sGBFCx
+VdVbTYyFRSmKAqADv0FhuUf1OUZMnQJAOayjUsgcxw+zfP+I32UHIvppslOBc/Mi
+zDi7Niab2+YAdo/StSoDWaQld/kUok0aWFSOfQRLq1c1MmZD0KiwAQJANY0LopqG
+pxACc4/QawxtBoV1a8j5Zui8LZPRtKwjkA30Nq8fOufzMuBeJIlLap45uD1xC7St
+bsPWG5+uz18e5w==
+-----END PRIVATE KEY-----
evmtest/files/policies/signed_policy new file +2 -0
new file mode 100644
index 0000000..87828f0
@@ -0,0 +1,2 @@
+measure func=POLICY_CHECK
+appraise func=POLICY_CHECK appraise_type=imasig
evmtest/files/policies/unknown_signed_policy new file +1 -0
new file mode 100644
index 0000000..1f8f8f4
@@ -0,0 +1 @@
+audit func=POLICY_CHECK
evmtest/files/policies/unsigned_policy new file +1 -0
new file mode 100644
index 0000000..1f8f8f4
@@ -0,0 +1 @@
+audit func=POLICY_CHECK
evmtest/functions/r_policy_sig.sh new file +93 -0

93 lines not on this page · raw message

Signature · 1 line
2.17.1
#2 lore raw

PATCH 3/7 evmtest: test kernel module loading

In reply to David Jacobson

The Linux kernel supports two methods of loading kernel modules - init_module and finit_module syscalls. This test verifies loading kernel modules with both syscalls, first without an IMA policy, and subsequently with an IMA policy (that restricts module loading to signed modules).

This test requires the kernel to be configured with the "CONFIG_MODULE_SIG" option, but not with "CONFIG_MODULE_SIG_FORCE". For this reason, the test requires that "module.sig_enforce=1" is supplied as a boot option to the kernel.

Changelog:

---
 evmtest/Makefile.am                         |  11 +-
 evmtest/files/policies/kernel_module_policy |   2 +
 evmtest/functions/r_kmod_sig.sh             | 225 ++++++++++++++++++++
 evmtest/src/Makefile                        |   5 +
 evmtest/src/basic_mod.c                     |  36 ++++
 evmtest/src/kern_mod_loader.c               | 131 ++++++++++++
 6 files changed, 407 insertions(+), 3 deletions(-)
 create mode 100644 evmtest/files/policies/kernel_module_policy
 create mode 100755 evmtest/functions/r_kmod_sig.sh
 create mode 100644 evmtest/src/Makefile
 create mode 100644 evmtest/src/basic_mod.c
 create mode 100644 evmtest/src/kern_mod_loader.c
evmtest/Makefile.am +8 -3
index b537e78..6be0596 100644
@@ -3,7 +3,7 @@ datarootdir=@datarootdir@
 exec_prefix=@exec_prefix@
 bindir=@bindir@
 
-all: evmtest.1
+all: src evmtest.1
 
 evmtest.1:
 	asciidoc -d manpage -b docbook -o evmtest.1.xsl README
@@ -11,7 +11,10 @@ evmtest.1:
 	xsltproc --nonet -o $@ $(MANPAGE_DOCBOOK_XSL) evmtest.1.xsl
 	asciidoc -o evmtest.html README
 	rm -f evmtest.1.xsl
-install:
+src:
+	cd src && make
+
+install: src
 	install -m 755 evmtest $(bindir)
 	install -d $(datarootdir)/evmtest/files/
 	install -d $(datarootdir)/evmtest/files/policies
@@ -19,7 +22,9 @@ install:
 	install -D $$(find ./files/ -not -type d -not -path "./files/policies/*")  $(datarootdir)/evmtest/files/
 	install -D ./functions/* $(datarootdir)/evmtest/functions/
 	install -D ./files/policies/* $(datarootdir)/evmtest/files/policies/
+	cp ./src/basic_mod.ko $(datarootdir)/evmtest/files/
+	cp ./src/kern_mod_loader $(datarootdir)/evmtest/files
 	cp evmtest.1 $(datarootdir)/man/man1
 	mandb -q
 
-.PHONY: install evmtest.1
+.PHONY: src install evmtest.1
evmtest/files/policies/kernel_module_policy new file +2 -0
new file mode 100644
index 0000000..8096e18
@@ -0,0 +1,2 @@
+measure func=MODULE_CHECK
+appraise func=MODULE_CHECK appraise_type=imasig
evmtest/functions/r_kmod_sig.sh new file +225 -0

225 lines not on this page · raw message

evmtest/src/Makefile new file +5 -0
new file mode 100644
index 0000000..4c3f33d
@@ -0,0 +1,5 @@
+obj-m += basic_mod.o
+
+all:
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
+	$(CC) kern_mod_loader.c -o kern_mod_loader
evmtest/src/basic_mod.c new file +36 -0
new file mode 100644
index 0000000..7c49c74
@@ -0,0 +1,36 @@
+/*
+ * Basic kernel module
+ *
+ * Copyright (C) 2018 IBM
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+/*
+ * evmtest_load_type is a flag passed when loading the module, it indicates
+ * which syscall is being used. It should be either init_module or finit_module
+ * When loaded, evmtest_load_type is outputted to the kernel's message buffer
+ */
+static char *evmtest_load_type;
+
+module_param(evmtest_load_type, charp, 000);
+MODULE_PARM_DESC(evmtest_load_type, "Which syscall is loading this module.");
+
+static int __init basic_module_init(void)
+{
+	printk(KERN_INFO "EVMTEST: LOADED MODULE (%s)\n", evmtest_load_type);
+	return 0;
+}
+
+static void __exit basic_module_cleanup(void)
+{
+	printk(KERN_INFO "EVMTEST: UNLOADED MODULE (%s)\n", evmtest_load_type);
+}
+
+module_init(basic_module_init);
+module_exit(basic_module_cleanup);
+
+MODULE_AUTHOR("David Jacobson");
+MODULE_DESCRIPTION("Kernel module for testing IMA signatures");
+MODULE_LICENSE("GPL");
evmtest/src/kern_mod_loader.c new file +131 -0

131 lines not on this page · raw message

Signature · 1 line
2.17.1
#3 lore raw

PATCH 4/7 evmtest: test kexec signature policy

In reply to David Jacobson

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.

---
 evmtest/files/policies/kexec_policy |   3 +
 evmtest/functions/r_kexec_sig.sh    | 156 ++++++++++++++++++++++++++++
 2 files changed, 159 insertions(+)
 create mode 100644 evmtest/files/policies/kexec_policy
 create mode 100755 evmtest/functions/r_kexec_sig.sh
evmtest/files/policies/kexec_policy new file +3 -0
new file mode 100644
index 0000000..dc00fa7
@@ -0,0 +1,3 @@
+appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig
+measure func=KEXEC_KERNEL_CHECK
+audit func=KEXEC_KERNEL_CHECK
evmtest/functions/r_kexec_sig.sh new file +156 -0

156 lines not on this page · raw message

Signature · 1 line
2.17.1
#4 lore raw

PATCH 5/7 evmtest: validate boot record

In reply to David Jacobson

The first record in the IMA runtime measurement list is the boot aggregate - a hash of PCRs 0-7. This test calculates the boot aggregate based off the PCRs and compares it to IMA's boot aggregate.

Dependencies: a TPM, IBMTSS2.

---
 evmtest/functions/r_validate_boot_record.sh | 140 ++++++++++++++++++++
 1 file changed, 140 insertions(+)
 create mode 100755 evmtest/functions/r_validate_boot_record.sh
evmtest/functions/r_validate_boot_record.sh new file +140 -0
new file mode 100755
index 0000000..421cbf1
@@ -0,0 +1,140 @@
+#!/bin/bash
+# Author: David Jacobson <[email protected]>
+TEST="r_validate_boot_record"
+
+ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.."
+source $ROOT/files/common.sh
+
+TPM_VERSION="2.0" # DEFAULT
+VERBOSE=0
+TSS_DIR=`locate ibmtpm20tss | head -1`
+EVENT_EXTEND=$TSS_DIR/utils12/eventextend
+LD_LIBRARY_PATH=$TSS_DIR/utils:$TSS_DIR/utils12
+MEASUREMENT_FILE=$EVMTEST_SECFS/tpm0/binary_bios_measurements
+# This test validates the eventlog against the hardware PCRs in the TPM, and
+# the boot aggregate against IMA.
+
+usage (){
+	echo "r_validate_boot_record [-hv]"
+	echo ""
+	echo "	This test must be run as root"
+	echo ""
+	echo "	This test will attempt to validate PCRs 0-7 in the TPM"
+	echo "	It will also validate the boot_aggregate based those PCRs"
+	echo "	against what IMA has recorded"
+	echo ""
+	echo "	-h,--help	Display this help message"
+	echo "	-v,--verbose	Verbose logging"
+}
+
+
+TEMP=`getopt -o 'hv' -l 'help,verbose' -n 'r_validate_boot_record' -- "$@"`
+eval set -- "$TEMP"
+
+while true ; do
+	case "$1" in
+	-h|--help) usage; exit; shift;;
+	-v|--verbose) VERBOSE=1; shift;;
+	--) shift; break;;
+	*) echo "[*] Unrecognized option $1"; exit 1 ;;
+	esac
+done
+
+EVMTEST_require_root
+
+echo "[*] Starting test: $TEST"
+
+v_out "Checking if securityfs is mounted..."
+if [[ -z $EVMTEST_SECFS_EXISTS ]]; then
+	fail "securityfs not found..."
+fi
+
+v_out "Verifying TPM is present..."
+if [[ ! -d $EVMTEST_SECFS/tpm0 ]]; then
+	fail "Could not locate TPM in $EVMTEST_SECFS"
+fi
+
+v_out "TPM found..."
+
+v_out "Checking if system supports reading event log..."
+
+if [[ ! -f $EVMTEST_SECFS/tpm0/binary_bios_measurements ]]; then
+		fail "Kernel does not support reading BIOS measurements,
+		please update to at least 4.16.0"
+fi
+
+
+
+v_out "Verifying TPM Version"
+if [[ -e /sys/class/tpm/tpm0/device/caps ]]; then
+	contains_12=`grep 'TCG version: 1.2' /sys/class/tpm/tpm0/device/caps`
+	if [[ -z $contains12 ]]; then
+		v_out "TPM 1.2"
+		TPM_VERSION="1.2"
+	fi
+else
+	v_out "TPM 2.0"
+fi
+
+v_out "Checking if system supports reading PCRs..."
+
+if [[ ! -d $TSS_DIR ]]; then
+	fail "Could not find TSS2, please install using the package and
+	 try again"
+fi
+
+v_out "Grabbing PCR values..."
+pcrs=() # array to store the Hardware PCR values
+sim_pcrs=() # What PCRs should be according to the event log
+halg=$(grep boot_aggregate $EVMTEST_SECFS/ima/ascii_runtime_measurements|\
+		sed -n 's/.*\(sha[^:]*\):.*/\1/p')
+
+for ((i=0; i<=7; i++)); do
+	if [[ $TPM_VERSION == "1.2" ]]; then
+		pcrs[i]=`TPM_INTERFACE_TYPE=dev $TSS_DIR/utils12/pcrread \
+			-ha $i -ns`
+	else
+		pcrs[i]=`TPM_INTERFACE_TYPE=dev $TSS_DIR/utils/pcrread \
+			-ha $i -halg $halg -ns`
+	fi
+done
+
+tss_out=`LD_LIBRARY_PATH=$LD_LIBRARY_PATH $EVENT_EXTEND -if \
+				$MEASUREMENT_FILE -sim -ns`
+for ((y=2; y<=9; y++)); do
+	# Parse TSS output - first strip away PCR, then split on :, then
+	# remove leading whitespace
+	x=`echo $tss_out | awk -v y=$y -F 'PCR' '{print $y}'`
+	x=`echo "$x" | awk -F ":" '{print $2}' | sed -e 's/^[ \t]*//'`
+	index=$((y-2))
+	sim_pcrs[$index]=$x
+done
+
+v_out "Validating PCRs.."
+for ((i=0; i<=7; i++)); do
+	v_out "SIM PCR [$i]: ${sim_pcrs[$i]}"
+	v_out "TPM PCR [$i]: ${pcrs[$i]}"
+	if [[  "${pcrs[$i]}" = "${sim_pcrs[$i]}" ]]; then
+		v_out "PCRs are incorrect..."
+		fail "Mismatch at PCR "$i" "
+	else
+		v_out "PCR $i validated..."
+	fi
+done
+
+
+v_out "Validating Boot Aggregate..."
+tss_boot_agg=`echo $tss_out | awk -F "boot aggregate:" '{print $2}'| tr -d " "`
+ima_boot_agg=`grep boot_aggregate \
+$EVMTEST_SECFS/ima/ascii_runtime_measurements|cut -d ":" -f2|cut -d " " -f1`
+v_out "TSS BOOT AGG: $tss_boot_agg"
+v_out "IMA BOOT AGG: $ima_boot_agg"
+
+if [ "$tss_boot_agg" != "$ima_boot_agg" ]; then
+	fail "Boot Aggregate is inconsistent"
+else
+	v_out "Boot Aggregate validated"
+fi
+
+echo "[*] TEST: PASSED"
+exit 0
Signature · 1 line
2.17.1
#5 lore raw

PATCH 6/7 evmtest: test the preservation of extended attributes

In reply to David Jacobson

IMA supports file signatures by storing information in a security.ima extended file attribute. This test ensures that the attribute is preserved when a file is copied. This test requires root because only root can write "security." xattrs to files.

---
 evmtest/functions/r_xattr_preserve.sh | 74 +++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)
 create mode 100755 evmtest/functions/r_xattr_preserve.sh
evmtest/functions/r_xattr_preserve.sh new file +74 -0
new file mode 100755
index 0000000..e7f0e2a
@@ -0,0 +1,74 @@
+#!/bin/bash
+# Author: David Jacobson <[email protected]>
+TEST="r_xattr_preserve"
+ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.."
+source $ROOT/files/common.sh
+
+VERBOSE=0
+# This test ensures that extended file attributes are preserved when a file is
+# moved with the correct flag
+
+usage (){
+	echo ""
+	echo "xattr_preserve [-hv]"
+	echo ""
+	echo "This test must be run as root"
+	echo ""
+	echo "	This test ensures that extended file attributes (specifically"
+	echo "	security.ima labels) are preserved when copying"
+	echo "Options"
+	echo "  -h,--help       Display this help message"
+	echo "  -v,--verbose    Verbose logging"
+}
+
+TEMP=`getopt -o 'hv' -l 'help,verbose' -n 'r_xattr_preserve' -- "$@"`
+eval set -- "$TEMP"
+
+while true ; do
+	case "$1" in
+	-h|--help) usage; exit; shift;;
+	-v|--verbose) VERBOSE=1; shift;;
+	--) shift; break;;
+	*) echo "[*] Unrecognized option $1"; exit 1;;
+	esac
+done
+
+EVMTEST_require_root
+
+begin
+
+LOCATION_1=`mktemp`
+LOCATION_2=`mktemp -u` # Doesn't create the file
+v_out "Labeling file..."
+
+evmctl ima_hash $LOCATION_1
+initial_ima_label=`getfattr -m ^security.ima -e hex \
+	--dump $LOCATION_1 2> /dev/null`
+
+initial_hash=`echo $initial_ima_label | awk -F '=' '{print $2}'`
+
+if [[ $initial_ima_label = *"security.ima"* ]]; then
+	v_out "Found hash on initial file... "
+else
+	fail "Hash not found on initial file"
+fi
+
+initial_hash=`echo $initial_ima_label | awk -F '=' '{print $2}'`
+
+v_out "Copying file..."
+cp --preserve=xattr $LOCATION_1 $LOCATION_2
+v_out "Checking if extended attribute has been preserved..."
+
+
+second_ima_label=`getfattr -m ^security.ima -e hex \
+	--dump $LOCATION_2 2> /dev/null`
+second_hash=`echo $second_ima_label | awk -F '=' '{print $2}'`
+if [[ "$initial_hash" != "$second_hash" ]]; then
+	fail "security.ima xattr was not preserved!"
+else
+	v_out "Extended attribute was preserved during copy"
+fi
+v_out "Cleaning up..."
+rm $LOCATION_1 $LOCATION_2
+
+passed
Signature · 1 line
2.17.1
#6 lore raw

PATCH 7/7 emvtest: Add ability to run all tests

In reply to David Jacobson

evmtest tests functionality of different IMA-Appraisal policies.

To simplify testing, this patch defines an evmtest config file. This allows for running all tests at once, rather than invoking each test individually. Variables can be set once rather than specifying parameters at runtime on the command line.

---
 evmtest/README       | 19 +++++++++++++++--
 evmtest/evmtest      | 51 +++++++++++++++++++++++++++++++++++++++++++-
 evmtest/example.conf | 14 ++++++++++++
 3 files changed, 81 insertions(+), 3 deletions(-)
 create mode 100644 evmtest/example.conf
evmtest/README +17 -2
index ac0c175..6f1c5c8 100644
@@ -20,8 +20,8 @@ used to check a kernel's configuration and validate compatibility with IMA.
 COMMANDS
 --------
 
- runtest <test name> - Run a specific test
- runall <configuration> - Run all tests
+ runtest <test name> 	 - Run a specific test
+ runall  <configuration> - Run all tests
 
 OPTIONS
 -------
@@ -34,7 +34,21 @@ OPTIONS
  --vm				Validate compatibility with a virtual machine
 
 
+CONFIGURATION FILE
+------------------
+
+The `example.conf` provides a skeleton configuration file, where the only
+variable that *must* be defined is `IMA_KEY`.
+
+* `IMA_KEY` - The private key for the certificate on the IMA Trusted Keyring
 
+* `KBUILD_DIR` - Should point to a kernel build tree. If not provided, the test
+will use `/lib/modules/$(uname -r)/build`.
+
+* `KERN_IMAGE` - Should point towards an unsigned kernel image. If not provided,
+the test will attempt to use the running kernel.
+
+* `VERBOSE` - If set to 1, will add -v to all tests run
 
 BACKGROUND
 ----------
@@ -42,6 +56,7 @@ The Linux kernel needs to be configured properly with a key embedded into the
 kernel and loaded onto the `.builtin_trusted_keys` keyring at boot in order to
 run evmtest.
 
+
 === 1. Confirming the kernel is properly configured with IMA enabled.
 
 A number of Kconfig options need to be configured to enable IMA and permit
evmtest/evmtest +50 -1

63 lines not on this page · raw message

evmtest/example.conf new file +14 -0
new file mode 100644
index 0000000..fd1c8fe
@@ -0,0 +1,14 @@
+# This is an example config file
+# There are three variables that can be set when using evmtest runall
+
+#Set this to 1 for verbose output
+VERBOSE=0
+# Path to the private key for the IMA Trusted Keyring
+# This is required
+IMA_KEY=/path/to/your/ima_key
+
+# If this is not provided, tests will run but attempt to copy the running kernel
+KERN_IMAGE=/path/to/unsigned/kernel_image
+
+# If this is not defined, tests will try to find build tree
+KBUILD_DIR=/path/to/kernel/build/tree
Signature · 1 line
2.17.1
#7 lore raw
In reply to David Jacobson
Quoted 2 lines · David Jacobson

This patchset introduces evmtest — a stand alone tool for regression testing IMA.

Nice!

I usually run the SELinux testsuite as a general sanity check of LSM before pushing to Linus, and I'll also run this once it's merged.

Signature · 2 lines
James Morris
<[email protected]>
#8 lore raw

Hi,

I will have a look to patches.

Thanks,
Dmitry

Quoted 14 lines · James Morris
Quoted 2 lines · David Jacobson

This patchset introduces evmtest — a stand alone tool for regression testing IMA.

Nice!

I usually run the SELinux testsuite as a general sanity check of LSM before pushing to Linus, and I'll also run this once it's merged.

--
James Morris
<[email protected]>

Signature · 2 lines
Thanks,
Dmitry