]> git.apps.os.sepia.ceph.com Git - xfstests-dev.git/commitdiff
common/encrypt: use a sub-keyring within the session keyring
authorEric Biggers <ebiggers@google.com>
Thu, 14 Apr 2022 07:19:32 +0000 (00:19 -0700)
committerEryu Guan <guaneryu@gmail.com>
Sun, 17 Apr 2022 12:31:38 +0000 (20:31 +0800)
Make the encryption tests create and use a named keyring "xfstests" in
the session keyring that the tests happen to be running under, rather
than replace the session keyring using 'keyctl new_session'.
Unfortunately, the latter doesn't work when the session keyring is owned
by a non-root user, which (depending on the Linux distro) can happen if
xfstests is run in a sudo "session" rather than in a real root session.

This isn't a great solution, as the lifetime of the keyring will no
longer be tied to the tests as it should be, but it should work.  The
alternative would be the weird hack of making the 'check' script
re-execute itself using something like 'keyctl session - $0 $@'.

Reported-by: Ritesh Harjani <ritesh.list@gmail.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
12 files changed:
common/encrypt
tests/ext4/024
tests/generic/397
tests/generic/398
tests/generic/399
tests/generic/419
tests/generic/421
tests/generic/429
tests/generic/435
tests/generic/440
tests/generic/576
tests/generic/593

index 3e8c7fd3908f6b871b8be70fbe1cc7e62a492813..8f3c46f642082f0eef8390d8006806b0966445d0 100644 (file)
@@ -121,7 +121,7 @@ _require_encryption_policy_support()
                local keyspec=$(_add_enckey $mnt "$raw_key" | awk '{print $NF}')
        else
                _require_command "$KEYCTL_PROG" keyctl
-               _new_session_keyring
+               _init_session_keyring
                local keyspec=$(_generate_session_encryption_key)
        fi
        if _set_encpolicy $dir $keyspec $set_encpolicy_args \
@@ -138,7 +138,7 @@ _require_encryption_policy_support()
                _notrun "encryption policy '$set_encpolicy_args' is unusable; probably missing kernel crypto API support"
        fi
        if (( policy_version <= 1 )); then
-               $KEYCTL_PROG clear @s
+               $KEYCTL_PROG clear $TEST_KEYRING_ID
        fi
        rm -r $dir
 }
@@ -199,11 +199,30 @@ TEST_KEY_DESCRIPTOR="0000111122223333"
 # Key identifier: HKDF-SHA512(key=$TEST_RAW_KEY, salt="", info="fscrypt\0\x01")
 TEST_KEY_IDENTIFIER="69b2f6edeee720cce0577937eb8a6751"
 
-# Give the invoking shell a new session keyring.  This makes any keys we add to
-# the session keyring scoped to the lifetime of the test script.
-_new_session_keyring()
+# This is the ID of the keyring that was created by _init_session_keyring().
+# You must call _init_session_keyring() before using this.
+TEST_KEYRING_ID=
+
+# Create a test keyring within the session keyring.  Keys added to this keyring
+# will be available within the test script and all its subprocesses.  If the
+# test keyring already exists, then it is replaced.
+#
+# This used to use 'keyctl new_session' to replace the session keyring itself.
+# However, that doesn't work if a non-root user owns the session keyring.
+_init_session_keyring()
 {
-       $KEYCTL_PROG new_session >>$seqres.full
+       TEST_KEYRING_ID=$($KEYCTL_PROG newring xfstests @s)
+       if [ -z "$TEST_KEYRING_ID" ]; then
+               _fail "Failed to create test keyring in session keyring"
+       fi
+}
+
+# Check that _init_session_keyring() has been called.
+_check_session_keyring()
+{
+       if [ -z "$TEST_KEYRING_ID" ]; then
+               _fail "_init_session_keyring() must be called before using the test keyring"
+       fi
 }
 
 # Generate a key descriptor (16 character hex string)
@@ -276,6 +295,8 @@ _add_session_encryption_key()
        local keydesc=$1
        local raw=$2
 
+       _check_session_keyring
+
        #
        # Add the key to the session keyring.  The required structure is:
        #
@@ -291,14 +312,14 @@ _add_session_encryption_key()
        local size=$(_num_to_hex 64 4)
        local prefix=$(_get_fs_keyprefix)
        echo -n -e "${mode}${raw}${size}" |
-               $KEYCTL_PROG padd logon $prefix:$keydesc @s >>$seqres.full
+               $KEYCTL_PROG padd logon $prefix:$keydesc $TEST_KEYRING_ID \
+                       >>$seqres.full
 }
 
 #
 # Generate a random encryption key, add it to the session keyring, and print out
 # the resulting key descriptor (example: "8bf798e1a494e1ec").  Requires the
-# keyctl program.  It's assumed the caller has already set up a test-scoped
-# session keyring using _new_session_keyring.
+# keyctl program and that _init_session_keyring() has been called.
 #
 _generate_session_encryption_key()
 {
@@ -313,18 +334,20 @@ _generate_session_encryption_key()
 # Unlink an encryption key from the session keyring, given its key descriptor.
 _unlink_session_encryption_key()
 {
+       _check_session_keyring
        local keydesc=$1
        local prefix=$(_get_fs_keyprefix)
-       local keyid=$($KEYCTL_PROG search @s logon $prefix:$keydesc)
+       local keyid=$($KEYCTL_PROG search $TEST_KEYRING_ID logon $prefix:$keydesc)
        $KEYCTL_PROG unlink $keyid >>$seqres.full
 }
 
 # Revoke an encryption key from the session keyring, given its key descriptor.
 _revoke_session_encryption_key()
 {
+       _check_session_keyring
        local keydesc=$1
        local prefix=$(_get_fs_keyprefix)
-       local keyid=$($KEYCTL_PROG search @s logon $prefix:$keydesc)
+       local keyid=$($KEYCTL_PROG search $TEST_KEYRING_ID logon $prefix:$keydesc)
        $KEYCTL_PROG revoke $keyid >>$seqres.full
 }
 
@@ -443,6 +466,8 @@ _add_fscrypt_provisioning_key()
        local type=$2
        local raw=$3
 
+       _check_session_keyring
+
        # The format of the key payload must be:
        #
        #       struct fscrypt_provisioning_key_payload {
@@ -454,7 +479,7 @@ _add_fscrypt_provisioning_key()
        local type_hex=$(_num_to_hex $type 4)
        local reserved=$(_num_to_hex 0 4)
        echo -n -e "${type_hex}${reserved}${raw}" |
-               $KEYCTL_PROG padd fscrypt-provisioning "$desc" @s
+               $KEYCTL_PROG padd fscrypt-provisioning "$desc" $TEST_KEYRING_ID
 }
 
 # Retrieve the encryption nonce of the given inode as a hex string.  The nonce
@@ -618,7 +643,7 @@ _require_get_ciphertext_filename_support()
                _require_command "$DUMP_F2FS_PROG" dump.f2fs
                _require_command "$KEYCTL_PROG" keyctl
                _scratch_mount
-               _new_session_keyring
+               _init_session_keyring
 
                local keydesc=$(_generate_session_encryption_key)
                local dir=$SCRATCH_MNT/test.${FUNCNAME[0]}
@@ -629,7 +654,7 @@ _require_get_ciphertext_filename_support()
                local inode=$(stat -c %i $file)
 
                _scratch_unmount
-               $KEYCTL_PROG clear @s
+               $KEYCTL_PROG clear $TEST_KEYRING_ID
 
                # 255-character filename should result in 340 base64 characters.
                if ! $DUMP_F2FS_PROG -i $inode $SCRATCH_DEV \
@@ -912,7 +937,7 @@ _verify_ciphertext_for_encryption_policy()
                                | awk '{print $NF}')
        else
                local keyspec=$(_generate_key_descriptor)
-               _new_session_keyring
+               _init_session_keyring
                _add_session_encryption_key $keyspec $raw_key
        fi
        local raw_key_hex=$(echo "$raw_key" | tr -d '\\x')
index 116adca950770af3d58d03094a1870af8040a8c0..11b335f0ba62611d50ae985208dc60fea1c79225 100755 (executable)
@@ -18,7 +18,7 @@ _supported_fs ext4
 _require_scratch_encryption
 _require_command "$KEYCTL_PROG" keyctl
 
-_new_session_keyring
+_init_session_keyring
 
 #
 # Create an encrypted file whose size is not a multiple of the filesystem block
index 5ff65cd948ed1e72b9acfd9736f50e1998dc0e93..6c03f274db5e3b92301b38d59f181f41ae9d7b19 100755 (executable)
@@ -23,7 +23,7 @@ _require_symlinks
 _require_scratch_encryption
 _require_command "$KEYCTL_PROG" keyctl
 
-_new_session_keyring
+_init_session_keyring
 
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
index 506513c10bcdff7e5affdb36aac2ca4743a55c58..e2cbad54422079abaf9833d882a4aee48146bd01 100755 (executable)
@@ -24,7 +24,7 @@ _supported_fs generic
 _require_scratch_encryption
 _require_renameat2 exchange
 
-_new_session_keyring
+_init_session_keyring
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 
index 55f07ae575c2fed047fcbdad5afef9f05970fcbe..a5aa7107d0d60810dd69e47c3dcea1fa64c1d48a 100755 (executable)
@@ -30,7 +30,7 @@ _require_symlinks
 _require_command "$XZ_PROG" xz
 _require_command "$KEYCTL_PROG" keyctl
 
-_new_session_keyring
+_init_session_keyring
 
 #
 # Set up a small filesystem containing an encrypted directory.  64 MB is enough
index 6be7865ccce313ad4bf68b746736516514f0868c..5d56d64fc50f286d40dd9b1c934935d3d06f60dd 100755 (executable)
@@ -24,7 +24,7 @@ _require_scratch_encryption
 _require_command "$KEYCTL_PROG" keyctl
 _require_renameat2 exchange
 
-_new_session_keyring
+_init_session_keyring
 
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
index 04462d1707510d92d5e77f1f7e0cf00e96cbf923..0c4fa8e3e0f530b382f2206a90e1c6fd070466ca 100755 (executable)
@@ -20,7 +20,7 @@ _supported_fs generic
 _require_scratch_encryption
 _require_command "$KEYCTL_PROG" keyctl
 
-_new_session_keyring
+_init_session_keyring
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 
index 558e93ca9f312fe4a650273f2206e5d908374d76..2cf12316d5a417d0d2d3611b82154e24e747977f 100755 (executable)
@@ -35,7 +35,7 @@ _require_test_program "t_encrypted_d_revalidate"
 # Set up an encrypted directory
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
-_new_session_keyring
+_init_session_keyring
 keydesc=$(_generate_key_descriptor)
 raw_key=$(_generate_raw_encryption_key)
 mkdir $SCRATCH_MNT/edir
index 031e43cc87e5aa37e1a136d17d2db288ba67b501..bb1cbb62b0b0e3394a78c63168b8aef291470528 100755 (executable)
@@ -29,7 +29,7 @@ _require_command "$KEYCTL_PROG" keyctl
 
 # set up an encrypted directory
 
-_new_session_keyring
+_init_session_keyring
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 mkdir $SCRATCH_MNT/edir
index f445a3861313bab757972ffda4e8d96dcfc3c181..5850a8fef1bd810037aa3237a6ff2d15382bbe2a 100755 (executable)
@@ -25,7 +25,7 @@ _require_symlinks
 _require_command "$KEYCTL_PROG" keyctl
 
 # Set up an encryption-capable filesystem and an encryption key.
-_new_session_keyring
+_init_session_keyring
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 keydesc=$(_generate_key_descriptor)
index 82fbdd7180ad8cf24ba45ac1764ff988cfd16273..3ef04953a27cc3544deeff511546e05e85104721 100755 (executable)
@@ -38,7 +38,7 @@ edir=$SCRATCH_MNT/edir
 fsv_file=$edir/file.fsv
 
 # Set up an encrypted directory.
-_new_session_keyring
+_init_session_keyring
 keydesc=$(_generate_session_encryption_key)
 mkdir $edir
 _set_encpolicy $edir $keydesc
index f0610c5794502465503100e6586ef3ab9050fa85..2dda5d7651dcfb915b8ee6a555f32dac808dcb69 100755 (executable)
@@ -20,7 +20,7 @@ _supported_fs generic
 _require_scratch_encryption -v 2
 _require_command "$KEYCTL_PROG" keyctl
 
-_new_session_keyring
+_init_session_keyring
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 _require_add_enckey_by_key_id $SCRATCH_MNT
@@ -113,25 +113,26 @@ echo -e "\n# keyctl_read() doesn't work on fscrypt-provisioning keys"
 keyid=$(_add_fscrypt_provisioning_key desc $FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR \
        "$TEST_RAW_KEY")
 $KEYCTL_PROG read $keyid
-$KEYCTL_PROG unlink $keyid @s
+$KEYCTL_PROG unlink $keyid $TEST_KEYRING_ID
 
 echo -e "\n# Only keys with the correct fscrypt_provisioning_key_payload::type field can be added"
 echo "# ... keyring key is v1, filesystem wants v2 key"
 keyid=$(_add_fscrypt_provisioning_key desc $FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR \
        "$TEST_RAW_KEY")
 $XFS_IO_PROG -c "add_enckey -k $keyid" $SCRATCH_MNT
-$KEYCTL_PROG unlink $keyid @s
+$KEYCTL_PROG unlink $keyid $TEST_KEYRING_ID
 
 echo "# ... keyring key is v2, filesystem wants v1 key"
 keyid=$(_add_fscrypt_provisioning_key desc $FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER \
        "$TEST_RAW_KEY")
 $XFS_IO_PROG -c "add_enckey -k $keyid -d $TEST_KEY_DESCRIPTOR" $SCRATCH_MNT
-$KEYCTL_PROG unlink $keyid @s
+$KEYCTL_PROG unlink $keyid $TEST_KEYRING_ID
 
 echo -e "\n# Only keys of type fscrypt-provisioning can be added"
-keyid=$(head -c 64 /dev/urandom | $KEYCTL_PROG padd logon foo:desc @s)
+keyid=$(head -c 64 /dev/urandom | \
+       $KEYCTL_PROG padd logon foo:desc $TEST_KEYRING_ID)
 $XFS_IO_PROG -c "add_enckey -k $keyid" $SCRATCH_MNT
-$KEYCTL_PROG unlink $keyid @s
+$KEYCTL_PROG unlink $keyid $TEST_KEYRING_ID
 
 # success, all done
 status=0