summaryrefslogtreecommitdiff
path: root/usr/src/common/zfs
diff options
context:
space:
mode:
authorTom Caputi <tcaputi@datto.com>2019-02-15 11:01:44 +0900
committerJason King <jason.king@joyent.com>2019-03-06 17:38:54 +0000
commite7bdded1633ecbebe34c73a32bdd54bf574db8a6 (patch)
tree50611cd1b9e118095ce8580755b8407c01142deb /usr/src/common/zfs
parent3a03637b212537bba044ef52e28dbdfb94872282 (diff)
downloadillumos-joyent-e7bdded1633ecbebe34c73a32bdd54bf574db8a6.tar.gz
WIP: Detect and prevent mixed raw and non-raw sends
Currently, there is an issue in the raw receive code where raw receives are allowed to happen on top of previously non-raw received datasets. This is a problem because the source-side dataset doesn't know about how the blocks on the destination were encrypted. As a result, any MAC in the objset's checksum-of-MACs tree that is a parent of both blocks encrypted on the source and blocks encrypted by the destination will be incorrect. This will result in authentication errors when we decrypt the dataset. This patch fixes this issue by adding a new check to the raw receive code. The code now maintains an "IVset guid", which acts as an identifier for the set of IVs used to encrypt a given snapshot. When a snapshot is raw received, the destination snapshot will take this value from the DRR_BEGIN payload. Non-raw receives and normal "zfs snap" operations will cause ZFS to generate a new IVset guid. When a raw incremental stream is received, ZFS will check that the "from" IVset guid in the stream matches that of the "from" destination snapshot. If they do not match, the code will error out the receive, preventing the problem. This patch requires an on-disk format change to add the IVset guids to snapshots and bookmarks. As a result, this patch has errata handling and a tunable to help affected users resolve the issue with as little interruption as possible. Signed-off-by: Tom Caputi <tcaputi@datto.com>
Diffstat (limited to 'usr/src/common/zfs')
-rw-r--r--usr/src/common/zfs/zfeature_common.c1
-rw-r--r--usr/src/common/zfs/zfs_prop.c3
2 files changed, 4 insertions, 0 deletions
diff --git a/usr/src/common/zfs/zfeature_common.c b/usr/src/common/zfs/zfeature_common.c
index 49566ced2f..6f2bf7b114 100644
--- a/usr/src/common/zfs/zfeature_common.c
+++ b/usr/src/common/zfs/zfeature_common.c
@@ -327,6 +327,7 @@ zpool_feature_init(void)
static const spa_feature_t encryption_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
+ SPA_FEATURE_BOOKMARK_V2,
SPA_FEATURE_NONE
};
zfeature_register(SPA_FEATURE_ENCRYPTION,
diff --git a/usr/src/common/zfs/zfs_prop.c b/usr/src/common/zfs/zfs_prop.c
index 291b5b3d02..27c730a5ac 100644
--- a/usr/src/common/zfs/zfs_prop.c
+++ b/usr/src/common/zfs/zfs_prop.c
@@ -507,6 +507,9 @@ zfs_prop_init(void)
PROP_READONLY, ZFS_TYPE_DATASET, "OBJSETID");
zprop_register_hidden(ZFS_PROP_INCONSISTENT, "inconsistent",
PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, "INCONSISTENT");
+ zprop_register_hidden(ZFS_PROP_IVSET_GUID, "ivsetguid",
+ PROP_TYPE_NUMBER, PROP_READONLY,
+ ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "IVSETGUID");
zprop_register_hidden(ZFS_PROP_PREV_SNAP, "prevsnap", PROP_TYPE_STRING,
PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "PREVSNAP");
zprop_register_hidden(ZFS_PROP_PBKDF2_SALT, "pbkdf2salt",