Imported Upstream version 2.6.1
[platform/upstream/cryptsetup.git] / tests / verity-compat-test
index 7f381e7..8a28a12 100755 (executable)
@@ -6,6 +6,7 @@ VERITYSETUP_VALGRIND=../.libs/veritysetup
 VERITYSETUP_LIB_VALGRIND=../.libs
 
 DEV_NAME=verity3273
+DEV_NAME2=verity3273x
 DEV_OUT="$DEV_NAME.out"
 IMG=verity-data
 IMG_HASH=verity-hash
@@ -17,9 +18,10 @@ DEV_UUID=a60c98d2-ae9b-4865-bfcb-b4e3ace11033
 
 function remove_mapping()
 {
+       [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2 >/dev/null 2>&1
        [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME >/dev/null 2>&1
        [ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1
-       rm -f $IMG $IMG_HASH $DEV_OUT $FEC_DEV $IMG_TMP  >/dev/null 2>&1
+       rm -f $IMG $IMG.roothash $IMG_HASH $DEV_OUT $FEC_DEV $IMG_TMP >/dev/null 2>&1
        LOOPDEV1=""
        LOOPDEV2=""
 }
@@ -87,8 +89,7 @@ function compare_out() # $1 what, $2 expected
 function check_root_hash_fail()
 {
        echo -n "Root hash check "
-       ARR=(`$VERITYSETUP format $IMG $IMG_HASH --fec-device $FEC_DEV --fec-roots 2 -h sha256`)
-       ROOT_HASH=${ARR[28]}
+       ROOT_HASH=$($VERITYSETUP format $IMG $IMG_HASH --fec-device $FEC_DEV --fec-roots 2 -h sha256 | grep -e "Root hash" | cut -d: -f2 | tr -d "\t\n ")
        ROOT_HASH_BAD=abcdef0000000000000000000000000000000000000000000000000000000000
 
        $VERITYSETUP verify $IMG $IMG_HASH $ROOT_HASH || fail
@@ -97,11 +98,13 @@ function check_root_hash_fail()
 
        $VERITYSETUP open $IMG $DEV_NAME $IMG_HASH $ROOT_HASH || fail
        check_exists
+       dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=4096 count=1 >/dev/null 2>&1
        dmsetup status $DEV_NAME | grep "verity V" >/dev/null || fail
        $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail
 
        $VERITYSETUP open $IMG $DEV_NAME $IMG_HASH $ROOT_HASH_BAD >/dev/null 2>&1 || fail
        check_exists
+       dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=4096 count=1 >/dev/null 2>&1
        dmsetup status $DEV_NAME | grep "verity C" >/dev/null || fail
        $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail
 
@@ -110,6 +113,10 @@ function check_root_hash_fail()
 
 function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6 offset]
 {
+       local FORMAT_PARAMS
+       local VERIFY_PARAMS
+       local ROOT_HASH
+
        if [ -z "$LOOPDEV2" ] ; then
                BLOCKS=$(($6 / $1))
                DEV_PARAMS="$LOOPDEV1 $LOOPDEV1 \
@@ -119,6 +126,7 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6
                DEV_PARAMS="$LOOPDEV1 $LOOPDEV2"
        fi
 
+       for root_hash_as_file in yes no; do
        for sb in yes no; do
        FORMAT_PARAMS="--format=$4 --data-block-size=$1 --hash-block-size=$1 --hash=$5 --salt=$3"
        if [ $sb == yes ] ; then
@@ -127,20 +135,34 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6
                FORMAT_PARAMS="$FORMAT_PARAMS --no-superblock"
                VERIFY_PARAMS=$FORMAT_PARAMS
        fi
+       if [ $root_hash_as_file == yes ] ; then
+               echo -n $2 > $IMG.roothash
+               FORMAT_PARAMS="$FORMAT_PARAMS --root-hash-file=$IMG.roothash"
+               VERIFY_PARAMS="$VERIFY_PARAMS --root-hash-file=$IMG.roothash"
+               ROOT_HASH=""
+       else
+               ROOT_HASH="$2"
+       fi
 
        for fail in data hash; do
        wipe
-       echo -n "V$4(sb=$sb) $5 block size $1: "
-       $VERITYSETUP format $DEV_PARAMS $FORMAT_PARAMS >$DEV_OUT || fail
+       echo -n "V$4(sb=$sb root_hash_as_file=$root_hash_as_file) $5 block size $1: "
+       $VERITYSETUP format $DEV_PARAMS $FORMAT_PARAMS >$DEV_OUT
+       if [ $? -ne 0 ] ; then
+               if [[ $1 =~ "sha2" ]] ; then
+                       fail "Cannot format device."
+               fi
+               return
+       fi
 
        echo -n "[root hash]"
        compare_out "root hash" $2
        compare_out "salt" "$3"
 
-       $VERITYSETUP verify $DEV_PARAMS $VERIFY_PARAMS $2 >>$DEV_OUT 2>&1 || fail
+       $VERITYSETUP verify $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH >>$DEV_OUT 2>&1 || fail
        echo -n "[verify]"
 
-       $VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $2  >>$DEV_OUT 2>&1 || fail
+       $VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH  >>$DEV_OUT 2>&1 || fail
        check_exists
        echo -n "[activate]"
 
@@ -165,9 +187,9 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6
                ;;
        esac
 
-       $VERITYSETUP verify $DEV_PARAMS $VERIFY_PARAMS $2 >>$DEV_OUT 2>&1 && \
+       $VERITYSETUP verify $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH >>$DEV_OUT 2>&1 && \
                fail "userspace check for $TXT corruption"
-       $VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $2 >>$DEV_OUT 2>&1 || \
+       $VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH >>$DEV_OUT 2>&1 || \
                fail "activation"
        dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=$1 2>/dev/null
        dmsetup status $DEV_NAME | grep "verity V" >/dev/null && \
@@ -176,6 +198,7 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6
        echo "[$TXT corruption]"
        done
        done
+       done
 }
 
 function corrupt_device() # $1 device, $2 device_size(in bytes), $3 #{corrupted_bytes}
@@ -217,24 +240,20 @@ function check_fec()
        if [ "${11}" == "n" ]; then
                INDEX=24
                echo -n "[no-superblock]"
-               PARAMS="$PARAMS --no-superblock -s=${12}"
+               PARAMS="$PARAMS --no-superblock --salt=${12}"
        elif [ -n "${12}" ]; then
-               PARAMS="$PARAMS -s=${12}"
+               PARAMS="$PARAMS --salt=${12}"
        fi
 
        if [[ "$1" == "$2" && "$1" == "$3" ]]; then
                echo -n "[one_device_test]"
                dd if=/dev/zero of=$IMG_TMP bs=$4 count=$5  > /dev/null 2>&1
-               ARR=(`sha256sum $IMG_TMP`)
-               HASH_ORIG=${ARR[0]}
+               HASH_ORIG=$(sha256sum $IMG_TMP | cut -d' ' -f 1)
        else
-               ARR=(`sha256sum $1`)
-               HASH_ORIG=${ARR[0]}
+               HASH_ORIG=$(sha256sum $1 | cut -d' ' -f 1)
        fi
 
-       ARR=(`$VERITYSETUP format $1 $2 --fec-device=$3 $PARAMS`)
-       SALT=${ARR[$INDEX]}
-       ROOT_HASH=${ARR[$(($INDEX+3))]}
+       ROOT_HASH=$($VERITYSETUP format $1 $2 --fec-device=$3 $PARAMS | grep -e "Root hash" | cut -d: -f2 | tr -d "\t\n ")
 
        corrupt_device $1 $(($5 * $4)) ${10}
 
@@ -244,12 +263,10 @@ function check_fec()
                return 3
        fi
 
-       udevadm settle
+       udevadm settle > /dev/null 2>&1
 
        dd if=/dev/mapper/$DEV_NAME of=$IMG_TMP > /dev/null 2>&1
-       ARR=(`sha256sum $IMG_TMP`)
-
-       HASH_REPAIRED=${ARR[0]}
+       HASH_REPAIRED=$(sha256sum $IMG_TMP | cut -d' ' -f 1)
 
        $VERITYSETUP close $DEV_NAME
 
@@ -261,11 +278,11 @@ function check_fec()
        else
                echo -n "[repaired in kernel]"
                $VERITYSETUP verify $1 $2 $ROOT_HASH --fec-device=$3 $PARAMS >/dev/null 2>&1 || fail "Userspace verify failed"
-                echo "[userspace verify][OK]"
-                RET=0
-       fi
+               echo "[userspace verify][OK]"
+               RET=0
+       fi
        rm $1 $2 $3 $IMG_TMP > /dev/null 2>&1
-       return $RET
+       return $RET
 }
 
 function check_option() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, $6 CLI option, $7 status option
@@ -285,7 +302,7 @@ function check_option() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, $6 CLI
 
 function valgrind_setup()
 {
-       which valgrind >/dev/null 2>&1 || fail "Cannot find valgrind."
+       command -v valgrind >/dev/null || fail "Cannot find valgrind."
        [ ! -f $VERITYSETUP_VALGRIND ] && fail "Unable to get location of veritysetup executable."
        export LD_LIBRARY_PATH="$VERITYSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
 }
@@ -362,8 +379,7 @@ function checkUserSpaceRepair()
 
        echo -n "[nroots::$3]"
 
-       ARR=(`$VERITYSETUP format $IMG $HASH_DEV --fec-device $FEC $PARAMS --salt=$DEV_SALT --uuid=$DEV_UUID`)
-       ROOT_HASH=${ARR[28]}
+       ROOT_HASH=$($VERITYSETUP format $IMG $HASH_DEV --fec-device $FEC $PARAMS --salt=$DEV_SALT --uuid=$DEV_UUID | grep -e "Root hash" | cut -d: -f2 | tr -d "\t\n ")
 
        echo -n "[Errors can be corrected]"
        corrupt_device $IMG $(($BS*$COUNT)) $7
@@ -380,6 +396,33 @@ function checkUserSpaceRepair()
        echo "[OK]"
 }
 
+function check_concurrent() # $1 hash
+{
+       DEV_PARAMS="$LOOPDEV1 $LOOPDEV2"
+
+       # First check that with two sequential opens, we are returning the expected -EEXIST
+       $VERITYSETUP format $DEV_PARAMS >/dev/null 2>&1 || fail
+       $VERITYSETUP create $DEV_NAME $DEV_PARAMS $1 >/dev/null 2>&1 || fail
+       check_exists
+       $VERITYSETUP create $DEV_NAME $DEV_PARAMS $1 2>&1 >/dev/null | grep -q "Device $DEV_NAME already exists" || fail
+       $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail
+
+       # Then do two concurrent opens, and check that libdevmapper did not return -EINVAL, which is
+       # not gracefully recoverable. Either could fail depending on scheduling, so just check that
+       # the libdevmapper error does not appear in either of the outputs.
+       cat /dev/null >$DEV_OUT
+       $VERITYSETUP create -v $DEV_NAME $DEV_PARAMS $1 >>$DEV_OUT 2>&1 &
+       $VERITYSETUP create -v $DEV_NAME $DEV_PARAMS $1 >>$DEV_OUT 2>&1 &
+       wait
+       grep -q "Command failed with code .* (wrong or missing parameters)" $DEV_OUT && fail
+       check_exists
+       rm $DEV_OUT
+       $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail
+
+       echo "[OK]"
+}
+
+export LANG=C
 [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
 [ ! -x "$VERITYSETUP" ] && skip "Cannot find $VERITYSETUP, test skipped."
 
@@ -434,6 +477,11 @@ if check_version 1 3; then
        if check_version 1 7; then
                check_option 512 $HASH $SALT 1 sha256 "--panic-on-corruption" "panic_on_corruption"
        fi
+
+       if check_version 1 9; then
+               echo "Verity data performance options test."
+               check_option 512 $HASH $SALT 1 sha256 "--use-tasklets" "try_verify_in_tasklet"
+       fi
 fi
 
 echo "Veritysetup [hash-offset bigger than 2G works] "
@@ -480,5 +528,32 @@ checkUserSpaceRepair -1  4096 2 0       0       3 10
 checkUserSpaceRepair 400 4096 2 2048000 0       2 1
 checkUserSpaceRepair 500 4096 2 2457600 4915200 1 2
 
+echo -n "Verity concurrent opening tests:"
+prepare 8192 1024
+check_concurrent 9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174
+
+echo -n "Deferred removal of device:"
+prepare 8192 1024
+$VERITYSETUP format $LOOPDEV1 $IMG_HASH --format=1 --data-block-size=512 --hash-block-size=512 --hash=sha256 --salt=$SALT >/dev/null 2>&1 || fail "Cannot format device."
+$VERITYSETUP open $LOOPDEV1 $DEV_NAME $DEV $IMG_HASH 9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174 || fail "Cannot activate device."
+dmsetup create $DEV_NAME2 --table "0 8 linear /dev/mapper/$DEV_NAME 0"
+[ ! -b /dev/mapper/$DEV_NAME2 ] && fail
+$VERITYSETUP close $DEV_NAME >/dev/null 2>&1 && fail
+$VERITYSETUP status $DEV_NAME >/dev/null 2>&1 || fail
+$VERITYSETUP close --deferred $DEV_NAME >/dev/null 2>&1
+if [ $? -eq 0 ] ; then
+       dmsetup info $DEV_NAME | grep -q "DEFERRED REMOVE" || fail
+       $VERITYSETUP close --cancel-deferred $DEV_NAME >/dev/null 2>&1
+       dmsetup info $DEV_NAME | grep -q "DEFERRED REMOVE" >/dev/null 2>&1 && fail
+       $VERITYSETUP close --deferred $DEV_NAME >/dev/null 2>&1
+       dmsetup remove $DEV_NAME2 || fail
+       $VERITYSETUP status $DEV_NAME >/dev/null 2>&1 && fail
+       echo "[OK]"
+else
+       dmsetup remove $DEV_NAME2 >/dev/null 2>&1
+       $VERITYSETUP close $DEV_NAME >/dev/null 2>&1
+       echo "[N/A]"
+fi
+
 remove_mapping
 exit 0