Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 'zfs change-key' with unencrypted child #9524

Merged
merged 1 commit into from
Oct 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions module/zfs/dsl_crypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,7 @@ spa_keystore_change_key_sync_impl(uint64_t rddobj, uint64_t ddobj,
uint64_t new_rddobj, dsl_wrapping_key_t *wkey, boolean_t skip,
dmu_tx_t *tx)
{
int ret;
zap_cursor_t *zc;
zap_attribute_t *za;
dsl_pool_t *dp = dmu_tx_pool(tx);
Expand All @@ -1448,12 +1449,15 @@ spa_keystore_change_key_sync_impl(uint64_t rddobj, uint64_t ddobj,
return;
}

ret = dsl_dir_get_encryption_root_ddobj(dd, &curr_rddobj);
VERIFY(ret == 0 || ret == ENOENT);

/*
* Stop recursing if this dsl dir didn't inherit from the root
* or if this dd is a clone.
*/
VERIFY0(dsl_dir_get_encryption_root_ddobj(dd, &curr_rddobj));
if (!skip && (curr_rddobj != rddobj || dsl_dir_is_clone(dd))) {
if (ret == ENOENT ||
(!skip && (curr_rddobj != rddobj || dsl_dir_is_clone(dd)))) {
dsl_dir_rele(dd, FTAG);
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@
# STRATEGY:
# 1. Create an encrypted dataset
# 2. Create an encrypted child dataset
# 3. Attempt to change the key without any flags
# 4. Attempt to change the key specifying keylocation
# 5. Attempt to change the key specifying keyformat
# 6. Verify the new encryption root can unload and load its key
# 7. Recreate the child dataset
# 8. Attempt to change the key specifying both the keylocation and keyformat
# 9. Verify the new encryption root can unload and load its key
# 3. Create an unencrypted child dataset
# 4. Attempt to change the key without any flags
# 5. Attempt to change the key specifying keylocation
# 6. Attempt to change the key specifying keyformat
# 7. Verify the new encryption root can unload and load its key
# 8. Recreate the child dataset
# 9. Attempt to change the key specifying both the keylocation and keyformat
# 10. Verify the new encryption root can unload and load its key
# 11. Verify the unencrytped child is still accessible normally
#

verify_runnable "both"
Expand All @@ -53,6 +55,7 @@ log_assert "'zfs change-key' should promote an encrypted child to an" \
log_must eval "echo $PASSPHRASE1 | zfs create -o encryption=on" \
"-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
log_must zfs create $TESTPOOL/$TESTFS1/child
log_must zfs create -o encryption=off $TESTPOOL/$TESTFS1/child2

log_mustnot eval "echo $PASSPHRASE2 | zfs change-key" \
"$TESTPOOL/$TESTFS1/child"
Expand Down Expand Up @@ -82,5 +85,7 @@ log_must key_unavailable $TESTPOOL/$TESTFS1/child

log_must eval "echo $PASSPHRASE2 | zfs load-key $TESTPOOL/$TESTFS1/child"
log_must key_available $TESTPOOL/$TESTFS1/child
log_must zfs unmount $TESTPOOL/$TESTFS1/child2
log_must zfs mount $TESTPOOL/$TESTFS1/child2

log_pass "'zfs change-key' promotes an encrypted child to an encryption root"