Message ID | 20200722184739.19460-1-t-josne@linux.microsoft.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v3] IMA: Add test for kexec cmdline measurement | expand |
Hi, ... > +++ 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. Do you mean that using this will not work? IMA_KEXEC_IMAGE="${IMA_KEXEC_IMAGE:-/boot/vmlinuz-$(uname -r)}" I don't understand that as I'm able to set variables even I run some tests in dracut. Also writing same docs doc on 2 places is not good. High level info should go to README.md, implementation details to shell script. Please hold on with posting new version. I have several fixes, thus I'd like to send it after we sort this (trying to save you time). Kind regards, Petr
Hi Petr, Thank you for reviewing On 7/23/20 7:46 AM, Petr Vorel wrote: > Hi, > > ... >> +++ 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. > Do you mean that using this will not work? > IMA_KEXEC_IMAGE="${IMA_KEXEC_IMAGE:-/boot/vmlinuz-$(uname -r)}" > I don't understand that as I'm able to set variables even I run some tests in > dracut. I tried doing this in the past, and couldn't get it to work, but I just tried it again and was able to get it working. Essentially, what I tried before was `SOME_VAR="..." sudo runltp ...`, which doesn't work, but `sudo SOME_VAR="..." runltp` does pass the variable to the test. So, that should be added to this patch. > > Also writing same docs doc on 2 places is not good. High level info should go to > README.md, implementation details to shell script. This is a good point. I'll reorganize the documentation of this patch. > Please hold on with posting new version. I have several fixes, thus I'd like to > send it after we sort this (trying to save you time). Okay :) > Kind regards, > Petr Thanks, Lachlan
> Hi Petr, > Thank you for reviewing Thanks for your time as well :). > On 7/23/20 7:46 AM, Petr Vorel wrote: > > Hi, > > ... > > > +++ 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. > > Do you mean that using this will not work? > > IMA_KEXEC_IMAGE="${IMA_KEXEC_IMAGE:-/boot/vmlinuz-$(uname -r)}" > > I don't understand that as I'm able to set variables even I run some tests in > > dracut. > I tried doing this in the past, and couldn't get it to work, but I just > tried it again > and was able to get it working. Essentially, what I tried before was > `SOME_VAR="..." sudo runltp ...`, which doesn't work, but `sudo > SOME_VAR="..." runltp` does pass the variable > to the test. So, that should be added to this patch. OK, so no any dracut / initramfs involved :). Passing variables really works as expected, you need to export it first: $ sudo su # export IMA_KEXEC_IMAGE=/tmp/foo # PATH="/opt/ltp/testcases/bin:$PATH" runltp ... or just run the script directly: $ sudo su # IMA_KEXEC_IMAGE=/tmp/foo PATH="/opt/ltp/testcases/bin:$PATH" ima_kexec.sh > > Also writing same docs doc on 2 places is not good. High level info should go to > > README.md, implementation details to shell script. > This is a good point. I'll reorganize the documentation of this patch. > > Please hold on with posting new version. I have several fixes, thus I'd like to > > send it after we sort this (trying to save you time). > Okay :) > > Kind regards, > > Petr > Thanks, > Lachlan Kind regards, Petr
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..7e3ecaec8 --- /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 -su + + 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" + if ! kexec -sl $IMAGE --append=$cmdline; then + tst_brk TCONF "kexec failed: $?" + fi + + kexec -su + + 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 -su + + 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
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