diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 6c8d737130..c6198ee264 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -3120,7 +3120,8 @@ zdb_load_key(objset_t *os) if (err != 0) fatal( "couldn't load encryption key for %s: %s", - encroot, strerror(err)); + encroot, err == ZFS_ERR_CRYPTO_NOTSUP ? + "crypto params not supported" : strerror(err)); ASSERT3U(dsl_dataset_get_keystatus(dd), ==, ZFS_KEYSTATUS_AVAILABLE); diff --git a/contrib/pyzfs/libzfs_core/_constants.py b/contrib/pyzfs/libzfs_core/_constants.py index 4db1de8d9a..5ee422dfa8 100644 --- a/contrib/pyzfs/libzfs_core/_constants.py +++ b/contrib/pyzfs/libzfs_core/_constants.py @@ -102,6 +102,7 @@ zfs_errno = enum_with_offset(1024, [ 'ZFS_ERR_VDEV_NOTSUP', 'ZFS_ERR_NOT_USER_NAMESPACE', 'ZFS_ERR_RESUME_EXISTS', + 'ZFS_ERR_CRYPTO_NOTSUP', ], {} ) diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h index da2d052165..e869685c5e 100644 --- a/include/sys/fs/zfs.h +++ b/include/sys/fs/zfs.h @@ -1545,6 +1545,7 @@ typedef enum { ZFS_ERR_VDEV_NOTSUP, ZFS_ERR_NOT_USER_NAMESPACE, ZFS_ERR_RESUME_EXISTS, + ZFS_ERR_CRYPTO_NOTSUP, } zfs_errno_t; /* diff --git a/lib/libzfs/libzfs_crypto.c b/lib/libzfs/libzfs_crypto.c index 3ef8837010..e8351b22ff 100644 --- a/lib/libzfs/libzfs_crypto.c +++ b/lib/libzfs/libzfs_crypto.c @@ -1407,6 +1407,11 @@ try_again: "Incorrect key provided for '%s'."), zfs_get_name(zhp)); break; + case ZFS_ERR_CRYPTO_NOTSUP: + zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, + "'%s' uses an unsupported encryption suite."), + zfs_get_name(zhp)); + break; } goto error; } diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c index 66a22e3336..4b6e06df69 100644 --- a/lib/libzfs/libzfs_sendrecv.c +++ b/lib/libzfs/libzfs_sendrecv.c @@ -5161,6 +5161,12 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, "stream.")); (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); break; + case ZFS_ERR_CRYPTO_NOTSUP: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "stream uses crypto parameters not compatible with " + "this pool")); + (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf); + break; case EDQUOT: zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "destination %s space quota exceeded."), name); diff --git a/module/zfs/dsl_crypt.c b/module/zfs/dsl_crypt.c index 408d038b4d..dd936e74b1 100644 --- a/module/zfs/dsl_crypt.c +++ b/module/zfs/dsl_crypt.c @@ -541,6 +541,12 @@ dsl_crypto_key_open(objset_t *mos, dsl_wrapping_key_t *wkey, if (ret != 0) goto error; + /* handle a future crypto suite that we don't support */ + if (crypt >= ZIO_CRYPT_FUNCTIONS) { + ret = (SET_ERROR(ZFS_ERR_CRYPTO_NOTSUP)); + goto error; + } + ret = zap_lookup(mos, dckobj, DSL_CRYPTO_KEY_GUID, 8, 1, &guid); if (ret != 0) goto error; @@ -2141,10 +2147,16 @@ dsl_crypto_recv_raw_key_check(dsl_dataset_t *ds, nvlist_t *nvl, dmu_tx_t *tx) * wrapping key. */ ret = nvlist_lookup_uint64(nvl, DSL_CRYPTO_KEY_CRYPTO_SUITE, &intval); - if (ret != 0 || intval >= ZIO_CRYPT_FUNCTIONS || - intval <= ZIO_CRYPT_OFF) + if (ret != 0 || intval <= ZIO_CRYPT_OFF) return (SET_ERROR(EINVAL)); + /* + * Flag a future crypto suite that we don't support differently, so + * we can return a more useful error to the user. + */ + if (intval >= ZIO_CRYPT_FUNCTIONS) + return (SET_ERROR(ZFS_ERR_CRYPTO_NOTSUP)); + ret = nvlist_lookup_uint64(nvl, DSL_CRYPTO_KEY_GUID, &intval); if (ret != 0) return (SET_ERROR(EINVAL));