diff mbox series

[v2] IMA: Add test for kexec cmdline measurement

Message ID 20200722164040.23109-1-t-josne@linux.microsoft.com
State Changes Requested
Headers show
Series [v2] IMA: Add test for kexec cmdline measurement | expand

Commit Message

Lachlan Sneff July 22, 2020, 4:40 p.m. UTC
IMA policy can be set to measure the command line passed in the kexec system call.
There needs to be a test to validate this kexec command line measurement.

Add a testcase that verifies that the IMA subsystem has correctly
measured the cmdline specified during a kexec.

Note that this test does not actually reboot.

Signed-off-by: Lachlan Sneff <t-josne@linux.microsoft.com>
---
 runtest/ima                                   |   1 +
 .../kernel/security/integrity/ima/README.md   |  11 ++
 .../security/integrity/ima/tests/ima_kexec.sh | 121 ++++++++++++++++++
 3 files changed, 133 insertions(+)
 create mode 100644 testcases/kernel/security/integrity/ima/tests/ima_kexec.sh

Comments

Mimi Zohar July 22, 2020, 6:09 p.m. UTC | #1
On Wed, 2020-07-22 at 12:40 -0400, Lachlan Sneff wrote:
> IMA policy can be set to measure the command line passed in the kexec system call.
> There needs to be a test to validate this kexec command line measurement.
> 
> Add a testcase that verifies that the IMA subsystem has correctly
> measured the cmdline specified during a kexec.
> 
> Note that this test does not actually reboot.
> 
> Signed-off-by: Lachlan Sneff <t-josne@linux.microsoft.com>

Other than the patch not applying cleanly and leading blanks, 

Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Mimi Zohar July 22, 2020, 6:32 p.m. UTC | #2
On Wed, 2020-07-22 at 14:09 -0400, Mimi Zohar wrote:
> On Wed, 2020-07-22 at 12:40 -0400, Lachlan Sneff wrote:
> > IMA policy can be set to measure the command line passed in the kexec system call.
> > There needs to be a test to validate this kexec command line measurement.
> > 
> > Add a testcase that verifies that the IMA subsystem has correctly
> > measured the cmdline specified during a kexec.
> > 
> > Note that this test does not actually reboot.
> > 
> > Signed-off-by: Lachlan Sneff <t-josne@linux.microsoft.com>
> 
> Other than the patch not applying cleanly and leading blanks, 
> 
> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>

Oops, the kexec load is using the '-s' option, similarly the unload
should use it too.  Please change all the "kexec -u" occurences to
"kexec -su".

+    if ! kexec -sl $IMAGE --reuse-cmdline; then
> +        tst_res TCONF "kexec failed: $?"
> +        
> +        local sb_status="$(bootctl status 2>/dev/null | grep 'Secure Boot' \
> +            | tr -d ' ' | sed 's/SecureBoot:*//')"
> +        
> +        if [ "$sb_status" = "enabled" ]; then
> +            tst_res TINFO "secure boot is enabled, the specified kernel image may not be signed"
> +        fi
> +
> +        return
> +    fi
> +
> +    kexec -u
> +
> +    if ! measure "$cmdline"; then
> +        tst_res TFAIL "unable to find a correct entry in the IMA log"
> +        
> +        if [ ! -r $IMA_POLICY ]; then
> +            tst_brk TCONF "cannot read IMA policy (CONFIG_IMA_READ_POLICY=y required) to give contextual information"
> +        fi
> +
> +        if ! grep "measure func=KEXEC_CMDLINE" $IMA_POLICY >/dev/null; then
> +            tst_brk TCONF "The IMA policy does not specify 'measure func=KEXEC_CMDLINE', see IMA test README"
> +        fi
> +
> +        return
> +    fi
> +
> +    cmdline="foo"cmldine
> +    if ! kexec -sl $IMAGE --append=$cmdline; then
> +        tst_brk TCONF "kexec failed: $?"
> +    fi
> +
> +    kexec -u
Lachlan Sneff July 22, 2020, 6:34 p.m. UTC | #3
Thank you for signing off on this patch!

I apologize for the issues on applying. I should've caught the trailing 
spaces, but the inability to apply the README
is actually a result of this patch being based on the custom keyring 
patch that I sent out last Friday [1].

[1]: [PATCH] IMA: Add a test to verify importing a certificate into 
custom keyring

On 7/22/20 2:09 PM, Mimi Zohar wrote:
> On Wed, 2020-07-22 at 12:40 -0400, Lachlan Sneff wrote:
>> IMA policy can be set to measure the command line passed in the kexec system call.
>> There needs to be a test to validate this kexec command line measurement.
>>
>> Add a testcase that verifies that the IMA subsystem has correctly
>> measured the cmdline specified during a kexec.
>>
>> Note that this test does not actually reboot.
>>
>> Signed-off-by: Lachlan Sneff <t-josne@linux.microsoft.com>
> Other than the patch not applying cleanly and leading blanks,
>
> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
diff mbox series

Patch

diff --git a/runtest/ima b/runtest/ima
index 309d47420..5f4b4a7a1 100644
--- a/runtest/ima
+++ b/runtest/ima
@@ -4,4 +4,5 @@  ima_policy ima_policy.sh
 ima_tpm ima_tpm.sh
 ima_violations ima_violations.sh
 ima_keys ima_keys.sh
+ima_kexec ima_kexec.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 db8819a99..926eb8478 100644
--- a/testcases/kernel/security/integrity/ima/README.md
+++ b/testcases/kernel/security/integrity/ima/README.md
@@ -30,6 +30,17 @@  measure func=KEY_CHECK keyrings=key_import_test template=ima-buf
 
 The test also requires loaded policy with `func=KEY_CHECK`, see example in `keycheck.policy`.
 
+### IMA kexec test
+
+This test requires that the ima policy contains:
+```
+measure func=KEXEC_CMDLINE
+```
+
+Even though the test does not actually reboot, it does require a valid,
+signed kernel image. By default, the test will look in `/boot/vmlinuz-$(uname r)`,
+but if no image is accessible there, a valid image be must be placed at `/tmp/Image`.
+
 ## 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_kexec.sh b/testcases/kernel/security/integrity/ima/tests/ima_kexec.sh
new file mode 100644
index 000000000..03caba308
--- /dev/null
+++ b/testcases/kernel/security/integrity/ima/tests/ima_kexec.sh
@@ -0,0 +1,121 @@ 
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2020 Microsoft Corporation
+# Author: Lachlan Sneff <t-josne@linux.microsoft.com>
+#
+# Verify that kexec cmdline is measured correctly.
+
+TST_NEEDS_CMDS="kexec sed xargs printf grep tr"
+TST_CNT=1
+TST_NEEDS_DEVICE=1
+
+. ima_setup.sh
+
+# Since the test is executed inside some sort of
+# separate shell, *most* environment variables are
+# not accessible, so there's no way to set it from
+# the outside.
+#
+# `/boot/vmlinuz-$(uname-r)` is where the image is
+# located on many systems, but not all. Therefore,
+# if the image is not located there, require the
+# user to copy it to `/tmp/Image`.
+#
+# Ideally, this test shouldn't even require an image,
+# since it doesn't actually reboot, but the IMA cmdline
+# measurement occurs after the image is parsed and
+# verified, so we must pass a valid kernel image. There
+# is a possiblity of putting together a "faux" kernel
+# image that has the right headers and appears to be
+# signed correctly, but doesn't actually contain any
+# code, but, after investigating that possiblity, it
+# appears to be quite difficult (and would require a
+# new faux kernel for each arch).
+IMAGE="/boot/vmlinuz-$(uname -r)"
+if [ ! -f $IMAGE ]; then
+    IMAGE="/tmp/Image"
+fi
+
+measure() {
+    local found temp_file="file.txt" temp_file2="file2.txt" algorithm \
+        digest expected_digest
+
+    echo -n "$1" > $temp_file
+    grep "kexec-cmdline" $ASCII_MEASUREMENTS > $temp_file2
+
+    while read found
+    do
+        algorithm=$(echo "$found" | cut -d' ' -f4 | cut -d':' -f1)
+        digest=$(echo "$found" | cut -d' ' -f4 | cut -d':' -f2)
+
+        expected_digest=$(compute_digest $algorithm $temp_file)
+
+        if [ "$digest" = "$expected_digest" ]; then
+            return 0
+        fi
+    done < $temp_file2
+
+    return 1
+}
+
+# Test that the kexec cmdline is measured correctly.
+# NOTE: This does *not* actually reboot.
+test1() {
+    # Strip the `BOOT_IMAGE=...` part from the cmdline.
+    local cmdline="$(sed 's/BOOT_IMAGE=[^ ]* //' /proc/cmdline)"
+
+    if ! kexec -sl $IMAGE --reuse-cmdline; then
+        tst_res TCONF "kexec failed: $?"
+        
+        local sb_status="$(bootctl status 2>/dev/null | grep 'Secure Boot' \
+            | tr -d ' ' | sed 's/SecureBoot:*//')"
+        
+        if [ "$sb_status" = "enabled" ]; then
+            tst_res TINFO "secure boot is enabled, the specified kernel image may not be signed"
+        fi
+
+        return
+    fi
+
+    kexec -u
+
+    if ! measure "$cmdline"; then
+        tst_res TFAIL "unable to find a correct entry in the IMA log"
+        
+        if [ ! -r $IMA_POLICY ]; then
+            tst_brk TCONF "cannot read IMA policy (CONFIG_IMA_READ_POLICY=y required) to give contextual information"
+        fi
+
+        if ! grep "measure func=KEXEC_CMDLINE" $IMA_POLICY >/dev/null; then
+            tst_brk TCONF "The IMA policy does not specify 'measure func=KEXEC_CMDLINE', see IMA test README"
+        fi
+
+        return
+    fi
+
+    cmdline="foo"cmldine
+    if ! kexec -sl $IMAGE --append=$cmdline; then
+        tst_brk TCONF "kexec failed: $?"
+    fi
+
+    kexec -u
+
+    if ! measure "$cmdline"; then
+        tst_brk TFAIL "unable to find a correct entry in the IMA log"
+    fi
+
+    cmdline="bar"
+    if ! kexec -sl $IMAGE --command-line=$cmdline; then
+        tst_brk TCONF "kexec failed: $?"
+    fi
+    
+    kexec -u
+
+    if ! measure "$cmdline"; then
+        tst_brk TFAIL "unable to find a correct entry in the IMA log"
+    fi
+
+    tst_res TPASS "kexec cmdline was measured correctly"
+}
+
+tst_run