mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
Allow unencrypted children of encrypted datasets
When encryption was first added to ZFS, we made a decision to prevent users from creating unencrypted children of encrypted datasets. The idea was to prevent users from inadvertently leaving some of their data unencrypted. However, since the release of 0.8.0, some legitimate reasons have been brought up for this behavior to be allowed. This patch simply removes this limitation from all code paths that had checks for it and updates the tests accordingly. Reviewed-by: Jason King <jason.king@joyent.com> Reviewed-by: Sean Eric Fagan <sef@ixsystems.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Tom Caputi <tcaputi@datto.com> Closes #8737 Closes #8870
This commit is contained in:
committed by
Brian Behlendorf
parent
84b4201f32
commit
da68988708
@@ -1349,13 +1349,6 @@ dmu_objset_clone_check(void *arg, dmu_tx_t *tx)
|
||||
return (SET_ERROR(EINVAL));
|
||||
}
|
||||
|
||||
error = dmu_objset_clone_crypt_check(pdd, origin->ds_dir);
|
||||
if (error != 0) {
|
||||
dsl_dataset_rele(origin, FTAG);
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
dsl_dataset_rele(origin, FTAG);
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
|
||||
|
||||
+12
-12
@@ -624,7 +624,7 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
|
||||
/* Open the parent of tofs */
|
||||
ASSERT3U(strlen(tofs), <, sizeof (buf));
|
||||
(void) strlcpy(buf, tofs, strrchr(tofs, '/') - tofs + 1);
|
||||
error = dsl_dataset_hold_flags(dp, buf, dsflags, FTAG, &ds);
|
||||
error = dsl_dataset_hold(dp, buf, FTAG, &ds);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
@@ -642,13 +642,13 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
|
||||
error = dmu_objset_create_crypt_check(ds->ds_dir,
|
||||
drba->drba_dcp, &will_encrypt);
|
||||
if (error != 0) {
|
||||
dsl_dataset_rele_flags(ds, dsflags, FTAG);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
if (will_encrypt &&
|
||||
(featureflags & DMU_BACKUP_FEATURE_EMBED_DATA)) {
|
||||
dsl_dataset_rele_flags(ds, dsflags, FTAG);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (SET_ERROR(EINVAL));
|
||||
}
|
||||
}
|
||||
@@ -661,25 +661,25 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
|
||||
error = dsl_fs_ss_limit_check(ds->ds_dir, 1,
|
||||
ZFS_PROP_FILESYSTEM_LIMIT, NULL, drba->drba_cred);
|
||||
if (error != 0) {
|
||||
dsl_dataset_rele_flags(ds, dsflags, FTAG);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = dsl_fs_ss_limit_check(ds->ds_dir, 1,
|
||||
ZFS_PROP_SNAPSHOT_LIMIT, NULL, drba->drba_cred);
|
||||
if (error != 0) {
|
||||
dsl_dataset_rele_flags(ds, dsflags, FTAG);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* can't recv below anything but filesystems (eg. no ZVOLs) */
|
||||
error = dmu_objset_from_ds(ds, &os);
|
||||
if (error != 0) {
|
||||
dsl_dataset_rele_flags(ds, dsflags, FTAG);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (error);
|
||||
}
|
||||
if (dmu_objset_type(os) != DMU_OST_ZFS) {
|
||||
dsl_dataset_rele_flags(ds, dsflags, FTAG);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (SET_ERROR(ZFS_ERR_WRONG_PARENT));
|
||||
}
|
||||
|
||||
@@ -688,25 +688,25 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
|
||||
error = dsl_dataset_hold_flags(dp, drba->drba_origin,
|
||||
dsflags, FTAG, &origin);
|
||||
if (error != 0) {
|
||||
dsl_dataset_rele_flags(ds, dsflags, FTAG);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (error);
|
||||
}
|
||||
if (!origin->ds_is_snapshot) {
|
||||
dsl_dataset_rele_flags(origin, dsflags, FTAG);
|
||||
dsl_dataset_rele_flags(ds, dsflags, FTAG);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (SET_ERROR(EINVAL));
|
||||
}
|
||||
if (dsl_dataset_phys(origin)->ds_guid != fromguid &&
|
||||
fromguid != 0) {
|
||||
dsl_dataset_rele_flags(origin, dsflags, FTAG);
|
||||
dsl_dataset_rele_flags(ds, dsflags, FTAG);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (SET_ERROR(ENODEV));
|
||||
}
|
||||
|
||||
if (origin->ds_dir->dd_crypto_obj != 0 &&
|
||||
(featureflags & DMU_BACKUP_FEATURE_EMBED_DATA)) {
|
||||
dsl_dataset_rele_flags(origin, dsflags, FTAG);
|
||||
dsl_dataset_rele_flags(ds, dsflags, FTAG);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (SET_ERROR(EINVAL));
|
||||
}
|
||||
|
||||
@@ -729,7 +729,7 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
|
||||
dsl_dataset_rele_flags(origin, dsflags, FTAG);
|
||||
}
|
||||
|
||||
dsl_dataset_rele_flags(ds, dsflags, FTAG);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
error = 0;
|
||||
}
|
||||
return (error);
|
||||
|
||||
+1
-43
@@ -1610,15 +1610,8 @@ dsl_dir_rename_crypt_check(dsl_dir_t *dd, dsl_dir_t *newparent)
|
||||
int ret;
|
||||
uint64_t curr_rddobj, parent_rddobj;
|
||||
|
||||
if (dd->dd_crypto_obj == 0) {
|
||||
/* children of encrypted parents must be encrypted */
|
||||
if (newparent->dd_crypto_obj != 0) {
|
||||
ret = SET_ERROR(EACCES);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (dd->dd_crypto_obj == 0)
|
||||
return (0);
|
||||
}
|
||||
|
||||
ret = dsl_dir_get_encryption_root_ddobj(dd, &curr_rddobj);
|
||||
if (ret != 0)
|
||||
@@ -1747,34 +1740,6 @@ dsl_dataset_promote_crypt_sync(dsl_dir_t *target, dsl_dir_t *origin,
|
||||
kmem_free(keylocation, ZAP_MAXVALUELEN);
|
||||
}
|
||||
|
||||
int
|
||||
dmu_objset_clone_crypt_check(dsl_dir_t *parentdd, dsl_dir_t *origindd)
|
||||
{
|
||||
int ret;
|
||||
uint64_t pcrypt, crypt;
|
||||
|
||||
/*
|
||||
* Check that we are not making an unencrypted child of an
|
||||
* encrypted parent.
|
||||
*/
|
||||
ret = dsl_dir_get_crypt(parentdd, &pcrypt);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
|
||||
ret = dsl_dir_get_crypt(origindd, &crypt);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
|
||||
ASSERT3U(pcrypt, !=, ZIO_CRYPT_INHERIT);
|
||||
ASSERT3U(crypt, !=, ZIO_CRYPT_INHERIT);
|
||||
|
||||
if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF)
|
||||
return (SET_ERROR(EINVAL));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dmu_objset_create_crypt_check(dsl_dir_t *parentdd, dsl_crypto_params_t *dcp,
|
||||
boolean_t *will_encrypt)
|
||||
@@ -1805,13 +1770,6 @@ dmu_objset_create_crypt_check(dsl_dir_t *parentdd, dsl_crypto_params_t *dcp,
|
||||
ASSERT3U(pcrypt, !=, ZIO_CRYPT_INHERIT);
|
||||
ASSERT3U(crypt, !=, ZIO_CRYPT_INHERIT);
|
||||
|
||||
/*
|
||||
* We can't create an unencrypted child of an encrypted parent
|
||||
* under any circumstances.
|
||||
*/
|
||||
if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF)
|
||||
return (SET_ERROR(EINVAL));
|
||||
|
||||
/* check for valid dcp with no encryption (inherited or local) */
|
||||
if (crypt == ZIO_CRYPT_OFF) {
|
||||
/* Must not specify encryption params */
|
||||
|
||||
Reference in New Issue
Block a user