Project

General

Profile

Actions

Bug #11880

closed

changing encryption key on dataset with unencrypted children triggers VERIFY

Added by Jason King over 2 years ago. Updated over 2 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
zfs - Zettabyte File System
Start date:
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:

Description

Doing something similar to the following:

# zfs create -o encryption=on -o keylocation=prompt -o keyformat=passphrase pool/encrypted
...
# zfs create -o encryption=off pool/encrypted/unencrypted
# zfs change-key pool/encrypted

Will trigger a panic similar to:

assertion failed: dsl_dir_get_encryption_root_ddobj(dd, &curr_rddobj) == 0 (0x2 == 0x0), file: ../../common/fs/zfs/dsl_crypt.c, line: 1421

0x2 is ENOENT which makes sense -- an unencrypted dataset would not have an encrypted root. The panic stack shows the following top few frames:

> ::stack
vpanic()
0xfffffffffbe35131()
spa_keystore_change_key_sync_impl+0x232(20, 280, 20, fffffe8b7159ee00, fffffe8b735a8400)
spa_keystore_change_key_sync_impl+0x1fd(20, 20, 20, fffffe8b7159ee00, fffffe8b735a8400)
spa_keystore_change_key_sync+0x16f(fffffe00bae6c528, fffffe8b735a8400)
zcp_sync_task+0x83(fffffe8672cf4e08, fffffffff7e51f30, fffffffff7e52560, fffffe00bae6c528, 1, fffffe8af9ae1620)

What appears to be happening is that spa_keystore_change_key_sync does the following:

        /* Recurse into all child dsl dirs. */
        for (zap_cursor_init(zc, dp->dp_meta_objset,
            dsl_dir_phys(dd)->dd_child_dir_zapobj);
            zap_cursor_retrieve(zc, za) == 0;
            zap_cursor_advance(zc)) {
                spa_keystore_change_key_sync_impl(rddobj,
                    za->za_first_integer, new_rddobj, wkey, tx);
        }

and when it calls spa_keystore_change_key_sync_impl on an unencrypted child, the recursive call will trigger the VERIFY0.

The likely fix is to add ENOENT as another condition to stop the recursion.

Actions

Also available in: Atom PDF