ZTS: testing for leaked key mappings in encrypted non-raw send

This test covers a bug fixed by commit ea74cde: performing an
incremental non-raw send from an encrypted filesystem followed by
exporting the pool. Before that commit, exporting the sending pool
in this scenario would trigger a panic:

VERIFY(avl_is_empty(&sk->sk_dsl_keys)) failed
PANIC at dsl_crypt.c:353:spa_keystore_fini()
Call Trace:
 spl_dumpstack+0x29/0x2f [spl]
 spl_panic+0xd1/0xe9 [spl]
 spl_assert.constprop.0+0x1a/0x30 [zfs]
 spa_keystore_fini+0xc2/0xf0 [zfs]
 spa_deactivate+0x25f/0x610 [zfs]
 spa_evict_all+0xf4/0x200 [zfs]
 spa_fini+0x13/0x140 [zfs]
 zfs_kmod_fini+0x72/0xc0 [zfs]
 openzfs_fini_os+0x13/0x3a [zfs]
 openzfs_fini+0x9/0x6b8 [zfs]

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: George Amanakis <gamanakis@gmail.com>
Closes #17366
This commit is contained in:
George Amanakis 2025-05-24 03:46:51 +02:00 committed by GitHub
parent 92157c840c
commit b01d7bd32d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 84 additions and 1 deletions

View File

@ -956,7 +956,7 @@ tests = ['recv_dedup', 'recv_dedup_encrypted_zvol', 'rsend_001_pos',
'send_spill_block', 'send_holds', 'send_hole_birth', 'send_mixed_raw', 'send_spill_block', 'send_holds', 'send_hole_birth', 'send_mixed_raw',
'send-wR_encrypted_zvol', 'send_partial_dataset', 'send_invalid', 'send-wR_encrypted_zvol', 'send_partial_dataset', 'send_invalid',
'send_doall', 'send_raw_spill_block', 'send_raw_ashift', 'send_doall', 'send_raw_spill_block', 'send_raw_ashift',
'send_raw_large_blocks'] 'send_raw_large_blocks', 'send_leak_keymaps']
tags = ['functional', 'rsend'] tags = ['functional', 'rsend']
[tests/functional/scrub_mirror] [tests/functional/scrub_mirror]

View File

@ -2003,6 +2003,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/rsend/send_holds.ksh \ functional/rsend/send_holds.ksh \
functional/rsend/send_hole_birth.ksh \ functional/rsend/send_hole_birth.ksh \
functional/rsend/send_invalid.ksh \ functional/rsend/send_invalid.ksh \
functional/rsend/send_leak_keymaps.ksh \
functional/rsend/send-L_toggle.ksh \ functional/rsend/send-L_toggle.ksh \
functional/rsend/send_mixed_raw.ksh \ functional/rsend/send_mixed_raw.ksh \
functional/rsend/send_partial_dataset.ksh \ functional/rsend/send_partial_dataset.ksh \

View File

@ -0,0 +1,82 @@
#!/bin/ksh -p
# SPDX-License-Identifier: CDDL-1.0
#
# CDDL HEADER START
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
# CDDL HEADER END
#
#
# Copyright (c) 2025 by George Amanakis. All rights reserved.
#
. $STF_SUITE/tests/functional/rsend/rsend.kshlib
#
# DESCRIPTION:
# Verify that an incremental non-raw zfs send from an encrypted filesystem
# does not leak any keys or key mappings.
#
# STRATEGY:
# 1. Create a new encrypted filesystem
# 2. Write some files and create snapshots.
# 3. Send to a new filesystem
# 4. Do an incremental (-I) send and before that access all properties on the
# sending filesystem (emulate sanoid)
# 5. Export and re-import the pool. Upon exporting the pool if any keys/key
# mappings leaked a panic will occur.
#
verify_runnable "both"
function cleanup
{
datasetexists $TESTPOOL/$TESTFS2 && \
destroy_dataset $TESTPOOL/$TESTFS2 -r
datasetexists $TESTPOOL/recv && \
destroy_dataset $TESTPOOL/recv -r
[[ -f $keyfile ]] && log_must rm $keyfile
}
log_onexit cleanup
log_assert "Verify non-raw send with encryption does not leak any key mappings"
typeset keyfile=/$TESTPOOL/pkey
# Create an encrypted dataset
log_must eval "echo 'password' > $keyfile"
log_must zfs create -o encryption=on -o keyformat=passphrase \
-o keylocation=file://$keyfile $TESTPOOL/$TESTFS2
log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS2/testfile bs=128K count=4 \
status=none
for i in $(seq 0 20); do
log_note "Taking snapshots"
log_must zfs snapshot $TESTPOOL/$TESTFS2@snap_$i
log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS2/testfile bs=128K \
count=4 status=none
done
log_must eval "zfs send $TESTPOOL/$TESTFS2@snap_0 | zfs recv $TESTPOOL/recv"
for i in $(seq 3 3 20); do
log_note "Sending incremental snapshot snap_$((i - 3)) -> snap_$i"
log_must zfs get -Hpd 1 -t snapshot all $TESTPOOL/$TESTFS2 &>/dev/null
log_must eval "zfs send -I $TESTPOOL/$TESTFS2@snap_$((i - 3)) \
$TESTPOOL/$TESTFS2@snap_$i | zfs recv $TESTPOOL/recv"
done
log_must zpool export $TESTPOOL
log_must zpool import $TESTPOOL
log_pass "Verify non-raw send with encryption does not leak any key mappings"