From patchwork Tue Feb 23 22:59:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Vorel X-Patchwork-Id: 12101033 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC4C7C433DB for ; Tue, 23 Feb 2021 23:10:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 830CC64E89 for ; Tue, 23 Feb 2021 23:10:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233068AbhBWXJE (ORCPT ); Tue, 23 Feb 2021 18:09:04 -0500 Received: from mx2.suse.de ([195.135.220.15]:52132 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233954AbhBWXAT (ORCPT ); Tue, 23 Feb 2021 18:00:19 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id DCF81AF45; Tue, 23 Feb 2021 22:59:37 +0000 (UTC) From: Petr Vorel To: ltp@lists.linux.it Cc: Tushar Sugandhi , Mimi Zohar , Lakshmi Ramasubramanian , agk@redhat.com, snitzer@redhat.com, gmazyland@gmail.com, linux-integrity@vger.kernel.org, dm-devel@redhat.com, Petr Vorel Subject: [PATCH v3 1/2] IMA: Generalize key measurement tests Date: Tue, 23 Feb 2021 23:59:29 +0100 Message-Id: <20210223225930.27095-2-pvorel@suse.cz> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210223225930.27095-1-pvorel@suse.cz> References: <20210223225930.27095-1-pvorel@suse.cz> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org From: Tushar Sugandhi Refactor check_keys_policy() and test1() implemented in ima_keys.sh to make it generic, and move the functionality to ima_setup.sh, to be used for measurements in other tests in the future. Suggested-by: Petr Vorel Reviewed-by: Petr Vorel Signed-off-by: Tushar Sugandhi [ pvorel: move tst_res TPASS/TFAIL into test_policy_measurement(), further cleanup ] Signed-off-by: Petr Vorel --- .../security/integrity/ima/tests/ima_keys.sh | 58 ++--------------- .../security/integrity/ima/tests/ima_setup.sh | 62 +++++++++++++++++++ 2 files changed, 68 insertions(+), 52 deletions(-) diff --git a/testcases/kernel/security/integrity/ima/tests/ima_keys.sh b/testcases/kernel/security/integrity/ima/tests/ima_keys.sh index c9eef4b68..1aeb1cd89 100755 --- a/testcases/kernel/security/integrity/ima/tests/ima_keys.sh +++ b/testcases/kernel/security/integrity/ima/tests/ima_keys.sh @@ -6,7 +6,7 @@ # # Verify that keys are measured correctly based on policy. -TST_NEEDS_CMDS="cmp cut grep sed xxd" +TST_NEEDS_CMDS="cmp cut grep tail xxd" TST_CNT=2 TST_NEEDS_DEVICE=1 TST_SETUP=setup @@ -28,64 +28,18 @@ cleanup() tst_is_num $KEYRING_ID && keyctl clear $KEYRING_ID } -check_keys_policy() -{ - local pattern="$1" - - if ! grep -E "$pattern" $TST_TMPDIR/policy.txt; then - tst_res TCONF "IMA policy must specify $pattern, $FUNC_KEYCHECK, $TEMPLATE_BUF" - return 1 - fi - return 0 -} - # Based on https://lkml.org/lkml/2019/12/13/564. # (450d0fd51564 - "IMA: Call workqueue functions to measure queued keys") test1() { local keycheck_lines i keyrings templates local pattern='keyrings=[^[:space:]]+' - local test_file="file.txt" tmp_file="file2.txt" + local temp_file="test1.txt" tst_res TINFO "verify key measurement for keyrings and templates specified in IMA policy" - check_keys_policy "$pattern" > $tmp_file || return - keycheck_lines=$(cat $tmp_file) - keyrings=$(for i in $keycheck_lines; do echo "$i" | grep "keyrings" | \ - sed "s/\./\\\./g" | cut -d'=' -f2; done | sed ':a;N;$!ba;s/\n/|/g') - if [ -z "$keyrings" ]; then - tst_res TCONF "IMA policy has a keyring key-value specifier, but no specified keyrings" - return - fi - - templates=$(for i in $keycheck_lines; do echo "$i" | grep "template" | \ - cut -d'=' -f2; done | sed ':a;N;$!ba;s/\n/|/g') - - tst_res TINFO "keyrings: '$keyrings'" - tst_res TINFO "templates: '$templates'" - - grep -E "($templates).*($keyrings)" $ASCII_MEASUREMENTS | while read line - do - local digest expected_digest algorithm - - digest=$(echo "$line" | cut -d' ' -f4 | cut -d':' -f2) - algorithm=$(echo "$line" | cut -d' ' -f4 | cut -d':' -f1) - keyring=$(echo "$line" | cut -d' ' -f5) - - echo "$line" | cut -d' ' -f6 | xxd -r -p > $test_file - - if ! expected_digest="$(compute_digest $algorithm $test_file)"; then - tst_res TCONF "cannot compute digest for $algorithm" - return - fi - - if [ "$digest" != "$expected_digest" ]; then - tst_res TFAIL "incorrect digest was found for $keyring keyring" - return - fi - done - - tst_res TPASS "specified keyrings were measured correctly" + check_policy_pattern "$pattern" $FUNC_KEYCHECK $TEMPLATE_BUF > $temp_file || return + test_policy_measurement keyrings $temp_file } # Create a new keyring, import a certificate into it, and verify @@ -97,11 +51,11 @@ test2() local cert_file="$TST_DATAROOT/x509_ima.der" local keyring_name="key_import_test" local pattern="keyrings=[^[:space:]]*$keyring_name" - local temp_file="file.txt" + local temp_file="test2.txt" tst_res TINFO "verify measurement of certificate imported into a keyring" - check_keys_policy "$pattern" >/dev/null || return + check_policy_pattern "$pattern" $FUNC_KEYCHECK $TEMPLATE_BUF >/dev/null || return KEYRING_ID=$(keyctl newring $keyring_name @s) || \ tst_brk TBROK "unable to create a new keyring" diff --git a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh index 59a7ffeac..605db0ff6 100644 --- a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh +++ b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh @@ -54,6 +54,19 @@ compute_digest() return 1 } +check_policy_pattern() +{ + local pattern="$1" + local func="$2" + local template="$3" + + if ! grep -E "$pattern" $TST_TMPDIR/policy.txt; then + tst_res TCONF "IMA policy must specify $pattern, $func, $template" + return 1 + fi + return 0 +} + check_policy_readable() { if [ ! -f $IMA_POLICY ]; then @@ -269,6 +282,55 @@ get_algorithm_digest() echo "$algorithm|$digest" } +test_policy_measurement() +{ + local policy_option="$1" + local lines=$(cat $2) + local input_digest="$3" + local test_file="$TST_TMPDIR/test.txt" + local grep_file="$TST_TMPDIR/grep.txt" + local i sources templates + + tst_require_cmds cut sed xxd + + sources=$(for i in $lines; do echo "$i" | grep "$policy_option" | \ + sed "s/\./\\\./g" | cut -d'=' -f2; done | sed ':a;N;$!ba;s/\n/|/g') + if [ -z "$sources" ]; then + tst_res TCONF "IMA policy $policy_option is a key-value specifier, but no values specified" + return + fi + + templates=$(for i in $lines; do echo "$i" | grep "template" | \ + cut -d'=' -f2; done | sed ':a;N;$!ba;s/\n/|/g') + + tst_res TINFO "policy sources: '$sources'" + tst_res TINFO "templates: '$templates'" + + grep -E "($templates).*($sources)" $ASCII_MEASUREMENTS > $grep_file + + while read line; do + local algorithm digest expected_digest src_line + + digest=$(echo "$line" | cut -d' ' -f4 | cut -d':' -f2) + algorithm=$(echo "$line" | cut -d' ' -f4 | cut -d':' -f1) + src_line=$(echo "$line" | cut -d' ' -f5) + + echo "$line" | cut -d' ' -f6 | xxd -r -p > $test_file + + if ! expected_digest="$(compute_digest $algorithm $test_file)"; then + tst_res TCONF "cannot compute digest for $algorithm" + return + fi + + if [ "$digest" != "$expected_digest" ]; then + tst_res TFAIL "incorrect digest was found for $src_line $policy_option" + return + fi + done < $grep_file + + tst_res TPASS "$policy_option measured correctly" +} + # loop device is needed to use only for tmpfs TMPDIR="${TMPDIR:-/tmp}" if [ "$(df -T $TMPDIR | tail -1 | awk '{print $2}')" != "tmpfs" -a -n "$TST_NEEDS_DEVICE" ]; then From patchwork Tue Feb 23 22:59:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Vorel X-Patchwork-Id: 12101035 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2B64BC433E0 for ; Tue, 23 Feb 2021 23:11:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E40E464E7C for ; Tue, 23 Feb 2021 23:11:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233576AbhBWXJq (ORCPT ); Tue, 23 Feb 2021 18:09:46 -0500 Received: from mx2.suse.de ([195.135.220.15]:52152 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233958AbhBWXAT (ORCPT ); Tue, 23 Feb 2021 18:00:19 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 28362AF49; Tue, 23 Feb 2021 22:59:38 +0000 (UTC) From: Petr Vorel To: ltp@lists.linux.it Cc: Tushar Sugandhi , Mimi Zohar , Lakshmi Ramasubramanian , agk@redhat.com, snitzer@redhat.com, gmazyland@gmail.com, linux-integrity@vger.kernel.org, dm-devel@redhat.com, Petr Vorel Subject: [PATCH v3 2/2] IMA: Add test for dm-crypt measurement Date: Tue, 23 Feb 2021 23:59:30 +0100 Message-Id: <20210223225930.27095-3-pvorel@suse.cz> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210223225930.27095-1-pvorel@suse.cz> References: <20210223225930.27095-1-pvorel@suse.cz> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org From: Tushar Sugandhi New functionality is being added to IMA to measure data provided by kernel components. With this feature, IMA policy can be set to enable measuring data provided by device-mapper targets. Currently one such device-mapper target - dm-crypt, is being updated to use this functionality. This new functionality needs test automation in LTP. Add a testcase which verifies that the IMA subsystem correctly measures the data coming from a device-mapper target - dm-crypt. Reviewed-by: Petr Vorel Signed-off-by: Tushar Sugandhi [ pvorel: adapt to previous commit changes, removed template=ima-buf, further cleanup ] Signed-off-by: Petr Vorel --- I wonder if $input_digest and $input_digest_found is needed to be considered in loop. Maybe there could be return after first check when $input_digest is passed to test_policy_measurement(). runtest/ima | 1 + .../kernel/security/integrity/ima/README.md | 20 +++++++++ .../integrity/ima/tests/ima_dm_crypt.sh | 41 +++++++++++++++++++ .../security/integrity/ima/tests/ima_setup.sh | 11 ++++- 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100755 testcases/kernel/security/integrity/ima/tests/ima_dm_crypt.sh diff --git a/runtest/ima b/runtest/ima index 5f4b4a7a1..123b6c8b0 100644 --- a/runtest/ima +++ b/runtest/ima @@ -5,4 +5,5 @@ ima_tpm ima_tpm.sh ima_violations ima_violations.sh ima_keys ima_keys.sh ima_kexec ima_kexec.sh +ima_dm_crypt ima_dm_crypt.sh evm_overlay evm_overlay.sh diff --git a/testcases/kernel/security/integrity/ima/README.md b/testcases/kernel/security/integrity/ima/README.md index 68d046678..007662fae 100644 --- a/testcases/kernel/security/integrity/ima/README.md +++ b/testcases/kernel/security/integrity/ima/README.md @@ -37,6 +37,26 @@ see example in `kexec.policy`. The test attempts to kexec the existing running kernel image. To kexec a different kernel image export `IMA_KEXEC_IMAGE=`. +### IMA DM target (dm-crypt) measurement test + +To enable IMA to measure device-mapper target - dm-crypt, +`ima_dm_crypt.sh` requires a readable IMA policy, as well as +a loaded measure policy with +`func=CRITICAL_DATA data_sources=dm-crypt` + +As well as what's required for the IMA tests, dm-crypt measurement test require +reading the IMA policy allowed in the kernel configuration: +``` +CONFIG_IMA_READ_POLICY=y +``` + +The following kernel configuration is also required. It enables compiling +the device-mapper target module dm-crypt, which allows to create a device +that transparently encrypts the data on it. +``` +CONFIG_DM_CRYPT +``` + ## EVM tests `evm_overlay.sh` requires a builtin IMA appraise tcb policy (e.g. `ima_policy=appraise_tcb` diff --git a/testcases/kernel/security/integrity/ima/tests/ima_dm_crypt.sh b/testcases/kernel/security/integrity/ima/tests/ima_dm_crypt.sh new file mode 100755 index 000000000..b49662f73 --- /dev/null +++ b/testcases/kernel/security/integrity/ima/tests/ima_dm_crypt.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2021 Microsoft Corporation +# Copyright (c) 2021 Petr Vorel +# Author: Tushar Sugandhi +# +# Verify that DM target dm-crypt are measured correctly based on policy. + +TST_NEEDS_CMDS="dmsetup" +TST_NEEDS_DEVICE=1 +TST_SETUP=setup +TST_CLEANUP=cleanup + +. ima_setup.sh + +FUNC='func=CRITICAL_DATA' +PATTERN='data_sources=[^[:space:]]+' +REQUIRED_POLICY="^measure.*($FUNC.*$PATTERN|$PATTERN.*$FUNC)" + +setup() +{ + require_ima_policy_content "$REQUIRED_POLICY" '-E' > $TST_TMPDIR/policy.txt +} + +cleanup() +{ + ROD "dmsetup remove test-crypt" +} + +test1() +{ + local input_digest="039d8ff71918608d585adca3e5aab2e3f41f84d6" + local key="faf453b4ee938cff2f0d2c869a0b743f59125c0a37f5bcd8f1dbbd911a78abaa" + + tst_res TINFO "verifying dm-crypt target measurement" + + ROD dmsetup create test-crypt --table "0 1953125 crypt aes-xts-plain64 $key 0 /dev/loop0 0 1 allow_discards" + check_policy_measurement data_sources $TST_TMPDIR/policy.txt $input_digest +} + +tst_run diff --git a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh index 605db0ff6..22bb4649d 100644 --- a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh +++ b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh @@ -289,7 +289,7 @@ test_policy_measurement() local input_digest="$3" local test_file="$TST_TMPDIR/test.txt" local grep_file="$TST_TMPDIR/grep.txt" - local i sources templates + local i input_digest_found sources templates tst_require_cmds cut sed xxd @@ -326,8 +326,17 @@ test_policy_measurement() tst_res TFAIL "incorrect digest was found for $src_line $policy_option" return fi + + if [ "$input_digest" -a "$digest" = "$input_digest" ]; then + input_digest_found=1 + fi done < $grep_file + if [ "$input_digest" -a "$input_digest_found" != 1 ]; then + tst_res TFAIL "expected digest '$input_digest' not found" + return + fi + tst_res TPASS "$policy_option measured correctly" }