From: Josef Bacik <[email protected]>

For send we will read the pages and copy them into our buffer.  Use the
fscrypt_inode_open helper to make sure the key is loaded properly before
trying to read from the inode so the contents are properly decrypted.

Signed-off-by: Josef Bacik <[email protected]>
Signed-off-by: Daniel Vacek <[email protected]>
---

v5: 
https://lore.kernel.org/linux-btrfs/a307def01bf28c3ed99398868a142180c6088527.1706116485.git.jo...@toxicpanda.com/
 * btrfs_iget() returns binode now.
---
 fs/btrfs/send.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index faaade4c35dc..bf9a99a9d24d 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -5331,6 +5331,38 @@ static int put_file_data(struct send_ctx *sctx, u64 
offset, u32 len)
        return ret;
 }
 
+static int load_fscrypt_context(struct send_ctx *sctx)
+{
+       struct btrfs_root *root = sctx->send_root;
+       struct name_cache_entry *nce;
+       struct btrfs_inode *dir;
+       int ret;
+
+       if (!btrfs_fs_incompat(root->fs_info, ENCRYPT))
+               return 0;
+
+       /*
+        * If we're encrypted we need to load the parent inode in order to make
+        * sure the encryption context is loaded.  We have to do this even if
+        * we're not encrypted, as we need to make sure that we don't violate
+        * the rule about encrypted children with non-encrypted parents, which
+        * is enforced by __fscrypt_file_open.
+        */
+       nce = name_cache_search(sctx, sctx->cur_ino, sctx->cur_inode_gen);
+       if (!nce) {
+               ASSERT(nce);
+               return -EINVAL;
+       }
+
+       dir = btrfs_iget(nce->parent_ino, root);
+       if (IS_ERR(dir))
+               return PTR_ERR(dir);
+
+       ret = __fscrypt_file_open(&dir->vfs_inode, sctx->cur_inode);
+       iput(&dir->vfs_inode);
+       return ret;
+}
+
 /*
  * Read some bytes from the current inode/file and send a write command to
  * user space.
@@ -5348,6 +5380,10 @@ static int send_write(struct send_ctx *sctx, u64 offset, 
u32 len)
        if (ret < 0)
                return ret;
 
+       ret = load_fscrypt_context(sctx);
+       if (ret < 0)
+               return ret;
+
        TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
        TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
        ret = put_file_data(sctx, offset, len);
-- 
2.51.0


Reply via email to