[RFC PATCH 07/13] fscrypt: store full fscrypt_contexts for each extent

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



For contrast purposes, this patch contains the entirety of the changes
necessary to switch between lightweight and heavyweight extents. This
patch could be dropped, or rolled into the former change, without
changing anything else.

Lightweight extents relying on their parent inode's context for
key and policy information do take up less disk space. Additionally,
they guarantee that if inode open succeeds, then all extents will be
readable and writeable, matching the current inode-based fscrypt
behavior.

However, heavyweight extents permit greater flexibility for future
extensions:

- Any form of changing the key for a non-empty directory's
  future writes requires that extents have some sort of policy in
  addition to the nonce, which is essentially the contents of the full
  fscrypt_context.
  - This could be approximated using overlayfs writing to a new
    encrypted directory, but this would waste space used by overwritten
    data and makes it very difficult to have nested subvolumes each with
    their own key, so it's very preferable to support this natively in
    btrfs.

- Scrub (verifying checksums) currently iterates over extents,
without interacting with inodes; in an authenticated encryption world,
scrub verifying authentication tags would need to iterate over inodes (a
large departure from the present) or need heavyweight extents storing
the necessary key information.

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@xxxxxxxxxx>
---
 fs/crypto/keysetup.c | 20 ++++++++++----------
 fs/crypto/policy.c   |  5 ++---
 2 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c
index 90143377cc61..4146b1380cb5 100644
--- a/fs/crypto/keysetup.c
+++ b/fs/crypto/keysetup.c
@@ -1061,25 +1061,25 @@ int fscrypt_load_extent_info(struct inode *inode, void *buf, size_t len,
 {
 	int res;
 	union fscrypt_context ctx;
-	const union fscrypt_policy *policy;
+	union fscrypt_policy policy;
 
 	if (!fscrypt_has_encryption_key(inode))
 		return -EINVAL;
 
-	if (len != FSCRYPT_FILE_NONCE_SIZE) {
+	memcpy(&ctx, buf, len);
+
+	res = fscrypt_policy_from_context(&policy, &ctx, len);
+	if (res) {
 		fscrypt_warn(inode,
 			     "Unrecognized or corrupt encryption context");
-		return -EINVAL;
+		return res;
 	}
 
-	policy = fscrypt_policy_to_inherit(inode);
-	if (policy == NULL)
-		return 0;
-	if (IS_ERR(policy))
-		return PTR_ERR(policy);
+	if (!fscrypt_supported_policy(&policy, inode))
+		return -EINVAL;
 
-	return fscrypt_setup_extent_info(inode, policy, buf,
-					 info_ptr);
+	return fscrypt_setup_extent_info(inode, &policy,
+					 fscrypt_context_nonce(&ctx), info_ptr);
 }
 EXPORT_SYMBOL_GPL(fscrypt_load_extent_info);
 
diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c
index cfbe83aee847..314bb6e97cec 100644
--- a/fs/crypto/policy.c
+++ b/fs/crypto/policy.c
@@ -778,10 +778,9 @@ EXPORT_SYMBOL_GPL(fscrypt_set_context);
 int fscrypt_set_extent_context(struct fscrypt_extent_info *ci, void *ctx,
 			       size_t len)
 {
-	if (len < FSCRYPT_EXTENT_CONTEXT_MAX_SIZE)
+	if (len < FSCRYPT_SET_CONTEXT_MAX_SIZE)
 		return -EINVAL;
-	memcpy(ctx, ci->info.ci_nonce, FSCRYPT_FILE_NONCE_SIZE);
-	return FSCRYPT_FILE_NONCE_SIZE;
+	return fscrypt_new_context(ctx, &ci->info.ci_policy, ci->info.ci_nonce);
 }
 EXPORT_SYMBOL_GPL(fscrypt_set_extent_context);
 
-- 
2.41.0




[Index of Archives]     [linux Cryptography]     [Asterisk App Development]     [PJ SIP]     [Gnu Gatekeeper]     [IETF Sipping]     [Info Cyrus]     [ALSA User]     [Fedora Linux Users]     [Linux SCTP]     [DCCP]     [Gimp]     [Yosemite News]     [Deep Creek Hot Springs]     [Yosemite Campsites]     [ISDN Cause Codes]

  Powered by Linux