diff options
author | Tom Caputi <tcaputi@datto.com> | 2017-11-08 14:12:59 -0500 |
---|---|---|
committer | Brian Behlendorf <behlendorf1@llnl.gov> | 2018-02-02 11:37:16 -0800 |
commit | ae76f45cda0e0857f99e53959cf71c7a5d66bd8b (patch) | |
tree | e1c3cabe0971272785a442d6fb627bf6ebd07148 /cmd | |
parent | 4c46b99d24a6e71b3c72462c11cb051d0930ad60 (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 <lundman@lundman.net>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #6845
Closes #6864
Closes #7052
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/zfs/zfs_main.c | 4 | ||||
-rw-r--r-- | cmd/zpool/zpool_main.c | 20 | ||||
-rw-r--r-- | cmd/zstreamdump/zstreamdump.c | 6 |
3 files changed, 27 insertions, 3 deletions
diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index fa1a5d9fd..22735ae38 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -342,8 +342,8 @@ get_usage(zfs_help_t idx) return (gettext("\tunload-key [-r] " "<-a | filesystem|volume>\n")); case HELP_CHANGE_KEY: - return (gettext("\tchange-key [-l] [-o keyformat=<value>]" - "\t [-o keylocation=<value>] [-o pbkfd2iters=<value>]" + return (gettext("\tchange-key [-l] [-o keyformat=<value>]\n" + "\t [-o keylocation=<value>] [-o pbkfd2iters=<value>]\n" "\t <filesystem|volume>\n" "\tchange-key -i [-l] <filesystem|volume>\n")); } diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index f8d3a75bd..273453f00 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -2123,6 +2123,15 @@ show_import(nvlist_t *config) "updating.\n")); break; + case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION: + (void) printf(gettext(" action: Existing " + "encrypted datasets contain an on-disk " + "incompatibility, which\n\tneeds to be " + "corrected. Backup these datasets to new " + "encrypted datasets\n\tand destroy the " + "old ones.\n")); + break; + default: /* * All errata must contain an action message. @@ -6501,6 +6510,17 @@ status_callback(zpool_handle_t *zhp, void *data) "run 'zpool scrub'.\n")); break; + case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION: + (void) printf(gettext("\tExisting encrypted datasets " + "contain an on-disk incompatibility\n\twhich " + "needs to be corrected.\n")); + (void) printf(gettext("action: To correct the issue " + "backup existing encrypted datasets to new\n\t" + "encrypted datasets and destroy the old ones. " + "'zfs mount -o ro' can\n\tbe used to temporarily " + "mount existing encrypted datasets readonly.\n")); + break; + default: /* * All errata which allow the pool to be imported diff --git a/cmd/zstreamdump/zstreamdump.c b/cmd/zstreamdump/zstreamdump.c index f7bba4c8c..4c33e0a5a 100644 --- a/cmd/zstreamdump/zstreamdump.c +++ b/cmd/zstreamdump/zstreamdump.c @@ -443,6 +443,8 @@ main(int argc, char *argv[]) drro->drr_raw_bonuslen = BSWAP_32(drro->drr_raw_bonuslen); drro->drr_toguid = BSWAP_64(drro->drr_toguid); + drro->drr_maxblkid = + BSWAP_64(drro->drr_maxblkid); } payload_size = DRR_OBJECT_PAYLOAD_SIZE(drro); @@ -451,7 +453,8 @@ main(int argc, char *argv[]) (void) printf("OBJECT object = %llu type = %u " "bonustype = %u blksz = %u bonuslen = %u " "dn_slots = %u raw_bonuslen = %u " - "flags = %u indblkshift = %u nlevels = %u " + "flags = %u maxblkid = %llu " + "indblkshift = %u nlevels = %u " "nblkptr = %u\n", (u_longlong_t)drro->drr_object, drro->drr_type, @@ -461,6 +464,7 @@ main(int argc, char *argv[]) drro->drr_dn_slots, drro->drr_raw_bonuslen, drro->drr_flags, + (u_longlong_t)drro->drr_maxblkid, drro->drr_indblkshift, drro->drr_nlevels, drro->drr_nblkptr); |