From patchwork Fri Mar 22 08:34:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: djacobs7@binghamton.edu X-Patchwork-Id: 10865271 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 07C58922 for ; Fri, 22 Mar 2019 08:35:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D61B42A587 for ; Fri, 22 Mar 2019 08:35:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C9E2F2A593; Fri, 22 Mar 2019 08:35:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 15A482A587 for ; Fri, 22 Mar 2019 08:35:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727847AbfCVIfD (ORCPT ); Fri, 22 Mar 2019 04:35:03 -0400 Received: from mail-qt1-f178.google.com ([209.85.160.178]:40161 "EHLO mail-qt1-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727597AbfCVIfD (ORCPT ); Fri, 22 Mar 2019 04:35:03 -0400 Received: by mail-qt1-f178.google.com with SMTP id x12so1594521qts.7 for ; Fri, 22 Mar 2019 01:35:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=binghamton.edu; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=eGHDJQgoJxv9uANnRijm3XAyAv37fWf1IfT/iuLCDBc=; b=PXjWftF3tWKUWR+5fL2JfiAh16wAPIKsQGEuqv0DMtX5apKQIxMvFdVt+CNwHrQtOd tjhWR8OMi/X57ZCTln2nQ4+x39O7S3kGZnpyz7uySGay/L/gmVCTQK1JVFUHz120ot9R 01R/rqFhrAWCDtLopkpY1YrkDvszTtQhEbH4Mry5cLWzZr/GpsuRkbirp8MWh07OBWL1 fZP0eMXXs5djcbFaoL9/b75vLdkUWzAmOXksTB6j2eniekHeg7lCv8AAblQWwztC6ddN dckkmhMtANdkzWFgK3efwshe4pUvdv69vrlzcdMgP9BpNfUOHSJGfThX1dbuib2Nimxq XbUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=eGHDJQgoJxv9uANnRijm3XAyAv37fWf1IfT/iuLCDBc=; b=RAOEK06SjU8P+r2yO+ku7aLZYKnLzIiKQkwqhPdAdrfcW7qlViGGgRnKpwfsxjzebB b38ZNVqatDHGNSaexF931cTO70DxDZafD2CCWL/PMflmNIem3Q/LuqsV9wPyteIOv4SE hfQHUjF5g4Zpuy8kEA6lThzSjc/VZWWvtctkbHGsCiIbecUvyRTn5+qxxqGF8t4baoz5 o7aHRkiiBkF9TPRnjv3cKzEAzV0O2hzE2VenIZ+lEbrPinxaUUgC8tG12VXFSJgAIzV1 AnDQUx5lmPEQIDf4635OUxFrm2h2D2eRIU7FiLY28y2sp3yx8qvTQ7DOQUhmnXfZrZ/y YZ6g== X-Gm-Message-State: APjAAAXVWwX6fIIrUXqxLRBG60zA7xehOOOB/YoxZQ0cbg/NKrd0eVQe Vll7rRfpWLS+g6GvVBUb1YC8Nur09dqjgw== X-Google-Smtp-Source: APXvYqy3/bx7EaW+imaNqL8lRhcQ2bDn9TFVYbmpmEgueStkTI3xL1NSzDyua5W1xa5BoYs/JQ+LNw== X-Received: by 2002:ac8:8d5:: with SMTP id y21mr7108448qth.67.1553243700732; Fri, 22 Mar 2019 01:35:00 -0700 (PDT) Received: from localhost.localdomain ([194.59.251.45]) by smtp.gmail.com with ESMTPSA id u16sm7441870qtc.84.2019.03.22.01.34.59 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 22 Mar 2019 01:35:00 -0700 (PDT) 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 Subject: [PATCH v2 1/8] evmtest: Regression testing integrity subsystem Date: Fri, 22 Mar 2019 04:34:34 -0400 Message-Id: <20190322083441.31084-1-djacobs7@binghamton.edu> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: David Jacobson As the Linux integrity subsystem matures and new features are added, the number of kernel configuration options (Kconfig) and methods for loading policies have increased. Regression testing of new and existing features is needed to ensure correct behavior. The Linux Test Project (LTP) is a test suite that aims to validate the "reliability, robustness, and stability" of Linux. Currently, the Linux Test Project (LTP) only includes the original IMA-measurement regression tests, not the newer IMA-appraisal or IMA- audit features. This patchset introduces "evmtest" — a standalone Linux integrity regression tool. evmtest can be used to validate individual behaviors by exercising execve, kexec, module load, and other LSM hooks. The initial evmtest regression tests verify the IMA-appraisal behavior based on appending IMA-appraisal policy rules to the custom policy. evmtest uses a combination of unsigned and validly signed files to verify the running system. The custom policy assumes the kernel is properly configured. The first evmtest named "env_validate" validates the kernel is properly configured. For example, CONFIG_IMA_WRITE_POLICY is required for appending to the IMA custom policy. A local-CA certificate needs to either be builtinto the kernel or memory reserved for embedding the certificate post-build. "evmtest" output is consistent, allowing "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 -h example_test -e [-vh] This is an example of how to structure an evmtest -e -h Displays this help message -v Verbose logging $ 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 [OPTIONS] options: -h Displays a help message -v Verbose logging Signed-off-by: David Jacobson Changelog: * Various clean-up to env_validate * Redid loading of running config * Changed comment order in example test * Cleaned up README * Removed notes about VM in env_validate and README * kernel_build_dir -> build_dir * Removed listing of functions/ directory * Added individual name of each test * Rewritten and expanded README * Rewrite validate and validate_defined * shellcheck compliant * example test, fewer comments + shellcheck * clean ups suggested by Mimi * renamed functions -> tests * checkbashishms compliant * removed begin funcion usage * removed long opt names * Notes file has changes in proper commit * switched to using functions for structure * added policy_readable to common.sh --- Makefile.am | 5 +- configure.ac | 1 + evmtest/INSTALL | 11 ++ evmtest/Makefile.am | 23 ++++ evmtest/README | 240 ++++++++++++++++++++++++++++++++++ evmtest/evmtest | 67 ++++++++++ evmtest/files/Notes | 5 + evmtest/files/common.sh | 59 +++++++++ evmtest/files/load_policy.sh | 37 ++++++ evmtest/tests/env_validate.sh | 196 +++++++++++++++++++++++++++ evmtest/tests/example_test.sh | 63 +++++++++ 11 files changed, 706 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 100644 evmtest/files/Notes create mode 100755 evmtest/files/common.sh create mode 100755 evmtest/files/load_policy.sh create mode 100755 evmtest/tests/env_validate.sh create mode 100755 evmtest/tests/example_test.sh diff --git a/Makefile.am b/Makefile.am index dba408d..0cb4111 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,4 +36,7 @@ rmman: doc: evmctl.1.html rmman evmctl.1 -.PHONY: $(tarname) +evmtest: + $(MAKE) -C evmtest + +.PHONY: $(tarname) evmtest diff --git a/configure.ac b/configure.ac index a5b4288..59ec1d1 100644 --- a/configure.ac +++ b/configure.ac @@ -52,6 +52,7 @@ EVMCTL_MANPAGE_DOCBOOK_XSL AC_CONFIG_FILES([Makefile src/Makefile packaging/ima-evm-utils.spec + evmtest/Makefile ]) AC_OUTPUT diff --git a/evmtest/INSTALL b/evmtest/INSTALL new file mode 100644 index 0000000..699853e --- /dev/null +++ b/evmtest/INSTALL @@ -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. diff --git a/evmtest/Makefile.am b/evmtest/Makefile.am new file mode 100644 index 0000000..e74feaf --- /dev/null +++ b/evmtest/Makefile.am @@ -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/tests/ + install -D $$(find ./files/ -not -type d) $(datarootdir)/evmtest/files/ + install -D ./tests/* $(datarootdir)/evmtest/tests/ + cp evmtest.1 $(datarootdir)/man/man1 + mandb -q + +.PHONY: install evmtest.1 diff --git a/evmtest/README b/evmtest/README new file mode 100644 index 0000000..5a44070 --- /dev/null +++ b/evmtest/README @@ -0,0 +1,240 @@ +evmtest(1) +========== + + +NAME +---- + +evmtest - Linux integrity subsystem regression testing utility + + +SYNOPSIS +-------- + +evmtest runtest [OPTIONS] + + +DESCRIPTION +----------- + +evmtest is a regression testing framework for testing different aspects of the +Linux integrity subsystem. + + +OPTIONS +------- + + -b + -c + -e + -h Help + -i + -k + -v Verbose logging + + +TEST NAMES +---------- + + env_validate - verify kernel build + example_test - example test + + +Introduction +------------ + +IMA-appraisal verifies a file's integrity based on the information +stored in the "security.ima" extended attribute (xattr), before the file +is made accessible to userspace. The "security.ima" xattr may contain +either a file hash or a file signature. However, only immutable files +may be signed. + +The file signatures are verified based on keys loaded onto the `.ima` +keyring. To prevent untrusted or unknown keys from being loaded onto +the `.ima` keyring, only certificates signed by a kernel "builtin" key +may be loaded onto the `.ima` keyring. This establishes a signature +chain of trust from a signed kernel image up to the running system. + + +Confirming the kernel is properly configured +-------------------------------------------- + +Several kernel configuration (Kconfig) options need to be enabled in order to +execute the regression test suite. To verify these options are enabled, +either a configuration file may be validated directly or the running +kernel's configuration may be validated. + +To directly validate a kernel's configuration file, execute: + + evmtest runtest r_env_validate -c [-v] + +To validate the running kernel's configuration is properly configured +requires root privileges. As root, execute: + + evmtest runtest r_env_validate -r [-v] + + +Creating a local-CA certificate +------------------------------- + +The local-CA's private key is used to sign certificates that are loaded +onto the `.ima` keyring. The evmctl manpage provides directions for +generating the local-CA keypair and for creating the certificate. Refer +to the evmctl manpage section named "GENERATE TRUSTED KEYS". + +The examples directory contains two sample scripts named +`ima-gen-local-ca.sh` and `ima-genkey.sh`, for generating these files. + +* `ima-local-ca.x509` - Inserted into the Linux kernel, to be loaded onto + the "builtin" keyring. +* `ima-local-ca.priv` - Used for signing the IMA certificate +* `x509_ima.der` - Loaded onto the IMA trusted keyring + + +Adding keys to the builtin kernel keyring +------------------------------------------- + +The Linux kernel's `scripts/insert-sys-cert`, included in the kernel +headers package (eg. kernel-headers, linux-headers), inserts a DER +encoded certificate into the Linux kernel post build. This requires +the kernel to be configured with `CONFIG_SYSTEM_EXTRA_CERTIFICATE` +enabled to reserve memory for the additional certificate. + +Some prebuilt kernel images are configured with this reserved memory. +For these kernels, after inserting the local-CA public key, the kernel +only needs to be resigned. For kernels which do not reserve memory for +a certificate, the kernel needs to be recompiled and resigned. + + +=== Inserting a local-CA certificate post build into the kernel + +upstreamed: insert-sys-cert -s System.map -b vmlinux -c +posted*: insert-sys-cert -s System.map -z vmlinuz -c + +After inserting the certificate with either of these methods, the kernel +needs to be resigned. + +* https://lwn.net/Articles/753487/ + + +=== Kernel build method for including a local-CA certificate + +The second method for adding a key to the .builtin_trusted_keys keyring is +to either directly include the certificate during the build, by +specifying the certificate pathname or by reserving memory for the +certificate. + +==== Kconfig options: including the certificate during build + CONFIG_SYSTEM_TRUSTED_KEYRING=y + CONFIG_SYSTEM_TRUSTED_KEYS="" + +==== Kconfig options: reserving memory for the certificate + CONFIG_SYSTEM_EXTRA_CERTIFICATE=y + CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=4096 + + +The latter method allows a generic kernel to be built, initially +containing a "test" certificate, but released with the "real" +certificate. + +In this kernel build environment, the certificate may be inserted into +the vmlinux post build, followed by "make" and "sudo make install". The kernel +image needs to be resigned as usual. + + +Signing the kernel image containing the local-CA certificate +------------------------------------------------------------ + +Once the kernel image is built and contains the local-CA certificate, +sign the kernel image as normal. A couple of tools exist for signing +kernel images (eg. pesign and sbsign). Refer to the distro’s +documentation. + + +Loading signed certificates onto the IMA trusted keyring +-------------------------------------------------------- + +The integrity dracut module 98integrity/ima-keys-load.sh loads keys +stored in /etc/keys/ima directory onto the IMA keyring. Assuming the +integrity dracut module is enabled, properly signed keys will be loaded +onto the IMA keyring on boot. + +To view the keys loaded onto the `.ima` keyring, as root execute: + + keyctl show %keyring:.ima + + +Boot command line options +------------------------- + +IMA's behavior is dependent on its policy. The policy defines which +files are measured, appraised, and audited. Without a policy, IMA does +not do anything. + + +=== Methods for defining policy rules + +* Builtin policies: are specified on the boot command line (eg. + ima_policy="tcb|appraise_tcb") +* Custom policy: is specified by echo'ing the custom policy pathname to + /ima/policy +* Build time policy rules: Kconfig options +* Architecture specific policy rules: Kconfig option + +The "builtin" policies, specified on the boot command line, are enabled +from boot. Once the LSMs are initialized, IMA policy rules can be +defined in terms of LSM labels, allowing for more fine grained policy +rules to be defined. The "builtin" policies can be replaced with a +"custom" policy. + +After loading a custom policy, additional rules may extend the +custom policy, if the kernel is configured with CONFIG_IMA_WRITE_POLICY +enabled. + +Unlike the "builtin" policies, the "build" time policy rules are +automatically enabled at runtime and continue to persist after loading a +custom policy. + +The "architecture" specific policy rules are derived during kernel boot, +based on runtime secure boot flags. These are similar to the "build" time +policies in that they persist after loading a custom policy. + +Initially each of the regression tests, first executes without an appraisal +policy rule and then extends the IMA policy with the specific test rule. +For this reason, the kernel must be configured with: + + CONFIG_IMA_WRITE_POLICY=y + CONFIG_IMA_READ_POLICY=y + +and booted without any appraisal policy rules. + +As the regression tests mature and additional tests are defined, the +regression tests will not make policy assumptions. + + +FAQ +--- +=== 1. How can an IMA key be loaded without rebuilding dracut? + +Unlike thread (@t), process (@p), session (@s), user (@u), or group (@g) +keyrings, loading keys onto a trusted keyring requires searching for the +keyring id. The shell command, below, finds and saves the keyring id. +The subsequent shell command loads a DER encoded key on to the keyring. + + keyring_id=`sudo keyctl describe %keyring:.ima | awk -F ':' '{print $1}';` + evmctl import ${keyring_id} + +This process can be scripted and added to startup/login + +=== 2. Should verbose mode be used when integrating with a test platform? + +When using evmtest inside of a test platform, output should be kept minimal. +This is accomplished by not using the --verbose option. + +== Reference + +1. https://sourceforge.net/p/linux-ima/wiki/Home/ + +Author +------ +David Jacobson - davidj@linux.ibm.com diff --git a/evmtest/evmtest b/evmtest/evmtest new file mode 100755 index 0000000..d579d03 --- /dev/null +++ b/evmtest/evmtest @@ -0,0 +1,67 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# Check to see if we're installed or not +evmtest=$(type -p evmtest) # Find in path +if [ -e "${evmtest}" ]; then + _evmdir=$(dirname "${evmtest}") + prefix=${_evmdir%%/bin} + EVMDIR=${prefix}/share/evmtest +else + EVMDIR=$DIR +fi + +source "$EVMDIR"/files/common.sh +usage (){ + echo "Usage:" + echo " evmtest runtest [OPTIONS]" + echo "" + echo "Options:" + echo " -h Displays this help message" + echo " -v Verbose logging" + echo "List of tests: [R] = Must be run as root" + echo "" + + # Any test should be added here manually + # The reason this is manual is to prevent the accidental / malicious + # placement of a script in tests/ + echo "[R] env_validate" + echo "[ ] examples_test" + + echo "" + echo "Note: Tests may be run directly from the \"tests\" directory" +} + + +runtest (){ + local test_name=$1 + shift + + if [ ! -e "$EVMDIR"/tests/"$test_name".sh ]; then + echo "[!] Test: \"$test_name\" not found" + usage + exit 1 + else + ("$EVMDIR"/tests/"$test_name".sh "$@") + fi +} + +if [ "$#" == 0 ]; then + usage + exit 1 +elif [ "$1" == "-h" ]; then + usage + exit 0 +elif [ "$1" == "runtest" ]; then + if [ -z "$2" ]; then + echo "[!] Provide a test" + exit + else + shift # Drop runtest + runtest "$@" + exit $? + fi +else + usage +fi diff --git a/evmtest/files/Notes b/evmtest/files/Notes new file mode 100644 index 0000000..f20a272 --- /dev/null +++ b/evmtest/files/Notes @@ -0,0 +1,5 @@ +This file contains a description of the contents of this directory. + +1. common.sh + +This file contains useful functions and variables for evmtest scripts. diff --git a/evmtest/files/common.sh b/evmtest/files/common.sh new file mode 100755 index 0000000..e48733f --- /dev/null +++ b/evmtest/files/common.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# This is the EVMTest common.sh file +# This is sourced at the top of a test file to provide common variables, +# paths, and functions. + +EVMTEST_forbid_root () { + if [ "$UID" == 0 ]; then + echo "[!] This test should not be run as root" + exit 1 + fi +} + +EVMTEST_require_root () { + if [ "$UID" != 0 ]; then + echo "[!] This test must be run as root" + exit 1 + fi +} + +# verbose_output function - will only echo output if verbose is true +# otherwise, output is muted +v_out () { + [ "$VERBOSE" != "0" ] && { echo "[*]" "$@" ; return ; } +} + +# Function to fail a test +fail () { + if [ "$VERBOSE" != 0 ]; then + if [ -n "$*" ]; then + echo "[!]" "$@" + fi + fi + echo "[*] TEST: FAILED" + exit 1 +} + +passed () { + echo "[*] TEST: PASSED" + exit 0 +} + +EVMTEST_check_policy_readable () { + v_out "Attempting to read current policy..." + if ! cat "$EVMTEST_SECFS"/ima/policy &>> /dev/null; then + fail "Could not read running policy. Kernel must be"\ + "configured with Kconfig option CONFIG_IMA_READ_POLICY=y" + fi + v_out "Policy is readable" +} + +# Everything exported should be prefixed with EVMTEST_ +EVMTEST_SECFS_EXISTS=$(findmnt securityfs) +EVMTEST_SECFS=$(findmnt -f -n securityfs -o TARGET) +EVMTEST_BOOT_OPTS=$(cat /proc/cmdline) + +export EVMTEST_SECFS_EXISTS +export EVMTEST_SECFS +export EVMTEST_BOOT_OPTS diff --git a/evmtest/files/load_policy.sh b/evmtest/files/load_policy.sh new file mode 100755 index 0000000..0430830 --- /dev/null +++ b/evmtest/files/load_policy.sh @@ -0,0 +1,37 @@ +#!/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 +# Otherwise, this will fail + +if [ "$#" != 1 ] || [ "$1" == "-h" ]; then + echo "Usage: load_policy " + exit +fi + +IMA_POLICY="$EVMTEST_SECFS"/ima/policy +EVMTESTPOLICY_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" \ + >/dev/null && pwd )/policies" + +if [ ! -e "$EVMTESTPOLICY_DIR"/"$1" ]; then + echo "[!] Policy: $1 not found, ensure it is in files/policies" + exit 1 +fi + +if ! echo "$EVMTESTPOLICY_DIR/$1" > "$IMA_POLICY"; then + echo "[!] Load failed - see dmesg" + exit 1 +else + echo "[*] Policy update completed" +fi + +exit 0 diff --git a/evmtest/tests/env_validate.sh b/evmtest/tests/env_validate.sh new file mode 100755 index 0000000..c630a23 --- /dev/null +++ b/evmtest/tests/env_validate.sh @@ -0,0 +1,196 @@ +#!/bin/bash +# This test serves to validate a kernel build for running with EVMTEST + +TEST="env_validate" +ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.." +source "$ROOT"/files/common.sh +VERBOSE=0 +CONFIG_FILE="" + +usage () { + echo "" + echo "env_validate [-c ]|-r] [-vh]" + echo "" + echo " This test validates that a kernel is properly configured, " + echo " based on either the provided config file or the builtin" + echo " kernel image config file of the running system" + echo "" + echo " -c Kernel config file" + echo " -r Will attempt to pull running config" + echo " -v Verbose testing" + echo " -h Displays this help message" + echo "" +} + +parse_args () { + TEMP=$(getopt -o 'hc:rv' -n 'env_validate' -- "$@") + eval set -- "$TEMP" + + while true ; do + case "$1" in + -h) usage; exit 0 ;; + -c) CONFIG="$2"; shift 2;; + -r) RUNNING=1; shift;; + -v) VERBOSE=1; shift;; + --) shift; break;; + *) echo "[*] Unrecognized option $1"; exit 1 ;; + esac + done + + # One must be defined + if [ -z "$CONFIG" ] && [ -z "$RUNNING" ]; then + usage + exit 1 + # But not both + elif [ -n "$CONFIG" ] && [ -n "$RUNNING" ]; then + usage + exit 1 + fi +} + +# Validate that a variable has been set to a value +validate () { + search="$1=$2" + for line in "${lines[@]}" + do + : + if test "${line}" == "${search}"; then + return + fi + done + INVALID_DEFINITION+=( "$search" ) +} + +# Validate that a variable is defined +validate_defined () { + search="$1" + for line in "${lines[@]}" + do + : + if test "${line#*$search}" != "$line"; then + if test "${line#*"#"}" == "$line"; then + return + fi + fi + done + NOT_DEFINED+=( "$1" ) +} + +# Attempt to find the config on /proc. If not on proc, try extracting from +# the image, and then the configs.ko module using extract-ikconfig. +locate_config () { + if [ -n "$RUNNING" ]; then + CONFIG_FILE=$(mktemp) + if ! gunzip -c /proc/config.gz &>> "$CONFIG_FILE"; then + # Clear errors + rm "$CONFIG_FILE" + + v_out "$WARN_PROC" + + build=$(uname -r) + scripts=/lib/modules/"$build"/build/scripts + extract="$scripts"/extract-ikconfig + image=/boot/vmlinuz-"$build" + mod=/lib/modules/"$build"/kernel/kernel/configs.ko + + if ! "$extract" "$image" &>> "$CONFIG_FILE"; then + rm "$CONFIG_FILE" + v_out "$WARN_IMAGE" + + if ! "$extract" "$mod" &>> "$CONFIG_FILE"; then + fail "$NO_CONF" + fi + fi + fi + v_out "Extracted config to $CONFIG_FILE" + fi + + if [ -n "$CONFIG" ]; then + CONFIG_FILE="$CONFIG" + fi + + if [ ! -f "$CONFIG_FILE" ]; then + fail "Could not find config file" + fi +} + +check_config () { + v_out "Parsing .config file..." + + IFS=$'\n' read -d '' -r -a lines < "$CONFIG_FILE" + + v_out "Validating keyring configuration..." + # Keyring configuration + validate "CONFIG_SYSTEM_EXTRA_CERTIFICATE" "y" + validate_defined "CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE" + validate "CONFIG_SYSTEM_TRUSTED_KEYRING" "y" + validate_defined "CONFIG_SYSTEM_TRUSTED_KEYS" + + v_out "Validating integrity configuration..." + # Integrity configuration + validate "CONFIG_INTEGRITY" "y" + validate "CONFIG_INTEGRITY_SIGNATURE" "y" + validate "CONFIG_INTEGRITY_ASYMMETRIC_KEYS" "y" + validate "CONFIG_INTEGRITY_TRUSTED_KEYRING" "y" + validate "CONFIG_INTEGRITY_AUDIT" "y" + + v_out "Validating IMA configuration..." + # IMA configuration + validate "CONFIG_IMA" "y" + validate "CONFIG_IMA_MEASURE_PCR_IDX" "10" + validate "CONFIG_IMA_LSM_RULES" "y" + validate "CONFIG_IMA_SIG_TEMPLATE" "y" + validate_defined "CONFIG_IMA_DEFAULT_TEMPLATE" + validate_defined "CONFIG_IMA_DEFAULT_HASH_SHA256" + validate_defined "CONFIG_IMA_DEFAULT_HASH" + validate "CONFIG_IMA_WRITE_POLICY" "y" + validate "CONFIG_IMA_READ_POLICY" "y" + validate "CONFIG_IMA_APPRAISE" "y" + validate "CONFIG_IMA_TRUSTED_KEYRING" "y" + validate "CONFIG_IMA_LOAD_X509" "y" + validate_defined "CONFIG_IMA_X509_PATH" + v_out "Validating module signing configuration..." + # Module signing configuration + validate_defined "CONFIG_MODULE_SIG_KEY" + validate "CONFIG_MODULE_SIG" "y" + + if [ ${#INVALID_DEFINITION[@]} != 0 ]; then + v_out "The following Kconfig variables are incorrectly defined:" + for var in "${INVALID_DEFINITION[@]}"; do + v_out "$var" + done + fi + + if [ ${#NOT_DEFINED[@]} != 0 ]; then + v_out "The following Kconfig variables need to be defined:" + for var in "${NOT_DEFINED[@]}"; do + v_out "$var" + done + + fi + + [ "${#NOT_DEFINED[@]}" -eq 0 ] && [ "${#INVALID_DEFINITION[@]}" -eq 0 ] + code=$? + + if [ -n "$RUNNING" ]; then + rm "$CONFIG_FILE" + fi + + if [ "$code" != 0 ]; then + fail + fi +} + +WARN_PROC="Configuration not on /proc, will attempt to extract from image" +WARN_IMAGE="Unable to extract from image, will attempt to extract from module" +NO_CONF="Unable to extract from module. Extracting kernel configuration + requires CONFIG_IKCONFIG to be enabled. Support for reading from /proc + is enabled with CONFIG_IKCONFIG_PROC" +INVALID_DEFINITION=() +NOT_DEFINED=() + +echo "[*] Starting test: $TEST" +parse_args "$@" +locate_config +check_config +passed diff --git a/evmtest/tests/example_test.sh b/evmtest/tests/example_test.sh new file mode 100755 index 0000000..c6035c9 --- /dev/null +++ b/evmtest/tests/example_test.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +# This is an example test for documentation purposes. +# This test describes the outline of evmtest test files. + +# Author: David Jacobson + +TEST="example_test" +ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.." +source "$ROOT"/files/common.sh +VERBOSE=0 + + + +usage () { + echo "" + echo "example_test -e [-vh]" + echo "" + echo " This is an example of how to structure an evmtest" + echo "" + echo " -e " + echo " -h Display this help message" + echo " -v Verbose logging" + echo "" +} + + + +parse_args () { + TEMP=$(getopt -o 'e:hv' -n 'example_test' -- "$@") + eval set -- "$TEMP" + while true ; do + case "$1" in + -h) usage; exit 0 ; shift;; + -e) EXAMPLE_FILE=$2; shift 2;; + -v) VERBOSE=1; shift;; + --) shift; break;; + *) echo "[*] Unrecognized option $1"; exit 1 ;; + esac + done + + if [ -z "$EXAMPLE_FILE" ]; then + usage + exit 1 + fi +} + +# Define what needs to be tested as a function +check_file_exists () { + if [ -e "$EXAMPLE_FILE" ]; then + v_out "Example file exists" + else + fail "Example file not found" + fi +} + +# The two options are: EVMTEST_forbid_root and EVMTEST_require_root +EVMTEST_forbid_root + +echo "[*] Starting test: $TEST" +parse_args "$@" +check_file_exists +passed From patchwork Fri Mar 22 08:34:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: djacobs7@binghamton.edu X-Patchwork-Id: 10865273 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4290817EF for ; Fri, 22 Mar 2019 08:35:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 210CF2A58D for ; Fri, 22 Mar 2019 08:35:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1360C2A587; Fri, 22 Mar 2019 08:35:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4AD352A58D for ; Fri, 22 Mar 2019 08:35:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727768AbfCVIfD (ORCPT ); Fri, 22 Mar 2019 04:35:03 -0400 Received: from mail-qk1-f176.google.com ([209.85.222.176]:43536 "EHLO mail-qk1-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727764AbfCVIfC (ORCPT ); Fri, 22 Mar 2019 04:35:02 -0400 Received: by mail-qk1-f176.google.com with SMTP id c20so716270qkc.10 for ; Fri, 22 Mar 2019 01:35:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=binghamton.edu; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Er3oFsIOCvxKt5MsoXkmkWsUWbLywGi6D9GPsEPoFyY=; b=E4zPyrebbceuVVf5IMU/iMY8g0E7nw9ingTUTZ75woXzSds79lTG1JZlxDcStFzX0+ q5b5rmzdjwFE++3qFDHVbySazFkV90Ihy25sDdI5ZDAuFFyxFcGMv3J4kLePcXmceBUQ tdepDz1EII+VBKFK1Rct1V1mlBo1GMbojnkY6LJMkvyL7T3TygqZJ1CBwE62zfYeo8r+ 6nq4ARancQKg44xAd98K7K2JLhWGIFvJkJRJ56khxS5s6whY5Nw4pDO77eH2oisDClev 4SDbFN9m8OKoBH1yuz1gVGKzHXvr/ZF06DdGwTQuTOP3LZKr24J7xTfTX8lM9RYbyKi2 MHBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Er3oFsIOCvxKt5MsoXkmkWsUWbLywGi6D9GPsEPoFyY=; b=EhvczMT/NxOohc96W9+JNRErtfHBdfOZliWlaj2cHEnU68suksZfaOEqLtBQGNge3g 7BSMCPknKkuWxg/D8yWCc9WqMxpebB6b+OejGB0LDV+WL1V6YHKeubjSGRrn/3M992Cu Oy06IDy9/Q76G3ZjWRfHKLFVt5vncHs6ZaKeCahe97miuIelARiBnLXHE7yQERWOhFPD Rm/3lM/YHY5r/1o97CqpJTXbnycUWLbczG7xKV2tYxeWLc3iJa42QmUVU/u0n8mxIzZl 1j43L7aZl131zwADAXpCiUmgw9+qpE1XF2Q15B2Y8uMm4ZUGvNDF2SnxYjXoekS6yBRm zwbQ== X-Gm-Message-State: APjAAAX21OLvEiz4n4GD9JI+Ovjw0uCpFrgZEI8RmVq0CJikLDZtK/pH pZynTH87o0ueVXVVS+3EZzO0jiLBQijfMg== X-Google-Smtp-Source: APXvYqyZnJzvNLJgKrjPqz8K/HWZBy+DDZ1uFHflcivvYKvjWs9R80sugazxFJDwjEwsTlQT9qXZUQ== X-Received: by 2002:a37:9bc7:: with SMTP id d190mr2456066qke.348.1553243701479; Fri, 22 Mar 2019 01:35:01 -0700 (PDT) Received: from localhost.localdomain ([194.59.251.45]) by smtp.gmail.com with ESMTPSA id u16sm7441870qtc.84.2019.03.22.01.35.00 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 22 Mar 2019 01:35:01 -0700 (PDT) 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 Subject: [PATCH v2 2/8] evmtest: test loading IMA policies Date: Fri, 22 Mar 2019 04:34:35 -0400 Message-Id: <20190322083441.31084-2-djacobs7@binghamton.edu> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190322083441.31084-1-djacobs7@binghamton.edu> References: <20190322083441.31084-1-djacobs7@binghamton.edu> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: David Jacobson 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. Signed-off-by: David Jacobson Changelog: * Placed policy_sig on list of tests * make sure key exists * shellcheck compliant * Update makefiles with tests instead of functions * removed begin * removed long opts * Notes file is updated in correct patch * restructure to use functions * reword usage * reworded patch title * Fixed changes in Notes * renamed key * Cut down on functions --- evmtest/Makefile.am | 6 +- evmtest/README | 1 + evmtest/evmtest | 1 + evmtest/files/Notes | 16 +++ evmtest/files/policies/signed_policy | 2 + evmtest/files/policies/unknown_signed_policy | 1 + evmtest/files/policies/unsigned_policy | 1 + evmtest/tests/policy_sig.sh | 110 +++++++++++++++++++ evmtest/unknown_privkey_ima.pem | 16 +++ 9 files changed, 153 insertions(+), 1 deletion(-) 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/tests/policy_sig.sh create mode 100644 evmtest/unknown_privkey_ima.pem diff --git a/evmtest/Makefile.am b/evmtest/Makefile.am index e74feaf..496a5de 100644 --- a/evmtest/Makefile.am +++ b/evmtest/Makefile.am @@ -14,9 +14,13 @@ evmtest.1: install: install -m 755 evmtest $(bindir) install -d $(datarootdir)/evmtest/files/ + install -d $(datarootdir)/evmtest/files/policies install -d $(datarootdir)/evmtest/tests/ - 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 ./tests/* $(datarootdir)/evmtest/tests/ + install -D ./files/policies/* $(datarootdir)/evmtest/files/policies/ cp evmtest.1 $(datarootdir)/man/man1 mandb -q diff --git a/evmtest/README b/evmtest/README index 5a44070..480f426 100644 --- a/evmtest/README +++ b/evmtest/README @@ -38,6 +38,7 @@ TEST NAMES env_validate - verify kernel build example_test - example test + policy_sig - verify loading IMA policies Introduction diff --git a/evmtest/evmtest b/evmtest/evmtest index d579d03..9902e61 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] policy_sig" echo "" echo "Note: Tests may be run directly from the \"tests\" directory" diff --git a/evmtest/files/Notes b/evmtest/files/Notes index f20a272..8aa2670 100644 --- a/evmtest/files/Notes +++ b/evmtest/files/Notes @@ -3,3 +3,19 @@ This file contains a description of the contents of this directory. 1. common.sh This file contains useful functions and variables for evmtest scripts. + +2. 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 additional rules to +the existing policy. + +3. policies/ + +This is a directory that contains IMA policies with self explanatory names. + +4. unknown_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. diff --git a/evmtest/files/policies/signed_policy b/evmtest/files/policies/signed_policy new file mode 100644 index 0000000..87828f0 --- /dev/null +++ b/evmtest/files/policies/signed_policy @@ -0,0 +1,2 @@ +measure func=POLICY_CHECK +appraise func=POLICY_CHECK appraise_type=imasig diff --git a/evmtest/files/policies/unknown_signed_policy b/evmtest/files/policies/unknown_signed_policy new file mode 100644 index 0000000..1f8f8f4 --- /dev/null +++ b/evmtest/files/policies/unknown_signed_policy @@ -0,0 +1 @@ +audit func=POLICY_CHECK diff --git a/evmtest/files/policies/unsigned_policy b/evmtest/files/policies/unsigned_policy new file mode 100644 index 0000000..1f8f8f4 --- /dev/null +++ b/evmtest/files/policies/unsigned_policy @@ -0,0 +1 @@ +audit func=POLICY_CHECK diff --git a/evmtest/tests/policy_sig.sh b/evmtest/tests/policy_sig.sh new file mode 100755 index 0000000..174d111 --- /dev/null +++ b/evmtest/tests/policy_sig.sh @@ -0,0 +1,110 @@ +#!/bin/bash +TEST="policy_sig" +# Author: David Jacobson + +ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.." +#shellcheck source=/usr/local/share/evmtest/files/common.sh +source "$ROOT"/files/common.sh + +VERBOSE=0 +POLICY_LOAD="$ROOT"/files/load_policy.sh +# This test validates that IMA measures and appraises policies. +usage() { + echo "" + echo "policy_sig -k [-vh]" + echo "" + echo " This test first loads a policy requiring all subsequent" + echo " policies to be signed, and verifies that only signed policies" + echo " may then be loaded." + echo "" + echo " Loading policy rules requires root privilege. This test must be" + echo " executed as root." + echo "" + echo " -k The key for the certificate on the IMA keyring" + echo " -h Display this help message" + echo " -v Verbose logging" +} + +parse_args () { + TEMP=$(getopt -o 'k:hv' -n 'policy_sig' -- "$@") + eval set -- "$TEMP" + + while true ; do + case "$1" in + -h) usage; exit 0; shift;; + -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 + fi + + if [ ! -f "$IMA_KEY" ]; then + cleanup + fail "Missing key" + fi +} + +load_signed_policy () { + v_out "Signing policy with provided key..." + if ! evmctl ima_sign -f "$POLICY_PATH" -k "$IMA_KEY" &>> /dev/null; then + cleanup + fail "Failed to sign policy - check key file" + fi + + v_out "Loading policy..." + if ! "$POLICY_LOAD" signed_policy &>> /dev/null; then + cleanup + fail "Failed to write policy. " + fi + v_out "Loaded" +} + +load_unsigned_policy () { + v_out "Attempting to load unsigned policy..." + if "$POLICY_LOAD" unsigned_policy &>> /dev/null; then + cleanup + fail "Failed to reject unsigned policy" + fi + + v_out "IMA Blocked unsigned policy" +} + +load_unknown_key_policy () { + v_out "Signing policy with invalid key..." + evmctl ima_sign -f "$ROOT"/files/policies/unknown_signed_policy \ + -k "$ROOT"/files/unknown_privkey_ima.pem &>> /dev/null + + v_out "Attempting to load policy signed by invalid key..." + if "$POLICY_LOAD" unknown_signed_policy &>> /dev/null; then + cleanup + fail "Failed to reject policy signed by unknown key" + fi + + v_out "IMA blocked policy signed by unknown key" +} + +cleanup () { + v_out "Removing security.ima attribute from policies..." + setfattr -x security.ima "$ROOT"/files/policies/unsigned_policy &>> \ + /dev/null + setfattr -x security.ima "$ROOT"/files/policies/unknown_signed_policy \ + &>> /dev/null + v_out "Done" +} + +POLICY_PATH="$ROOT"/files/policies/signed_policy + +EVMTEST_require_root +echo "[*] Starting test: $TEST" +parse_args "$@" +load_signed_policy +load_unsigned_policy +load_unknown_key_policy +cleanup +passed diff --git a/evmtest/unknown_privkey_ima.pem b/evmtest/unknown_privkey_ima.pem new file mode 100644 index 0000000..dcc0e24 --- /dev/null +++ b/evmtest/unknown_privkey_ima.pem @@ -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----- From patchwork Fri Mar 22 08:34:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: djacobs7@binghamton.edu X-Patchwork-Id: 10865267 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 20ED717EF for ; Fri, 22 Mar 2019 08:35:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 00BFB2A587 for ; Fri, 22 Mar 2019 08:35:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E859A2A593; Fri, 22 Mar 2019 08:35:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8CDA12A587 for ; Fri, 22 Mar 2019 08:35:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727728AbfCVIfF (ORCPT ); Fri, 22 Mar 2019 04:35:05 -0400 Received: from mail-qk1-f172.google.com ([209.85.222.172]:43533 "EHLO mail-qk1-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727832AbfCVIfE (ORCPT ); Fri, 22 Mar 2019 04:35:04 -0400 Received: by mail-qk1-f172.google.com with SMTP id c20so716288qkc.10 for ; Fri, 22 Mar 2019 01:35:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=binghamton.edu; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Co1GEveZfd4Xat/3SkhOIRbPAE0PV1ph7DVuYY6Ne9E=; b=XuBUTTifIU7ogJzt7QLOPuNl4dSKWG9Tb7oSjT9ZL0nTasRSj4+ZinaPjRN/LwtmSA OWo9DhiXI7wxC8MU1TqER6+woLKguT2Q32b9hxSqqBLLdEL10VSp15LolquD/rRweKcH BNiLIvZQ4AWqmOj/TG+jqb7QU9+RnsPczlvnL41n5gnEBqa7MPwKNeaY3U8Yc96yeT81 RNVuGOTGl9KzqcUnAl/1+dv2ezINu16qBITOJxacbzXfOoUu997uVcFIdmjUA8NLxbhc rvS+ztiSfY53GmP+HkEmH20H7TzbAOXRZjr7rnxhxH+1KmkjP/c8v6lmosOUvZrUmXlE sYyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Co1GEveZfd4Xat/3SkhOIRbPAE0PV1ph7DVuYY6Ne9E=; b=GBGGuHzPCYADDIKVdV9kz3iJBGYfONrvotmF1P/8MpKOer/Kj5H4pgjOaOr+hqcefp q1v6TNjciGWFYhgmaPXL5JlrfXdyPE1bqodIkotSzAHkiCeVqtXWhJALYRcHL2ZKs6kG MLLj4RZLJ4tuUyMyyDxH9wVeC2jf6h9lbu+hVH1rYbgcAMG6K8fsEEpUk0Vu3UPaAe5J udhic+ESVRNV+XpCHZOIlkwQ1Ftl73Mu7bQlNkGojx93eqRGEonKU0/m9l+OA5K98EFG c9rArzllFuo8Ns/vRgFmd1RCXXcQV96hRWAKLXRmrqB7YQTyW+mbk8nUWZ8mQTCTqxF/ cj3g== X-Gm-Message-State: APjAAAVoFEHUEvfdH/Rxeo+PCoYHdvatn1h7HNh6x30RVGIemzIoA6aD nFD6S3PsrpyzUi5cHkOrH8jxwSR5y4bGUg== X-Google-Smtp-Source: APXvYqy8HAJrJ2ZHffcHjms8Ex5r3yIe8vcUdAnu33j2e+T8yYwHbyUglzQxQLskDwzc2RxVgOR4cA== X-Received: by 2002:a37:d8e:: with SMTP id 136mr6322045qkn.95.1553243702353; Fri, 22 Mar 2019 01:35:02 -0700 (PDT) Received: from localhost.localdomain ([194.59.251.45]) by smtp.gmail.com with ESMTPSA id u16sm7441870qtc.84.2019.03.22.01.35.01 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 22 Mar 2019 01:35:01 -0700 (PDT) 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 Subject: [PATCH v2 3/8] evmtest: test kernel module loading Date: Fri, 22 Mar 2019 04:34:36 -0400 Message-Id: <20190322083441.31084-3-djacobs7@binghamton.edu> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190322083441.31084-1-djacobs7@binghamton.edu> References: <20190322083441.31084-1-djacobs7@binghamton.edu> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: 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. Signed-off-by: David Jacobson Changelog: * kernel_build_directory -> build_directory * Added kmod_sig to test list * shellcheck compliant * move from functions to tests * clean up for readability * redid order of loading and pushing policy * added policy check * checkbashisms complaint * removed begin * removed long opts * Notes file updated in appropriate patch * Restructured with functions * Renamed to simple_modload, can now be used in other areas --- evmtest/Makefile.am | 11 +- evmtest/README | 11 + evmtest/evmtest | 1 + evmtest/files/Notes | 5 + evmtest/files/policies/kernel_module_policy | 2 + evmtest/src/Makefile | 5 + evmtest/src/basic_mod.c | 36 +++ evmtest/src/simple_modload.c | 151 ++++++++++ evmtest/tests/kmod_sig.sh | 288 ++++++++++++++++++++ evmtest/tests/policy_sig.sh | 1 - 10 files changed, 507 insertions(+), 4 deletions(-) create mode 100644 evmtest/files/policies/kernel_module_policy create mode 100644 evmtest/src/Makefile create mode 100644 evmtest/src/basic_mod.c create mode 100644 evmtest/src/simple_modload.c create mode 100755 evmtest/tests/kmod_sig.sh diff --git a/evmtest/Makefile.am b/evmtest/Makefile.am index 496a5de..74a8199 100644 --- a/evmtest/Makefile.am +++ b/evmtest/Makefile.am @@ -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 @@ -21,7 +24,9 @@ install: $(datarootdir)/evmtest/files/ install -D ./tests/* $(datarootdir)/evmtest/tests/ install -D ./files/policies/* $(datarootdir)/evmtest/files/policies/ + cp ./src/basic_mod.ko $(datarootdir)/evmtest/files/ + cp ./src/basic_modload $(datarootdir)/evmtest/files cp evmtest.1 $(datarootdir)/man/man1 mandb -q -.PHONY: install evmtest.1 +.PHONY: src install evmtest.1 diff --git a/evmtest/README b/evmtest/README index 480f426..8c63630 100644 --- a/evmtest/README +++ b/evmtest/README @@ -39,6 +39,7 @@ TEST NAMES env_validate - verify kernel build example_test - example test policy_sig - verify loading IMA policies + policy_sig - test IMA-appraise on policies Introduction @@ -172,6 +173,9 @@ IMA's behavior is dependent on its policy. The policy defines which files are measured, appraised, and audited. Without a policy, IMA does not do anything. +When running evmtest, boot with: module.sig_enforce=1. This tells the kernel to +prevent the loading of any unsigned modules. + === Methods for defining policy rules @@ -213,6 +217,13 @@ As the regression tests mature and additional tests are defined, the regression tests will not make policy assumptions. +=== Require kernel module appended signatures + +Most kernels are configured with CONFIG_MODULE_SIG enabled but without +CONFIG_MODULE_SIG_FORCE. For testing purposes, require kernel module appended +signatures by specifying `module.sig_enforce=1` on the boot command line. + + FAQ --- === 1. How can an IMA key be loaded without rebuilding dracut? diff --git a/evmtest/evmtest b/evmtest/evmtest index 9902e61..49b162d 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] kmod_sig" echo "[R] policy_sig" echo "" diff --git a/evmtest/files/Notes b/evmtest/files/Notes index 8aa2670..574f5d8 100644 --- a/evmtest/files/Notes +++ b/evmtest/files/Notes @@ -19,3 +19,8 @@ This is a directory that contains IMA policies with self explanatory names. 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. + +5. basic_mod.ko + +This is a kernel module that logs (to dmesg) the syscall that was used to load +it. diff --git a/evmtest/files/policies/kernel_module_policy b/evmtest/files/policies/kernel_module_policy new file mode 100644 index 0000000..8096e18 --- /dev/null +++ b/evmtest/files/policies/kernel_module_policy @@ -0,0 +1,2 @@ +measure func=MODULE_CHECK +appraise func=MODULE_CHECK appraise_type=imasig diff --git a/evmtest/src/Makefile b/evmtest/src/Makefile new file mode 100644 index 0000000..2d66ece --- /dev/null +++ b/evmtest/src/Makefile @@ -0,0 +1,5 @@ +obj-m += basic_mod.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + $(CC) simple_modload.c -o simple_modload diff --git a/evmtest/src/basic_mod.c b/evmtest/src/basic_mod.c new file mode 100644 index 0000000..7c49c74 --- /dev/null +++ b/evmtest/src/basic_mod.c @@ -0,0 +1,36 @@ +/* + * Basic kernel module + * + * Copyright (C) 2018 IBM + */ +#include +#include +#include + +/* + * 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"); diff --git a/evmtest/src/simple_modload.c b/evmtest/src/simple_modload.c new file mode 100644 index 0000000..42510f0 --- /dev/null +++ b/evmtest/src/simple_modload.c @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * finit_module - load a kernel module using the finit_module syscall + * @fd: File Descriptor of the kernel module to be loaded + */ +int finit_module(int fd) +{ + return syscall(__NR_finit_module, fd, + "evmtest_load_type=finit_module", 0); +} + +/* + * init_module - load a kernel module using the init_module syscall + * @fd: File Descriptor of the kernel module to be loaded + * + * Adapted explanation from: https://github.com/cirosantilli/ + * linux-kernel-module-cheat/blob/ + * 91583552ba2c2d547c8577ac888ab9f851642b25/kernel_module/user/ + * myinsmod.c + */ +int init_module(int fd) +{ + + struct stat st; + + int mod = fstat(fd, &st); + + if (mod != 0) { + printf("[!] Failed to load module\n"); + return -1; + } + + size_t im_size = st.st_size; + void *im = malloc(im_size); + + if (im == NULL) { + printf("[!] Failed to load module - MALLOC NULL\n"); + return -1; + } + read(fd, im, im_size); + close(fd); + + int loaded = syscall(__NR_init_module, im, im_size, + "evmtest_load_type=init_module"); + free(im); + + return loaded; +} + +/* + * usage - print out a help message to the user + */ +void usage(void) +{ + printf("Usage: simple_modload <-p pathname> <-o | -n>\n"); + printf(" -p,--path pathname of kernel module\n"); + printf(" -o,--old old syscall (INIT_MODULE)\n"); + printf(" -n,--new new syscall (FINIT_MODULE)\n"); +} + +int main(int argc, char **argv) +{ + + int ret; + int uid = getuid(); + char * path; + char old = 0; + char new = 0; + + // For getopt + char * opt_path = 0; + int next; + + const char * const short_opts = "p:on"; + const struct option long_opts[] = + { + { "path", 1, NULL, 'p' }, + { "old", 0, NULL, 'o' }, + { "new", 0, NULL, 'n' }, + { NULL, 0, NULL, 0 } + }; + + while (1) { + next = getopt_long(argc, argv, short_opts, long_opts, NULL); + + if (next == -1) { + break; + } + + switch (next) { + case 'p' : + opt_path=optarg; + int size = strlen(opt_path) + 1; + path=(char *)malloc(sizeof(char) * size); + strcpy(path,opt_path); + break; + + case 'o' : + old = 1; + break; + + case 'n' : + new = 1; + break; + + case '?' : + case -1 : + break; + + default : + return -1; + } + } + + if ( (old && new) || !(old || new) || path == NULL) { + usage(); + return -1; + } + + /* Root is required to try and load kernel modules */ + if (uid != 0) { + printf("[!] simple_modload must be run as root\n"); + return -1; + } + + int fd = open(path, O_RDONLY); + if (fd == -1) { + printf("[!] Could not open file for read.\n"); + return -1; + } + + if (old == 1) { + ret = init_module(fd); + } else { + ret = finit_module(fd); + } + + return ret; +} diff --git a/evmtest/tests/kmod_sig.sh b/evmtest/tests/kmod_sig.sh new file mode 100755 index 0000000..0ebbaf3 --- /dev/null +++ b/evmtest/tests/kmod_sig.sh @@ -0,0 +1,288 @@ +#!/bin/bash +# Author: David Jacobson +TEST="kmod_sig" +BUILD_DIR="" +ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.." +source "$ROOT"/files/common.sh + +VERBOSE=0 +# This test validates that IMA prevents the loading of unsigned +# kernel modules + +# The boot command line option module.sig_enforce=1 is equivalent to +# compiling with CONFIG_MODULE_SIG_FORCE enabled. + +usage(){ + echo "" + echo "kmod_sig [-b build_directory] -k [-v]" + echo " This test verifies that IMA prevents the loading of an" + echo " unsigned kernel module with a policy appraising MODULE_CHECK" + echo "" + echo " This test must be run as root" + echo "" + echo " -b The path to a kernel build dir" + echo " -k IMA key" + echo " -v Verbose logging" + echo " -h Display this help message" +} + +parse_args () { + TEMP=$(getopt -o 'b:k:hv' -n 'kmod_sig' -- "$@") + eval set -- "$TEMP" + + while true ; do + case "$1" in + -h) usage; exit 0 ;; + -b) BUILD_DIR=$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 + echo "[!] Please provide an IMA key." + usage + exit 1 + fi +} + + +set_build_tree_location () { + if [ -z "$BUILD_DIR" ]; then + BUILD_DIR="/lib/modules/$(uname -r)/build" + if [ ! -e "$BUILD_DIR" ]; then + echo "[!] Could not find build tree. Specify with -b" + exit 1 + else + v_out "No build tree provided."\ + "Found - using: $(readlink -f "$BUILD_DIR")" + fi + fi + + + if [ ! -d "$BUILD_DIR" ]; then + fail "Could not find kernel build path" + fi +} + +check_key () { + if [ ! -e "$IMA_KEY" ]; then + fail "Could not find IMA key" + fi +} + +check_policy () { + already_run="IMA policy already contains MODULE_CHECK" + if [ -e "$EVMTEST_SECFS"/ima/policy ]; then + POLICY=$(mktemp -u) + cp "$EVMTEST_SECFS"/ima/policy "$POLICY" + if grep -q "MODULE_CHECK" "$POLICY"; then + rm "$POLICY" + fail "$already_run" + fi + rm "$POLICY" + fi +} + +unload_module () { + v_out "Unloading test module if loaded..." + rmmod basic_mod &>> /dev/null +} + + + +check_boot_opts () { + if ! printf '%s' "$EVMTEST_BOOT_OPTS" | grep -E -q "$SIG_ENFORCE_CMD"; + then + v_out "Run with kernel command: $SIG_ENFORCE_CMD" + fail "Booted with options: $EVMTEST_BOOT_OPTS" + else + v_out "Booted with correct configuration..." + fi +} + +# This test may have been run before - remove the security attribute so we can +# test again +remove_xattr_appended_sig () { + v_out "Removing security attribute and appended signature if present" + setfattr -x security.ima "$ROOT"/files/basic_mod.ko &>> /dev/null + strip --strip-debug "$ROOT"/files/basic_mod.ko +} + +check_hash_algo () { + # First attempt to find hash algo + hash_alg=$(grep CONFIG_MODULE_SIG_HASH "$BUILD_DIR"/.config|awk -F "=" \ + '{print $2}'| tr -d "\"") + # Need to read the config more to determine how to sign module... + if [ -z "$hash_alg" ]; then + v_out "Could not determine hash algorithm used on module"\ + "signing. Checking for other Kconfig variables..." + hash_opts=$(grep CONFIG_MODULE_SIG "$BUILD_DIR"/.config) + + # All possible hashes from: + # https://www.kernel.org/doc/html/v4.17/admin-guide/ + # module-signing.html + case $hash_opts in + *"CONFIG_MODULE_SIG_SHA1=y"*) + hash_alg="sha1" + ;; + *"CONFIG_MODULE_SIG_SHA224"*) + hash_alg="sha224" + ;; + *"CONFIG_MODULE_SIG_SHA256"*) + hash_alg="sha256" + ;; + *"CONFIG_MODULE_SIG_SHA384"*) + hash_alg="sha384" + ;; + *"CONFIG_MODULE_SIG_SHA512"*) + hash_alg="sha512" + ;; + *) + fail "Could not determine hash" + ;; + esac + fi + + v_out "Found hash algo: $hash_alg" +} + +check_signing_key () { + v_out "Looking for signing key..." + if [ ! -e "$BUILD_DIR"/certs/signing_key.pem ]; then + v_out "signing_key.pem not in certs/ finding via Kconfig"; + key_location=$(grep MODULE_SIG_KEY "$BUILD_DIR"/.config) + if [ -z "$key_location" ]; then + fail "Could not determine key location" + fi + # Parse from .config + key_location=${key_location/CONFIG_MODULE_SIG_KEY=/} + # Drop quotes + key_location=${key_location//\"} + # Drop .pem + key_location=${key_location/.pem} + sig_key="$key_location" + + else + sig_key="$BUILD_DIR"/certs/signing_key + fi + + v_out "Found key: $sig_key" +} + +sign_appended_signature () { + v_out "Signing module [appended signature]..." + + if ! "$BUILD_DIR"/scripts/sign-file "$hash_alg" "$sig_key".pem \ + "$sig_key".x509 "$ROOT"/files/basic_mod.ko; then + fail "Signing failed - please ensure sign-file is in scripts/" + fi +} + +check_appended_signature_init_mod () { + v_out "Attempting to load signed (appended) module with INIT_MODULE"\ + " syscall [should pass]" + if ! "$mod_load" -p "$ROOT"/files/basic_mod.ko -o &>> /dev/null; + then + fail "Failed to load using init_module - check key" + fi + + v_out "Module loaded - unloading" + rmmod basic_mod &>> /dev/null +} + +check_appended_signature_finit_mod () { + v_out "Attempting to load signed (appended) module with FINIT_MODULE"\ + " syscall [should pass]" + if ! "$mod_load" -p "$ROOT"/files/basic_mod.ko -n &>> /dev/null; + then + fail "Failed to load module" + fi + + v_out "Module loaded - unloading" + rmmod basic_mod &>> /dev/null +} + +update_policy () { + if ! evmctl ima_sign -f "$POLICY_PATH" -k "$IMA_KEY"; then + fail "Failed to sign policy - check key" + fi + + v_out "Signing and loading policy to prevent loading unsigned kernel"\ + " modules..." + if ! "$POLICY_LOAD" kernel_module_policy &>> /dev/null; then + fail "Could not write policy - is the supplied key correct?" + fi +} + +check_appended_signature_init_mod_IMA () { + v_out "Attempting to load signed (appended) module with FINIT_MODULE "\ + "syscall [should fail]" + if "$mod_load" -p "$ROOT"/files/basic_mod.ko -n &>> /dev/null; + then + rmmod_basic_mod &>> /dev/null + fail "FINIT_MODULE loaded module without xattr. Unloading" + fi + v_out "Prevented module without file attribute from loading" +} + +sign_xattr () { + v_out "Signing file [extended file attribute]..." + if ! evmctl ima_sign -k "$IMA_KEY" -f "$ROOT"/files/basic_mod.ko; then + fail "Error signing module - check keys" + fi +} + +check_xattr_finit_mod () { + v_out "Attempting to load module with FINIT_MODULE syscall"\ + " [should pass]" + "$mod_load" -p "$ROOT"/files/basic_mod.ko -n &>> /dev/null +} + +check_unknown_key () { + v_out "Signing with unknown key..." + evmctl ima_sign -f "$ROOT"/files/basic_mod.ko &>> /dev/null + if "$mod_load" -p "$ROOT"/files/basic_mod.ko -n &>> /dev/null; + then + fail "Allowed module to load with wrong signature" + fi + + v_out "Prevented loading module signed by unknown key using"\ + " FINIT_MODULE syscall" + + if "$mod_load" -p "$ROOT"/files/basic_mod.ko -o &>> /dev/null; + then + fail "Allowed module to load with wrong signature" + fi + + v_out "Prevented loading module signed by unknown key using"\ + " INIT_MODULE syscall" +} + +mod_load="$ROOT"/files/simple_modload +SIG_ENFORCE_CMD="module.sig_enforce=1" +POLICY_LOAD="$ROOT"/files/load_policy.sh +POLICY_PATH="$ROOT"/files/policies/kernel_module_policy + +EVMTEST_require_root +echo "[*] Starting test: $TEST" +parse_args "$@" +set_build_tree_location +check_key +check_policy +unload_module +check_boot_opts +remove_xattr_appended_sig +check_hash_algo +check_signing_key +sign_appended_signature +check_appended_signature_init_mod +check_appended_signature_finit_mod +update_policy +check_appended_signature_init_mod_IMA +sign_xattr +check_xattr_finit_mod +remove_xattr_appended_sig +passed diff --git a/evmtest/tests/policy_sig.sh b/evmtest/tests/policy_sig.sh index 174d111..ac56d0a 100755 --- a/evmtest/tests/policy_sig.sh +++ b/evmtest/tests/policy_sig.sh @@ -3,7 +3,6 @@ TEST="policy_sig" # Author: David Jacobson ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.." -#shellcheck source=/usr/local/share/evmtest/files/common.sh source "$ROOT"/files/common.sh VERBOSE=0 From patchwork Fri Mar 22 08:34:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: djacobs7@binghamton.edu X-Patchwork-Id: 10865269 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 996CC922 for ; Fri, 22 Mar 2019 08:35:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7DFE92A587 for ; Fri, 22 Mar 2019 08:35:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7225A2A589; Fri, 22 Mar 2019 08:35:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 010B22A58D for ; Fri, 22 Mar 2019 08:35:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727872AbfCVIfF (ORCPT ); Fri, 22 Mar 2019 04:35:05 -0400 Received: from mail-qt1-f193.google.com ([209.85.160.193]:46938 "EHLO mail-qt1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727857AbfCVIfE (ORCPT ); Fri, 22 Mar 2019 04:35:04 -0400 Received: by mail-qt1-f193.google.com with SMTP id z17so1550262qts.13 for ; Fri, 22 Mar 2019 01:35:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=binghamton.edu; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RdvC+51bl32WZuffSvloly+TOiS9ydaLK+J/h7e5kYs=; b=F9pzVM9SkG4ZphEXCNN0bYhZqKAmSw7jLc/Ydzo2p8QJnrVkebtLpNk76ZwfjfQifX adHDA+PC/V4jNT4DtDKWlS6A+oW/4p6MkzKcTpWqFuAsbjN204lrhGBy+6x9EuKNDpHX Uwejm1Zi0ETAOJbu7Hqhk8M4VuAsmyf6HScUmtLZwlHlAEWnuVXOwVm9pqBLWM9wMnf7 npQKmGBXjN4O7u4vvo8x4g0N0i5lh/85aQj48LWH2kWRQPPdtzOflPQd2cazwdTAaD7T NVnpJYh4I7Ng/47a5LMArZSO+JcRPR9TlO7X1gtEdmgC0RufIyEf9hXBV+Sxsir2iJi4 lk7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RdvC+51bl32WZuffSvloly+TOiS9ydaLK+J/h7e5kYs=; b=mPzupGJlRYHhQYzs246IN438+8wY0aGezZ+zF/YeMf5W8WPt0oZyk2LpBIu9nvJA1V mqDeGzeKN3L2UTzYmOb6kH8Vp87FaAKXKWTMj7o0dMS+stOyN4bcElhDFUg8YhTI0OgU kMtVgDbamfsfcyaGup5G5TKG3nOXx/Xz2xvvkSlN2/PT7fcXZW6gcLwjdE6tq9hvNRnl dcjvNCfx8Ybi+zChnWh3mK+xk+Fiyx6+v+1pENhTQ03ir2BZYqcjgsaGbPuMeLhl2KTY 5ounEjjeSzT21/9Nc7z0ZJzZAUn52BOtvETv9/MXmkTsi7iib+JeoUFVyYjlVsYdhkQ8 t+Hw== X-Gm-Message-State: APjAAAXUGqhq6h0iI34Wm7qP/LpcS/1YyObLs6fDqruYQ/dq9gx5+cmp qRhKjWzCxduvKsiCevvlb84QSKFbB4HEtQ== X-Google-Smtp-Source: APXvYqy4B4vQQeXJ1uhnaHc3rTnP73LNgKT3ooddRvEZrmVWZvbx6CpbgpWsgg/qibB6cAY086Fvhg== X-Received: by 2002:ac8:6894:: with SMTP id m20mr6648520qtq.277.1553243703074; Fri, 22 Mar 2019 01:35:03 -0700 (PDT) Received: from localhost.localdomain ([194.59.251.45]) by smtp.gmail.com with ESMTPSA id u16sm7441870qtc.84.2019.03.22.01.35.02 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 22 Mar 2019 01:35:02 -0700 (PDT) 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 Subject: [PATCH v2 4/8] evmtest: test kexec signature policy Date: Fri, 22 Mar 2019 04:34:37 -0400 Message-Id: <20190322083441.31084-4-djacobs7@binghamton.edu> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190322083441.31084-1-djacobs7@binghamton.edu> References: <20190322083441.31084-1-djacobs7@binghamton.edu> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: 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. Signed-off-by: David Jacobson 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 +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 [-i > /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 From patchwork Fri Mar 22 08:34:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: djacobs7@binghamton.edu X-Patchwork-Id: 10865265 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 957FC139A for ; Fri, 22 Mar 2019 08:35:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 76DBC2A589 for ; Fri, 22 Mar 2019 08:35:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 683932A593; Fri, 22 Mar 2019 08:35:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D4D962A589 for ; Fri, 22 Mar 2019 08:35:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727713AbfCVIfl (ORCPT ); Fri, 22 Mar 2019 04:35:41 -0400 Received: from mail-qt1-f196.google.com ([209.85.160.196]:41579 "EHLO mail-qt1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727665AbfCVIfF (ORCPT ); Fri, 22 Mar 2019 04:35:05 -0400 Received: by mail-qt1-f196.google.com with SMTP id w30so1595313qta.8 for ; Fri, 22 Mar 2019 01:35:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=binghamton.edu; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9+5vHzaM94PHzv+dji4AwOBZn3vkWoXUaRBYZUH01I8=; b=VH322g9hoUB26uiYPCGItW0jJWpi8Vr400pYKeYX67/VlRiiu9FTkUL+3DJgBOHk3J RgjCf6yFqx7OMlsut5RFvOQZF0mtaPcFFFJYJbJnJDSDsiCJT+G7r8t4gM1FTHotxpgk 7itB5rNapVkAbxxjxptcL1pwwzLO1UgP6FUo2EbTf2HbrwGXhqDKA3aj2FlRo3BiHa9R IcCqpoKjYXOpk2W8vYUuBnf4o+1OWaBWiFdCXlmTEmbu3shQ57OYYp5Pleyk2DJDTq0Y VDCTGXAvbf8p4C/dnn7hlvXNKubf6Yk1vH4mdBAf0hYeWFVUUCV+FKhhWJjZQlXdw7bg YZoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9+5vHzaM94PHzv+dji4AwOBZn3vkWoXUaRBYZUH01I8=; b=aUoHazfPlFfRQ3aK52h4y2+2VWkjP5ABeGn42e2w58l5tgXcyVpL256S5hIu05MzBT vIc0j5iBu5AOKGUWVVIvPpgxf/ieQRatby115LTelD/31lOxJq3TVfALYGdtQwY9sSDf FgBZzz8e7lSUyVGaJxaqASrV+OVxmWOVpGFu7XFXNNBF9CSJJvQ96HLy/VGjV6YLdUHo sQgETc07p+GiNLtdpIjWhnYla6e22m1sA1LXBRIkyBK7S0KS9ebFl+qWRf6FI1eaoulR c6QGogZ3QSFeuUPmd6YkTjnkOX9nfQbJmH3oBxuWmVZTitgRjpKsFWnzwJHQtzrbyF/P zAFg== X-Gm-Message-State: APjAAAXWwRCAZD0a1CE3oud7jA4XWO3CPA/h+tKM/n/r9fQuUoEX9+zN /Zo1w9u6SI4MZxTqlcZdpb10FU61BsyNGw== X-Google-Smtp-Source: APXvYqyqkGGC3LzyX2zgNQm+6lL4OrrKQVIKEeFukf3jJwF9HhQXjH0xLwPCcoyIUIXY4z8DB1zi4Q== X-Received: by 2002:ac8:2eb8:: with SMTP id h53mr6742069qta.188.1553243704023; Fri, 22 Mar 2019 01:35:04 -0700 (PDT) Received: from localhost.localdomain ([194.59.251.45]) by smtp.gmail.com with ESMTPSA id u16sm7441870qtc.84.2019.03.22.01.35.03 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 22 Mar 2019 01:35:03 -0700 (PDT) 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 Subject: [PATCH v2 5/8] evmtest: validate boot record Date: Fri, 22 Mar 2019 04:34:38 -0400 Message-Id: <20190322083441.31084-5-djacobs7@binghamton.edu> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190322083441.31084-1-djacobs7@binghamton.edu> References: <20190322083441.31084-1-djacobs7@binghamton.edu> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: 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. Signed-off-by: David Jacobson Changelog: * Added boot_aggregate to test list * shellcheck compliant * minor fixes * move from functions to tests * redid tss parsing * checkbashisms complaint * remove begin * removed long opts * restructured to use functions * added changes from Mimi to work with new TSS * removed searching for TSS locations --- evmtest/README | 1 + evmtest/evmtest | 1 + evmtest/tests/boot_aggregate.sh | 140 ++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100755 evmtest/tests/boot_aggregate.sh diff --git a/evmtest/README b/evmtest/README index 91c8cda..b2d37e2 100644 --- a/evmtest/README +++ b/evmtest/README @@ -36,6 +36,7 @@ OPTIONS TEST NAMES ---------- + boot_aggregate - verify the IMA boot-aggregate env_validate - verify kernel build example_test - example test policy_sig - verify loading IMA policies diff --git a/evmtest/evmtest b/evmtest/evmtest index cd5e238..3c967f9 100755 --- a/evmtest/evmtest +++ b/evmtest/evmtest @@ -26,6 +26,7 @@ usage (){ # Any test should be added here manually # The reason this is manual is to prevent the accidental / malicious # placement of a script in tests/ + echo "[R] boot_aggregate" echo "[R] env_validate" echo "[ ] examples_test" echo "[R] kexec_sig" diff --git a/evmtest/tests/boot_aggregate.sh b/evmtest/tests/boot_aggregate.sh new file mode 100755 index 0000000..adecfeb --- /dev/null +++ b/evmtest/tests/boot_aggregate.sh @@ -0,0 +1,140 @@ +#!/bin/bash +# Author: David Jacobson +TEST="boot_aggregate" + +ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.." +source "$ROOT"/files/common.sh + +VERBOSE=0 +TPM_VERSION="2.0" +# This test validates the eventlog against the hardware PCRs in the TPM, and +# the boot aggregate against IMA. + +usage (){ + echo "boot_aggregate [-hv]" + echo "" + echo " This test must be run as root" + echo "" + echo " This test validates PCRs 0-7 in the TPM" + echo " It also validates the boot_aggregate based those PCRs" + echo " against what IMA has recorded" + echo "" + echo " -h Display this help message" + echo " -v Verbose logging" +} + +parse_args () { + TEMP=$(getopt -o 'hv' -n 'boot_aggregate' -- "$@") + eval set -- "$TEMP" + + while true ; do + case "$1" in + -h) usage; exit; shift;; + -v) VERBOSE=1; shift;; + --) shift; break;; + *) echo "[*] Unrecognized option $1"; exit 1 ;; + esac + done +} + +check_requirements () { + 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 + TPM_VERSION="1.2" + fi +} + +check_pcrs () { + v_out "Grabbing PCR values..." + local pcrs=() # array to store the Hardware PCR values + local sim_pcrs=() # What PCRs should be according to the event log + local eventextend=tsseventextend + local pcrread="tsspcrread -halg sha1" + local eventlog=/sys/kernel/security/tpm0/binary_bios_measurements + + if [ "$TPM_VERSION" == "1.2" ]; then + eventextend=tss1eventextend + pcrread=tss1pcrread + fi + + for ((i=0; i<=7; i++)); do + pcrs[i]=$(TPM_INTERFACE_TYPE=dev $pcrread -ha "$i" -ns) + done + + local output=$(mktemp -u) + "$eventextend" -if "$eventlog" -sim -ns > "$output" + + # Some PTT's are using TPM 1.2 event log format. Retry on failure. + if [ $? -ne 0 ]; then + eventextend=tss1eventextend + "$eventextend" -if "$eventlog" -sim -ns > "$output" + fi + + IFS=$'\n' read -d '' -r -a lines < "$output" + rm "$output" + + for line in "${lines[@]}" + do + : + sim_pcrs+=( "$(echo "$line" | cut -d ':' -f2 | \ + tr -d '[:space:]')" ) + if printf '%s' "$line" | grep -E -q "boot aggregate"; then + tss_agg=$(echo "$line" | cut -d ':' -f2 | \ + tr -d '[:space:]') + fi + 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 +} + +check_boot_aggregate () { + v_out "Validating Boot Aggregate..." + ima_agg=$(grep boot_aggregate \ + "$EVMTEST_SECFS"/ima/ascii_runtime_measurements| head -1 | cut \ + -d ":" -f2|cut -d " " -f1) + v_out "TSS BOOT AGG: $tss_agg" + v_out "IMA BOOT AGG: $ima_agg" + + if [ "$tss_agg" != "$ima_agg" ]; then + fail "Boot Aggregate is inconsistent" + else + v_out "Boot Aggregate validated" + fi +} + +EVMTEST_require_root +echo "[*] Starting test: $TEST" +parse_args "$@" +check_requirements +check_pcrs +check_boot_aggregate +passed From patchwork Fri Mar 22 08:34:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: djacobs7@binghamton.edu X-Patchwork-Id: 10865263 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 409F3922 for ; Fri, 22 Mar 2019 08:35:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 256CB2A3F4 for ; Fri, 22 Mar 2019 08:35:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 194922A3FD; Fri, 22 Mar 2019 08:35:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8083E2A3F4 for ; Fri, 22 Mar 2019 08:35:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727786AbfCVIfX (ORCPT ); Fri, 22 Mar 2019 04:35:23 -0400 Received: from mail-qt1-f196.google.com ([209.85.160.196]:43911 "EHLO mail-qt1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727875AbfCVIfG (ORCPT ); Fri, 22 Mar 2019 04:35:06 -0400 Received: by mail-qt1-f196.google.com with SMTP id v32so1572860qtc.10 for ; Fri, 22 Mar 2019 01:35:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=binghamton.edu; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PhnXicmFBTSFqGzyUFmfRXJnBFygK9aujfgCD+WFYQc=; b=U3GGCL4EZQ0KRnBnwtu0pLNYoBpC9WIh8gZny1AkxtFqhJ94HZHIepwHsgMlHJ/yvq hTxDBfS5Bh0ZvdKwLzKAMki1lkTQ+vPZ1gqP904HWsGpZ2SCEMYCDfs9HMaUJ9ENvzmE tfXA5UczkNHPjCuv/pcWjbsbEwr/DKIEoCgijm44GYcJTvn+cGPMp3+urbtxrEj/frcf Kqq6BBR8g5lvLI2kbYo2ABR688HWgKOfrYifB4wnI7s/Qpn1k/Zs6L+ek0MvjjPtkfXN WilkzKD9H3l/xMSuAtIU/6WhBi/usLlREzQ5+AJNI6X2WkOsILumXXOZRZ8eUzlBBQPz Rsrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PhnXicmFBTSFqGzyUFmfRXJnBFygK9aujfgCD+WFYQc=; b=gm4S3rocxabnUC3cq9aYmuNUs9YUa1Z7lvjDtqTbJRHh4dK+KSxL8SDCKlaYmEjQb+ xTjNcLYhqhCFFTvNHPeHxpcE16nZtk9W6FqZ8UvzAxwSPesc/qdawSIvt1NMTFF2S8+q eDYhnjfShdlPKxpIlVRFD8jbCRXOGjd88USLm4WA4jwaxKoYGCVYm8FhUqimJQ9igSD0 0P2nUI67w8eCgGtxQiGN3b9EjK8ZWT2t5kTavHDJBvqvXEocPjcHMw4DuUP/1PzIZ8lo Ow9ldsXyp7GDA1B8GIxzA7SqCynTkWPw/7OVFKunSURUkz14K67bpoST4pPOhFYeQ2a6 b6gA== X-Gm-Message-State: APjAAAVTj5lkS7IeQMdDqv6KS5sBMU1IfYdkmsFsKBey0XacvKe2hHob P+jPRPtBxsYvS6kcKbOCDIBocdLuOt+amQ== X-Google-Smtp-Source: APXvYqzTwpQ+98MlfPVXbP3DCYg8Q/B8dIvd/aNpwTKL/1heCL76s0oqo2fX8aXwbpbWsW46sI/hCQ== X-Received: by 2002:ac8:30ea:: with SMTP id w39mr7125192qta.351.1553243704818; Fri, 22 Mar 2019 01:35:04 -0700 (PDT) Received: from localhost.localdomain ([194.59.251.45]) by smtp.gmail.com with ESMTPSA id u16sm7441870qtc.84.2019.03.22.01.35.04 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 22 Mar 2019 01:35:04 -0700 (PDT) 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 Subject: [PATCH v2 6/8] evmtest: test the preservation of extended attributes Date: Fri, 22 Mar 2019 04:34:39 -0400 Message-Id: <20190322083441.31084-6-djacobs7@binghamton.edu> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190322083441.31084-1-djacobs7@binghamton.edu> References: <20190322083441.31084-1-djacobs7@binghamton.edu> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: 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. Signed-off-by: David Jacobson Changelog: * Clean ups suggested via mailing list * getfattr used correctly * more information about which file is created * added xattr_preserve to test list * shellcheck compliant * move from functions to tests * checkbashisms complaint * remove begin * removed long opts * restructured using functions --- evmtest/README | 1 + evmtest/evmtest | 1 + evmtest/tests/xattr_preserve.sh | 81 +++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100755 evmtest/tests/xattr_preserve.sh diff --git a/evmtest/README b/evmtest/README index b2d37e2..4dddbc0 100644 --- a/evmtest/README +++ b/evmtest/README @@ -42,6 +42,7 @@ TEST NAMES policy_sig - verify loading IMA policies kexec_sig - test IMA-appraise on kexec image loading kmod_sig - test IMA-appraise on kernel module loading + xattr_preserve - test metadata preservation on file move Introduction diff --git a/evmtest/evmtest b/evmtest/evmtest index 3c967f9..18cb98d 100755 --- a/evmtest/evmtest +++ b/evmtest/evmtest @@ -32,6 +32,7 @@ usage (){ echo "[R] kexec_sig" echo "[R] kmod_sig" echo "[R] policy_sig" + echo "[R] xattr_preserve" echo "" echo "Note: Tests may be run directly from the \"tests\" directory" diff --git a/evmtest/tests/xattr_preserve.sh b/evmtest/tests/xattr_preserve.sh new file mode 100755 index 0000000..61f6ded --- /dev/null +++ b/evmtest/tests/xattr_preserve.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# Author: David Jacobson +TEST="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 requires root privileges to write security xattrs" + echo "" + echo " This test ensures that extended file attributes (specifically" + echo " security.ima labels) are preserved when copying" + echo "Options" + echo " -h Display this help message" + echo " -v Verbose logging" +} + +parse_args () { + TEMP=$(getopt -o 'hv' -n 'xattr_preserve' -- "$@") + eval set -- "$TEMP" + + while true ; do + case "$1" in + -h) usage; exit; shift;; + -v) VERBOSE=1; shift;; + --) shift; break;; + *) echo "[*] Unrecognized option $1"; exit 1;; + esac + done +} + +check_xattr_preserve () { + LOCATION_1=$(mktemp) + LOCATION_2=$(mktemp -u) # Doesn't create the file + + v_out "Creating and labeling file $LOCATION_1..." + + evmctl ima_hash "$LOCATION_1" + + initial_ima_label=$(getfattr --absolute-names -n security.ima \ + "$LOCATION_1") + initial_hash=$(echo "$initial_ima_label" | awk -F '=' '{print $2}') + if printf '%s' "$initial_ima_label" | grep -E -q "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 to $LOCATION_2..." + cp --preserve=xattr "$LOCATION_1" "$LOCATION_2" + v_out "Checking if extended attribute has been preserved..." + + + second_ima_label=$(getfattr --absolute-names -n security.ima \ + "$LOCATION_2") + 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 +} + +cleanup () { + v_out "Cleaning up..." + rm "$LOCATION_1" "$LOCATION_2" +} + +EVMTEST_require_root +echo "[*] Starting test: $TEST" +check_xattr_preserve +cleanup +passed From patchwork Fri Mar 22 08:34:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: djacobs7@binghamton.edu X-Patchwork-Id: 10865261 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5492E17EF for ; Fri, 22 Mar 2019 08:35:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 39A3A2A3F4 for ; Fri, 22 Mar 2019 08:35:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2E0652A3F7; Fri, 22 Mar 2019 08:35:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 076802A3F6 for ; Fri, 22 Mar 2019 08:35:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727910AbfCVIfK (ORCPT ); Fri, 22 Mar 2019 04:35:10 -0400 Received: from mail-qt1-f193.google.com ([209.85.160.193]:42281 "EHLO mail-qt1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727900AbfCVIfI (ORCPT ); Fri, 22 Mar 2019 04:35:08 -0400 Received: by mail-qt1-f193.google.com with SMTP id p20so1586679qtc.9 for ; Fri, 22 Mar 2019 01:35:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=binghamton.edu; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NgqzJKlYgrjsh+NPCvN4r+JkV5xuGyj+t6AG7/VzGIM=; b=IwnsUXB/ai3XHdIYd81DS0Ek/J8MbUGNfLHbA9yGdCvp8a5gjvzRAaC0IrKNC4bhw8 qNTw9twdi9eVZKM/NKSFc6FoNtcbPWz19UoFph8g6XgZ3LfyUZYz4wHIH9Z9MHc8xHhJ FvzrIu8sp4dcfmqkgfgR7xo7f+tT4q7NPxr1vZtUvtFpj4ii7gQm8JdhZrksbr6zHK1w Y5UDGpotPju+zKQvPrwy9JRThH9fXZIPQJEv7oBpavRSJlDmX7ENla2UgB7LwjJW2AIn hXGooIOz7Q40K/baBs8BxgL5C9a51BnHxEzjlnwAoiKUnaHUCMhAuJO2jmicClIl+Wwx IBMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NgqzJKlYgrjsh+NPCvN4r+JkV5xuGyj+t6AG7/VzGIM=; b=Y197Sgy2fQeGsnmr0BI+LbjJgZxUCwaZ+FjPfTLPgpkzE4kN05zkQS37UnCAdTOJlu BzHJM6t0G17Y0b65u1KEpK/a/8lH3jRSWX2JQyonDDBa+ljCxgr9n+zeaWWzVumGexUL kDBdjT7hFaDfZY5o5m+Ms5WVgcMz0Uo9ctuf7zwXpXuVlx5+upc0J+dqDk1NjvVWATHX gmzDqUerdmOU+B3aAZOZ5LoC4iHkTv+H8ikehvB6rTYxozD38qOUxNX6N/vusZMxQzwT REKyV22avJp2cPurbRxkOM6KT1DavMzq9e8it51LY//WVOCu26nln/GXAX2l0kq1Dkqw rWtQ== X-Gm-Message-State: APjAAAX7ENKFGK7L+BpOn1zn9gczxMzwS9Pbv8nxsqjLjRcgN8MAUcKz KYxMNY4fmDRd3j9pFPASgEZXIDSQxDHmOg== X-Google-Smtp-Source: APXvYqyoZ+gSSwdrqlgeeUPNErbFQtlTOA3fr1N5LHKlhKBLBrxyN9/3qLvxuWQcoyNLY9CM1zOW2w== X-Received: by 2002:aed:35e4:: with SMTP id d33mr6647374qte.58.1553243705650; Fri, 22 Mar 2019 01:35:05 -0700 (PDT) Received: from localhost.localdomain ([194.59.251.45]) by smtp.gmail.com with ESMTPSA id u16sm7441870qtc.84.2019.03.22.01.35.04 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 22 Mar 2019 01:35:05 -0700 (PDT) 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 Subject: [PATCH v2 7/8] emvtest: Add ability to run all tests Date: Fri, 22 Mar 2019 04:34:40 -0400 Message-Id: <20190322083441.31084-7-djacobs7@binghamton.edu> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190322083441.31084-1-djacobs7@binghamton.edu> References: <20190322083441.31084-1-djacobs7@binghamton.edu> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: 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. Signed-off-by: David Jacobson changelog: * removed [OPTIONS] for runall * added CONFIGURATION PATHNAME -> configuration file * shellcheck compliant --- evmtest/README | 31 +++++++++++++++++++++++++- evmtest/evmtest | 52 ++++++++++++++++++++++++++++++++++++++++++++ evmtest/example.conf | 14 ++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 evmtest/example.conf diff --git a/evmtest/README b/evmtest/README index 4dddbc0..d202559 100644 --- a/evmtest/README +++ b/evmtest/README @@ -13,6 +13,7 @@ SYNOPSIS evmtest runtest [OPTIONS] +evmtest runall DESCRIPTION ----------- @@ -34,7 +35,7 @@ OPTIONS TEST NAMES ----------- +--------- boot_aggregate - verify the IMA boot-aggregate env_validate - verify kernel build @@ -45,6 +46,34 @@ TEST NAMES xattr_preserve - test metadata preservation on file move + +CONFIGURATION PATHNAME +---------------------- + +The configuration pathname should point to the runall configuration file. + + +=== Configuration File + +The evmtest configuration file allows all tests to be run by executing a single +command. The configuration file contains all the options that needed for +various tests and allows tests to be run non-interactively, so they can be +integrated in a larger testing suite. + +The `example.conf` file provides a skeleton configuration file, where the only +variable that *must* be defined is `IMA_KEY`. Defaults are described below. + +* `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 + + Introduction ------------ diff --git a/evmtest/evmtest b/evmtest/evmtest index 18cb98d..d6f46f5 100755 --- a/evmtest/evmtest +++ b/evmtest/evmtest @@ -16,6 +16,7 @@ source "$EVMDIR"/files/common.sh usage (){ echo "Usage:" echo " evmtest runtest [OPTIONS]" + echo " evmtest runall " echo "" echo "Options:" echo " -h Displays this help message" @@ -67,6 +68,57 @@ elif [ "$1" == "runtest" ]; then runtest "$@" exit $? fi +elif [ "$1" == "runall" ]; then + if [ -z "$2" ] || [ ! -e "$2" ]; then + echo "evmtest runall " + echo "[!] Please provide a config file" + exit 1 + fi + source "$2" # Load in config + if [ "$VERBOSE" -eq 1 ]; then + V="-v" + fi + + # Key is not optional + if [ -z "$IMA_KEY" ]; then + echo "[*] Please correct your config file" + exit 1 + fi + + EVMTEST_require_root + FAIL=0 + echo "[*] Running tests..." + # 1 + "$EVMDIR"/tests/env_validate.sh -r "$V" + FAIL=$((FAIL+$?)) + # 2 + if [ -z "$KERN_IMAGE" ]; then + "$EVMDIR"/tests/kexec_sig.sh -k "$IMA_KEY" "$V" + else + "$EVMDIR"/tests/kexec_sig.sh -k "$IMA_KEY" -i \ + "$KERN_IMAGE" "$V" + fi + FAIL=$((FAIL+$?)) + # 3 + if [ -z "$KBUILD_DIR" ]; then + "$EVMDIR"/tests/kmod_sig.sh -k "$IMA_KEY" "$V" + else + "$EVMDIR"/tests/kmod_sig.sh -b "$KBUILD_DIR" \ + -k "$IMA_KEY" "$V" + fi + FAIL=$((FAIL+$?)) + # 4 + "$EVMDIR"/tests/policy_sig.sh -k "$IMA_KEY" "$V" + FAIL=$((FAIL+$?)) + # 5 + "$EVMDIR"/tests/boot_aggregate.sh "$V" + FAIL=$((FAIL+$?)) + # 6 + "$EVMDIR"/tests/xattr_preserve.sh "$V" + FAIL=$((FAIL+$?)) + echo "..." + echo "[*] TESTS PASSED: $((6-FAIL))" + echo "[*] TESTS FAILED: $FAIL" else usage fi diff --git a/evmtest/example.conf b/evmtest/example.conf new file mode 100644 index 0000000..fd1c8fe --- /dev/null +++ b/evmtest/example.conf @@ -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 From patchwork Fri Mar 22 08:34:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: djacobs7@binghamton.edu X-Patchwork-Id: 10865259 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BCE93139A for ; Fri, 22 Mar 2019 08:35:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A13132A3F4 for ; Fri, 22 Mar 2019 08:35:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 945432A407; Fri, 22 Mar 2019 08:35:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DA9F62A3F4 for ; Fri, 22 Mar 2019 08:35:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727754AbfCVIfJ (ORCPT ); Fri, 22 Mar 2019 04:35:09 -0400 Received: from mail-qt1-f194.google.com ([209.85.160.194]:45304 "EHLO mail-qt1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727910AbfCVIfI (ORCPT ); Fri, 22 Mar 2019 04:35:08 -0400 Received: by mail-qt1-f194.google.com with SMTP id v20so1553986qtv.12 for ; Fri, 22 Mar 2019 01:35:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=binghamton.edu; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SyR5K000eJqDJS2DYCuM2fzt+a01LslORKwShJPCIkI=; b=HggEDh+WehkMnrpSFHpp0f11kdWfugptRsPBK5fvEj0QpDbv53G9Hcw+RebQqOzCis ULpf22W8E2mVn4LSAYOoprBmv5Mp/nUH5l7+rouxxvDI6LDcuTUQitX1BTV1nGnZUJ7C +LdtHzDvep7QKPKXfIYDl9A2hm1bPvVUbNeMVCT6KiVc8e4CpJL/eVf5St4372dK5L9i 9OuXdz0zwEqLmk+7UtyIxZd8Kg6cNkPoa0h7Is+vuN+h8v6Qbh/W+bp9P/KVDdjVrFAo UL2Erbr4z4cl8YGoPZuOa8i9lzTmI2EPfDNWkF1OPXpDL/smWpOtVjMU9d/FQUqPvjLk BR2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SyR5K000eJqDJS2DYCuM2fzt+a01LslORKwShJPCIkI=; b=BuRu0dEudCZvPn4Phg48zqUtKsz+CKdl53U63sgXPigDJRY53MqP1EmhVvBoYlM+1x TVHnmP4JMSRlqCtlGlNF830hhW+xg0e6nMU8I2nm8Oq+Kw8hqJKHAk0PZRIkm4MPXFgg JEYODCwbrciMjR+OjVzrVG1JGP7x8q8ybBccW5DXlDjj26+ktB2DV60Awv+DXkYSoTfs SV9CFhrNdUrtyGRnuE9xSZ7W/P5RwgSFcRykBEkp7pmlyFJv+M4HsmkV3gMU1T8QGTKq tvrhnBNgGTWHJhE0Up/pUJ/F00DyAqXn/9uM6YrQzp1uvqnbtVDXxWcMWi8/ASTEsnK1 iuIg== X-Gm-Message-State: APjAAAUAerTM8Te2a3aFXjThFFW+mWz6SFAQttsV8wdRHfqI0qxHPi5e bWmoVH04HfoVcVKPZtv/ATPDuMDQsCLMUQ== X-Google-Smtp-Source: APXvYqzcfm/HHhcnTTmMRlkLsiJWZP0e96qeIDSYtvQ+TQCaEwBUIMOJukaxavKymlOUwrhbd+DjbQ== X-Received: by 2002:ac8:1b63:: with SMTP id p32mr7142703qtk.173.1553243706447; Fri, 22 Mar 2019 01:35:06 -0700 (PDT) Received: from localhost.localdomain ([194.59.251.45]) by smtp.gmail.com with ESMTPSA id u16sm7441870qtc.84.2019.03.22.01.35.05 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 22 Mar 2019 01:35:05 -0700 (PDT) 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 Subject: [PATCH v2 8/8] evmtest: virtual machine compatibility Date: Fri, 22 Mar 2019 04:34:41 -0400 Message-Id: <20190322083441.31084-8-djacobs7@binghamton.edu> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190322083441.31084-1-djacobs7@binghamton.edu> References: <20190322083441.31084-1-djacobs7@binghamton.edu> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: David Jacobson Regression testing kernels is a task that is often virtualized. This patch adds functionality to evmtest that enables a developer to determine if their kernel build is suitable for running in a virtual machine. Signed-off-by: David Jacobson changelog: * shellcheck compliant * updated patch to work with function restructure --- evmtest/tests/env_validate.sh | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/evmtest/tests/env_validate.sh b/evmtest/tests/env_validate.sh index c630a23..09b1a87 100755 --- a/evmtest/tests/env_validate.sh +++ b/evmtest/tests/env_validate.sh @@ -4,12 +4,13 @@ TEST="env_validate" ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.." source "$ROOT"/files/common.sh +VM_VALIDATE=0 VERBOSE=0 CONFIG_FILE="" usage () { echo "" - echo "env_validate [-c ]|-r] [-vh]" + echo "env_validate [-c ]|-r] [--vm] [-vh]" echo "" echo " This test validates that a kernel is properly configured, " echo " based on either the provided config file or the builtin" @@ -18,12 +19,13 @@ usage () { echo " -c Kernel config file" echo " -r Will attempt to pull running config" echo " -v Verbose testing" + echo " --vm Will validate that the build is VM compatible" echo " -h Displays this help message" echo "" } parse_args () { - TEMP=$(getopt -o 'hc:rv' -n 'env_validate' -- "$@") + TEMP=$(getopt -o 'hc:rv' -l "vm" -n 'env_validate' -- "$@") eval set -- "$TEMP" while true ; do @@ -32,6 +34,7 @@ parse_args () { -c) CONFIG="$2"; shift 2;; -r) RUNNING=1; shift;; -v) VERBOSE=1; shift;; + --vm) VM_VALIDATE=1; shift;; --) shift; break;; *) echo "[*] Unrecognized option $1"; exit 1 ;; esac @@ -154,6 +157,22 @@ check_config () { validate_defined "CONFIG_MODULE_SIG_KEY" validate "CONFIG_MODULE_SIG" "y" + + if [ $VM_VALIDATE == 1 ]; then + v_out "Validating VM configuration" + + validate "CONFIG_BLK_MQ_VIRTIO" "y" + validate "CONFIG_MEMORY_BALLOON" "y" + validate "CONFIG_VIRTIO_BLK" "y" + validate "CONFIG_SCSI_VIRTIO" "y" + validate "CONFIG_HW_RANDOM_VIRTIO" "y" + validate "CONFIG_VIRTIO" "y" + validate "CONFIG_VIRTIO_MENU" "y" + validate "CONFIG_VIRTIO_PCI" "y" + validate "CONFIG_VIRTIO_PCI_LEGACY" "y" + validate "CONFIG_VIRTIO_BALLOON" "y" + fi + if [ ${#INVALID_DEFINITION[@]} != 0 ]; then v_out "The following Kconfig variables are incorrectly defined:" for var in "${INVALID_DEFINITION[@]}"; do