-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Use recv_fix_encryption_hierarchy for non-recursive send/receive so that encryptionroot is inherited on received side #15687
Comments
"The root of a raw send should never be force-inherited." from zfs/lib/libzfs/libzfs_sendrecv.c Line 3479 in 233d34e
except in my above example if I did This change was introduced here, but I couldn't find reference to an issue or why.
Can there be an option on And similarly for non-recursive, can |
This code comment could be a bug or lead to one zfs/lib/libzfs/libzfs_sendrecv.c Line 4467 in 07e95b4
in zfs_receive_one() this comment states
but " That function will fixup the keylocation anyway" is not true:
patch attemptI tried reverting the chunk from 4807c0b #6595 that prevents force-inheriting the root of a raw send. Revert patch: --- libzfs_sendrecv.c
+++ libzfs_sendrecv.c
@@ -3472,11 +3472,9 @@
/*
* If the dataset is not flagged as an encryption root and is
* currently an encryption root, force it to inherit from its
- * parent. The root of a raw send should never be
- * force-inherited.
+ * parent.
*/
- if (!stream_encroot && is_encroot &&
- strcmp(top_zfs, fsname) != 0) {
+ if (!stream_encroot && is_encroot {
err = lzc_change_key(fsname, DCP_CMD_FORCE_INHERIT,
NULL, NULL, 0);
if (err != 0) { But doing a |
Oops so that patch above had a typo, and it also worked as intended (I was only building zfs-dkms and not zfs-utils), but isn't the whole story. If we receive into a copy of the encryption root, we now inherit as expected. But if we receive into a different independent encryption root, it will still inherit when it should not. What is needed is, before force inherit, detect if the candidate encryption root has the same key (? or ivset or something) as the current dataset. I don't know my way around enough to know how this can be looked up. Details below. Fix missing parenthesis: --- libzfs_sendrecv.c
+++ libzfs_sendrecv.c
@@ -3472,11 +3472,9 @@
/*
* If the dataset is not flagged as an encryption root and is
* currently an encryption root, force it to inherit from its
- * parent. The root of a raw send should never be
- * force-inherited.
+ * parent.
*/
- if (!stream_encroot && is_encroot &&
- strcmp(top_zfs, fsname) != 0) {
+ if (!stream_encroot && is_encroot) {
err = lzc_change_key(fsname, DCP_CMD_FORCE_INHERIT,
NULL, NULL, 0);
if (err != 0) { Test code: # Create test pool
dd if=/dev/zero of=/root/zpool bs=1M count=128
zpool create testpool /root/zpool
# Create encryptionroot and some datasets
echo "12345678" | zfs create -o canmount=off -o mountpoint=/mnt -o encryption=on -o keylocation=prompt -o keyformat=passphrase testpool/enc
zfs create testpool/enc/data1
zfs create testpool/enc/data2
touch /mnt/data1/x
touch /mnt/data2/x
zfs snapshot -r testpool/enc@1
# Make a recursive copy of the encryption root
zfs send -Rw testpool/enc@1 | zfs recv testpool/enc_copy
# Make a new dataset on the original encryption root and try to send to the new one
zfs create testpool/enc/data3
touch /mnt/data3/x
zfs snapshot testpool/enc/data3@x
zfs send -Rw testpool/enc/data3@x | zfs recv testpool/enc_copy/data3
# Expected behavior: the received encryption root will be enc_copy Before the fix:
After the fix:
and we can mount and access the data
This is good. But what is now broken is if we receive in to a different independent encryption root, it will force inherit anyway.
|
I just discovered that pyzfs exposes the force_inherit function! So now we can at least fix the encryptionroot manually if we know what we're doing.
|
This implements functionality already available in pyzfs i.e. libzfs_core.lzc_change_key(b"tank/enc/data", "force_inherit") Unlike zfs change-key -i, the key is not required to be loaded. Work-around to openzfs#15687. Signed-off-by: andy <andy@digitalsignalperson.com>
This implements functionality already available in pyzfs i.e. libzfs_core.lzc_change_key(b"tank/enc/data", "force_inherit") Unlike zfs change-key -i, the key is not required to be loaded. Work-around to openzfs#15687. Signed-off-by: andy <andy@digitalsignalperson.com>
Describe the feature would like to see added to OpenZFS
encryptionroot
property is only preserved when raw sending with-R
(for new datasets)--raw
will automatically use the correctencryptionroot
on the other side if it exists (like usingrecv_fix_encryption_hierarchy
but for non-recursive sends)Example of the encryptionroot not preserved
Step 1: Create and encryption root with a couple datasets and replicate it with -R to show we have the same structure on both sides
As shown by the
zfs get encryptionroot
, both sides have the expected structure of a single encryption root.But sending any individual dataset with
--raw
will cause the received dataset to be it's own encryption rootThis can be fixed with loading all the keys and doing
zfs change-key -i
although I see some bugs related to this to watch out for. Edit: I tested this out and documented my results here #12123 (comment) and I didn't encounter and issues.But
zfs change-key -i
is annoying if you just received 100+ datasets. You would need to write a script to supply the password to each dataset (zfs load-key prompts for every single dataset).Note that as long as the encryptionroot gets set correctly once, then future non
-R
incremental sends seem to keep the correct encryptionroot.How will this feature improve OpenZFS?
encryptionroot
is set on the received side.-R
send the whole thing at any given time.zfs change-key -i
on every received dataset if it came from the same original encryption rootThe text was updated successfully, but these errors were encountered: