On Wed, 2019-01-09 at 10:54 -0700, Dave Jiang wrote:
> Add unit test for security enable, disable, update, erase, unlock, and
> freeze.
> 
> Signed-off-by: Dave Jiang <[email protected]>
> ---
>  test/Makefile.am |    4 +
>  test/security.sh |  203 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 207 insertions(+)
>  create mode 100755 test/security.sh
> 
> diff --git a/test/Makefile.am b/test/Makefile.am
> index ebdd23f6..42009c31 100644
> --- a/test/Makefile.am
> +++ b/test/Makefile.am
> @@ -27,6 +27,10 @@ TESTS =\
>       max_available_extent_ns.sh \
>       pfn-meta-errors.sh
>  
> +if ENABLE_KEYUTILS
> +TESTS += security.sh
> +endif
> +
>  check_PROGRAMS =\
>       libndctl \
>       dsm-fail \
> diff --git a/test/security.sh b/test/security.sh
> new file mode 100755
> index 00000000..1dbe04d2
> --- /dev/null
> +++ b/test/security.sh
> @@ -0,0 +1,203 @@
> +#!/bin/bash -Ex
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright(c) 2018 Intel Corporation. All rights reserved.
> +
> +rc=77
> +dev=""
> +id=""
> +dev_no=""
> +keypath="/etc/ndctl/keys"
> +masterkey="nvdimm-master-test"
> +masterpath="$keypath/$masterkey"
> +keyctl="/usr/bin/keyctl"

Hm, no need to hard-code the path for keyctl, it should be in the $PATH

> +
> +. ./common
> +
> +lockpath="/sys/devices/platform/${NFIT_TEST_BUS0}/nfit_test_dimm/test_dimm"
> +
> +trap 'err $LINENO' ERR
> +
> +check_prereq()
> +{
> +     if [ ! -f "$keyctl" ]; then
> +             echo "$keyctl does not exist."
> +             exit 1
> +     fi

And then instead of checking for the path here, test/common already has
a function for checking the presence of system utilities, just use
that. In fact that function is called check_prereq, so let us not
duplicate the name.

The keypath check below is still valid.

> +
> +     if [ ! -d "$keypath" ]; then
> +             echo "$keypath directory does not exist."
> +             exit 1
> +     fi
> +}
> +
> +setup()
> +{
> +     $NDCTL disable-region -b "$NFIT_TEST_BUS0" all
> +}
> +
> +detect()
> +{
> +     dev=$($NDCTL list -b "$NFIT_TEST_BUS0" -D | jq .[0].dev | tr -d '"')
> +     [ -n "$dev" ] || err "$LINENO"
> +     id=$($NDCTL list -b "$NFIT_TEST_BUS0" -D | jq .[0].id | tr -d '"')

Quote these command substitutions as well "$(...)"

Also, this applies to several existing tests, I'm sure, and that
cleanup can happen later..
But every jq query doesn't need to be appended with | tr -d '"' to
remove the quotes. jq has a '-r' option to do exactly that.

Maybe the 3 spots in this file where jq | tr is used can be corrected
as a start :)

> +     [ -n "$id" ] || err "$LINENO"
> +}
> +
> +setup_keys()
> +{
> +     if [ ! -f "$masterpath" ]; then
> +             keyctl add user $masterkey "$(dd if=/dev/urandom bs=1 count=32 
> 2>/dev/null)" @u
> +             keyctl pipe "$(keyctl search @u user $masterkey)" > $masterpath

Quotes around $masterkey and $masterpath

We defined $keyctl with a fixed path, but are just calling it directly
from the system PATH :)
Just just check_prereq from test/common to check for keyctl's presence,
and then use keyctl directly (like you do here).

> +     else
> +             echo "Unclean setup. Please cleanup $masterpath file."

Can't the test just perform this cleanup before it starts?

> +             exit 1
> +     fi
> +}
> +
> +test_cleanup()
> +{
> +     keyctl unlink "$(keyctl search @u encrypted nvdimm:"$id")"
> +     keyctl unlink "$(keyctl search @u user $masterkey)"
> +     rm -f "$keypath"/nvdimm_"$id"\_"$(hostname)".blob

The underscore shouldn't need to be escaped?
You can also quote the whole thing at once instead of each variable,
looks much cleaner:

rm -f "${keypath}/nvdimm_${id}_$(hostname).blob"


> +     rm -f "$masterpath"
> +}
> +
> +lock_dimm()
> +{
> +     $NDCTL disable-dimm "$dev"
> +     dev_no="$(echo "$dev" | cut -b 5-)"

I was going to say 'useless use of echo' -- you can do:

        dev_no="$(cut -b 5- <<< "$dev")"

but there is really no need to call spawn a subshell to call cut
either, bash can do this directly by parameter expansion:

if dev is set to "dimm0", then:

        dev_no="${dev#dimm}"

will drop the 'dimm' from $dev and yield '0'

> +     echo 1 > "${lockpath}${dev_no}/lock_dimm"
> +     sstate="$(get_security_state)"
> +     if [ "$sstate" != "locked" ]; then
> +             echo "Incorrect security state: $sstate expected: disabled"
> +             exit 1
> +     fi
> +}
> +
> +get_security_state()
> +{
> +     $NDCTL list -i -b "$NFIT_TEST_BUS0" -d "$dev" | jq 
> .[].dimms[0].security | tr -d '"'
> +}
> +
> +enable_passphrase()
> +{
> +     $NDCTL enable-passphrase -m user:"$masterkey" "$dev"
> +     sstate=$(get_security_state)

Quote command substitution

> +     if [ "$sstate" != "unlocked" ]; then
> +             echo "Incorrect security state: $sstate expected: unlocked"
> +             exit 1
> +     fi
> +}
> +
> +disable_passphrase()
> +{
> +     $NDCTL disable-passphrase "$dev"
> +     sstate=$(get_security_state)

Quote command substitution

> +     if [ "$sstate" != "disabled" ]; then
> +             echo "Incorrect security state: $sstate expected: disabled"
> +             exit 1
> +     fi
> +}
> +
> +erase_security()
> +{
> +     $NDCTL sanitize-dimm -c "$dev"
> +     sstate=$(get_security_state)

Quote command substitution
(you get the idea :))

> +     if [ "$sstate" != "disabled" ]; then
> +             echo "Incorrect security state: $sstate expected: disabled"
> +             exit 1
> +     fi
> +}
> +
> +update_security()
> +{
> +     $NDCTL update-passphrase -m user:"$masterkey" "$dev"
> +     sstate=$(get_security_state)
> +     if [ "$sstate" != "unlocked" ]; then
> +             echo "Incorrect security state: $sstate expected: unlocked"
> +             exit 1
> +     fi
> +}
> +
> +freeze_security()
> +{
> +     $NDCTL freeze-security "$dev"
> +}
> +
> +test_1_security_enable_and_disable()
> +{
> +     enable_passphrase
> +     disable_passphrase
> +}
> +
> +test_2_security_enable_and_update()
> +{
> +     enable_passphrase
> +     update_security
> +     disable_passphrase
> +}
> +
> +test_3_security_enable_and_erase()
> +{
> +     enable_passphrase
> +     erase_security
> +}
> +
> +test_4_security_unlocking()

s/unlocking/unlock/

> +{
> +     enable_passphrase
> +     lock_dimm
> +     $NDCTL enable-dimm "$dev"
> +     sstate=$(get_security_state)
> +     if [ "$sstate" != "unlocked" ]; then
> +             echo "Incorrect security state: $sstate expected: unlocked"
> +             exit 1
> +     fi
> +     $NDCTL disable-region -b "$NFIT_TEST_BUS0" all
> +     disable_passphrase
> +}
> +
> +# this should always be the last test. with security frozen, nfit_test must
> +# be removed and is no longer usable
> +test_5_security_freeze()
> +{
> +     enable_passphrase
> +     freeze_security
> +     sstate=$(get_security_state)
> +     if [ "$sstate" != "frozen" ]; then
> +             echo "Incorrect security state: $sstate expected: frozen"
> +             exit 1
> +     fi
> +     $NDCTL disable-passphrase "$dev" && { echo "disable succeed after 
> frozen"; }
> +     sstate=$(get_security_state)
> +     echo "$sstate"
> +     if [ "$sstate" != "frozen" ]; then
> +             echo "Incorrect security state: $sstate expected: disabled"
> +             exit 1
> +     fi
> +}
> +
> +check_min_kver "5.0" || do_skip "may lack security handling"
> +
> +modprobe nfit_test
> +setup
> +check_prereq

After the initial setup set rc=1
This allows err() in test/common to correctly return $rc (77 = skip
test and anything else means failed).

Also in the various tests, don't 'exit 1' directly. Call err $LINENO.
THat way in the run log, we always get the exact failure line.

> +detect
> +setup_keys
> +echo "Test 1, security enable and disable"
> +test_1_security_enable_and_disable
> +echo "Test 2, security enable, update, and disable"
> +test_2_security_enable_and_update
> +echo "Test 3, security enable and erase"
> +test_3_security_enable_and_erase
> +echo "Test 4, unlocking dimm"

s/unlocking/unlock/

> +test_4_security_unlocking
> +
> +# Freeze should always be run last because it locks security state and 
> require
> +# nfit_test module unload.
> +echo "Test 5, freeze security"
> +test_5_security_freeze
> +
> +test_cleanup
> +_cleanup
> +exit 0
> 

_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

Reply via email to