aboutsummaryrefslogtreecommitdiffstats
path: root/tests/zfs-tests
diff options
context:
space:
mode:
authorTom Caputi <[email protected]>2017-11-08 14:12:59 -0500
committerBrian Behlendorf <[email protected]>2018-02-02 11:37:16 -0800
commitae76f45cda0e0857f99e53959cf71c7a5d66bd8b (patch)
treee1c3cabe0971272785a442d6fb627bf6ebd07148 /tests/zfs-tests
parent4c46b99d24a6e71b3c72462c11cb051d0930ad60 (diff)
Encryption Stability and On-Disk Format Fixes
The on-disk format for encrypted datasets protects not only the encrypted and authenticated blocks themselves, but also the order and interpretation of these blocks. In order to make this work while maintaining the ability to do raw sends, the indirect bps maintain a secure checksum of all the MACs in the block below it along with a few other fields that determine how the data is interpreted. Unfortunately, the current on-disk format erroneously includes some fields which are not portable and thus cannot support raw sends. It is not possible to easily work around this issue due to a separate and much smaller bug which causes indirect blocks for encrypted dnodes to not be compressed, which conflicts with the previous bug. In addition, the current code generates incompatible on-disk formats on big endian and little endian systems due to an issue with how block pointers are authenticated. Finally, raw send streams do not currently include dn_maxblkid when sending both the metadnode and normal dnodes which are needed in order to ensure that we are correctly maintaining the portable objset MAC. This patch zero's out the offending fields when computing the bp MAC and ensures that these MACs are always calculated in little endian order (regardless of the host system's byte order). This patch also registers an errata for the old on-disk format, which we detect by adding a "version" field to newly created DSL Crypto Keys. We allow datasets without a version (version 0) to only be mounted for read so that they can easily be migrated. We also now include dn_maxblkid in raw send streams to ensure the MAC can be maintained correctly. This patch also contains minor bug fixes and cleanups. Reviewed-by: Jorgen Lundman <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed by: Matthew Ahrens <[email protected]> Signed-off-by: Tom Caputi <[email protected]> Closes #6845 Closes #6864 Closes #7052
Diffstat (limited to 'tests/zfs-tests')
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zpool_import/Makefile.am6
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zpool_import/cryptv0.dat.bz2bin0 -> 94716 bytes
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata3.ksh99
-rw-r--r--tests/zfs-tests/tests/functional/rsend/Makefile.am1
-rw-r--r--tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh101
5 files changed, 205 insertions, 2 deletions
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_import/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zpool_import/Makefile.am
index 94031b9a7..6200af247 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zpool_import/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_import/Makefile.am
@@ -27,10 +27,12 @@ dist_pkgdata_SCRIPTS = \
zpool_import_missing_003_pos.ksh \
zpool_import_rename_001_pos.ksh \
zpool_import_encrypted.ksh \
- zpool_import_encrypted_load.ksh
+ zpool_import_encrypted_load.ksh \
+ zpool_import_errata3.ksh
BLOCKFILES = \
- unclean_export.dat.bz2
+ unclean_export.dat.bz2 \
+ cryptv0.dat.bz2
dist_pkgdata_DATA = $(BLOCKFILES)
EXTRA_DIST = $(BLOCKFILES)
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_import/cryptv0.dat.bz2 b/tests/zfs-tests/tests/functional/cli_root/zpool_import/cryptv0.dat.bz2
new file mode 100644
index 000000000..1c625c2c4
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_import/cryptv0.dat.bz2
Binary files differ
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata3.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata3.ksh
new file mode 100755
index 000000000..67e4caee8
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata3.ksh
@@ -0,0 +1,99 @@
+#!/bin/ksh -p
+#
+# 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) 2017 Datto, Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# 'zpool import' should import a pool with Errata #3 while preventing
+# the user from performing read write operations
+#
+# STRATEGY:
+# 1. Import a pre-packaged pool with Errata #3
+# 2. Attempt to write to the effected datasets
+# 3. Attempt to read from the effected datasets
+# 4. Attempt to perform a raw send of the effected datasets
+# 5. Perform a regular send of the datasets under a new encryption root
+# 6. Verify the new datasets can be read from and written to
+# 7. Destroy the old effected datasets
+# 8. Reimport the pool and verify that the errata is no longer present
+#
+
+verify_runnable "global"
+
+POOL_NAME=cryptv0
+POOL_FILE=cryptv0.dat
+
+function uncompress_pool
+{
+ log_note "Creating pool from $POOL_FILE"
+ log_must bzcat \
+ $STF_SUITE/tests/functional/cli_root/zpool_import/$POOL_FILE.bz2 \
+ > /$TESTPOOL/$POOL_FILE
+ return 0
+}
+
+function cleanup
+{
+ poolexists $POOL_NAME && log_must zpool destroy $POOL_NAME
+ [[ -e /$TESTPOOL/$POOL_FILE ]] && rm /$TESTPOOL/$POOL_FILE
+ return 0
+}
+log_onexit cleanup
+
+log_assert "Verify that Errata 3 is properly handled"
+
+uncompress_pool
+log_must zpool import -d /$TESTPOOL/ $POOL_NAME
+log_must eval "zpool status | grep -q Errata"
+log_must eval "echo 'password' | zfs load-key $POOL_NAME/testfs"
+log_must eval "echo 'password' | zfs load-key $POOL_NAME/testvol"
+
+log_mustnot zfs mount $POOL_NAME/testfs
+log_must zfs mount -o ro $POOL_NAME/testfs
+
+old_mntpnt=$(get_prop mountpoint $POOL_NAME/testfs)
+log_must eval "ls $old_mntpnt | grep -q testfile"
+block_device_wait
+log_mustnot dd if=/dev/zero of=/dev/zvol/$POOL_NAME/testvol bs=512 count=1
+log_must dd if=/dev/zvol/$POOL_NAME/testvol of=/dev/null bs=512 count=1
+log_must eval "echo 'password' | zfs create \
+ -o encryption=on -o keyformat=passphrase -o keylocation=prompt \
+ cryptv0/encroot"
+log_mustnot eval "zfs send -w $POOL_NAME/testfs@snap1 | \
+ zfs recv $POOL_NAME/encroot/testfs"
+log_mustnot eval "zfs send -w $POOL_NAME/testvol@snap1 | \
+ zfs recv $POOL_NAME/encroot/testvol"
+
+log_must eval "zfs send $POOL_NAME/testfs@snap1 | \
+ zfs recv $POOL_NAME/encroot/testfs"
+log_must eval "zfs send $POOL_NAME/testvol@snap1 | \
+ zfs recv $POOL_NAME/encroot/testvol"
+block_device_wait
+log_must dd if=/dev/zero of=/dev/zvol/$POOL_NAME/encroot/testvol bs=512 count=1
+new_mntpnt=$(get_prop mountpoint $POOL_NAME/encroot/testfs)
+log_must eval "ls $new_mntpnt | grep -q testfile"
+log_must zfs destroy -r $POOL_NAME/testfs
+log_must zfs destroy -r $POOL_NAME/testvol
+
+log_must zpool export $POOL_NAME
+log_must zpool import -d /$TESTPOOL/ $POOL_NAME
+log_mustnot eval "zpool status | grep -q Errata"
+log_pass "Errata 3 is properly handled"
diff --git a/tests/zfs-tests/tests/functional/rsend/Makefile.am b/tests/zfs-tests/tests/functional/rsend/Makefile.am
index 8833d1d76..6598b1c3d 100644
--- a/tests/zfs-tests/tests/functional/rsend/Makefile.am
+++ b/tests/zfs-tests/tests/functional/rsend/Makefile.am
@@ -23,6 +23,7 @@ dist_pkgdata_SCRIPTS = \
rsend_021_pos.ksh \
rsend_022_pos.ksh \
rsend_024_pos.ksh \
+ send_encrypted_files.ksh \
send_encrypted_heirarchy.ksh \
send-cD.ksh \
send-c_embedded_blocks.ksh \
diff --git a/tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh b/tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh
new file mode 100644
index 000000000..20f3788d5
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh
@@ -0,0 +1,101 @@
+#!/bin/ksh -p
+#
+# 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) 2017 by Datto Inc. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+
+#
+# DESCRIPTION:
+#
+#
+# STRATEGY:
+# 1. Create a new encrypted filesystem
+# 2. Add an empty file to the filesystem
+# 3. Add a small 512 byte file to the filesystem
+# 4. Add a larger 32M file to the filesystem
+# 5. Add a large sparse file to the filesystem
+# 6. Add a file truncated to 4M to the filesystem
+# 7. Add a sparse file with metadata compression disabled to the filesystem
+# 8. Add and remove 1000 empty files to the filesystem
+# 9. Snapshot the filesystem
+# 10. Send and receive the filesystem, ensuring that it can be mounted
+#
+
+verify_runnable "both"
+
+function set_metadata_compression_disabled # <0|1>
+{
+ echo $1 > /sys/module/zfs/parameters/zfs_mdcomp_disable
+}
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+ datasetexists $TESTPOOL/recv && \
+ log_must zfs destroy -r $TESTPOOL/recv
+ [[ -f $keyfile ]] && log_must rm $keyfile
+ [[ -f $sendfile ]] && log_must rm $sendfile
+}
+log_onexit cleanup
+
+log_assert "Verify 'zfs send -w' works with many different file layouts"
+
+typeset keyfile=/$TESTPOOL/pkey
+typeset sendfile=/$TESTPOOL/sendfile
+
+log_must eval "echo 'password' > $keyfile"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file://$keyfile $TESTPOOL/$TESTFS2
+
+log_must touch /$TESTPOOL/$TESTFS2/empty
+log_must mkfile 512 /$TESTPOOL/$TESTFS2/small
+log_must mkfile 32M /$TESTPOOL/$TESTFS2/full
+log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS2/sparse \
+ bs=512 count=1 seek=10G >/dev/null 2>&1
+log_must mkfile 32M /$TESTPOOL/$TESTFS2/truncated
+log_must truncate -s 4M /$TESTPOOL/$TESTFS2/truncated
+sync
+
+log_must set_metadata_compression_disabled 1
+log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS2/no_mdcomp \
+ count=1 bs=512 seek=10G >/dev/null 2>&1
+sync
+log_must set_metadata_compression_disabled 0
+
+log_must mkdir -p /$TESTPOOL/$TESTFS2/dir
+for i in {1..1000}; do
+ log_must mkfile 512 /$TESTPOOL/$TESTFS2/dir/file-$i
+done
+sync
+
+for i in {1..1000}; do
+ log_must rm /$TESTPOOL/$TESTFS2/dir/file-$i
+done
+sync
+
+log_must zfs snapshot $TESTPOOL/$TESTFS2@now
+log_must eval "zfs send -wR $TESTPOOL/$TESTFS2@now > $sendfile"
+
+log_must eval "zfs recv -F $TESTPOOL/recv < $sendfile"
+log_must zfs load-key $TESTPOOL/recv
+
+log_must zfs mount -a
+
+log_pass "Verified 'zfs send -w' works with many different file layouts"