[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <0508dac7fd6ec817007c5e21a565d1bb9d4f4921.1658623235.git.sweettea-kernel@dorminy.me>
Date: Sat, 23 Jul 2022 20:52:26 -0400
From: Sweet Tea Dorminy <sweettea-kernel@...miny.me>
To: "Theodore Y . Ts'o " <tytso@....edu>,
Jaegeuk Kim <jaegeuk@...nel.org>,
Eric Biggers <ebiggers@...nel.org>,
linux-fscrypt@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-btrfs@...r.kernel.org, osandov@...ndov.com,
kernel-team@...com
Cc: Sweet Tea Dorminy <sweettea-kernel@...miny.me>
Subject: [PATCH RFC 2/4] fscrypt: add flag allowing partially-encrypted directories
From: Omar Sandoval <osandov@...ndov.com>
Creating several new subvolumes out of snapshots of another subvolume,
each for a different VM's storage, is a important usecase for btrfs. We
would like to give each VM a unique encryption key to use for new writes
to its subvolume, so that secure deletion of the VM's data is as simple
as securely deleting the key; to avoid needing multiple keys in each VM,
we envision the initial subvolume being unencrypted. However, this means
that the snapshot's directories would have a mix of encrypted and
unencrypted files.
To allow this, add another FS_CFLG to allow filesystems to opt into
partially encrypted directories.
Signed-off-by: Omar Sandoval <osandov@...ndov.com>
Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@...miny.me>
---
fs/crypto/fname.c | 17 ++++++++++++++++-
include/linux/fscrypt.h | 2 ++
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index 5d5c26d827fd..c5dd19c1d19e 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -389,6 +389,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
fname->usr_fname = iname;
if (!IS_ENCRYPTED(dir) || fscrypt_is_dot_dotdot(iname)) {
+unencrypted:
fname->disk_name.name = (unsigned char *)iname->name;
fname->disk_name.len = iname->len;
return 0;
@@ -424,8 +425,16 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
* user-supplied name
*/
- if (iname->len > FSCRYPT_NOKEY_NAME_MAX_ENCODED)
+ if (iname->len > FSCRYPT_NOKEY_NAME_MAX_ENCODED) {
+ /*
+ * This isn't a valid nokey name, but it could be an unencrypted
+ * name if the filesystem allows partially encrypted
+ * directories.
+ */
+ if (dir->i_sb->s_cop->flags & FS_CFLG_ALLOW_PARTIAL)
+ goto unencrypted;
return -ENOENT;
+ }
fname->crypto_buf.name = kmalloc(FSCRYPT_NOKEY_NAME_MAX, GFP_KERNEL);
if (fname->crypto_buf.name == NULL)
@@ -436,6 +445,12 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
if (ret < (int)offsetof(struct fscrypt_nokey_name, bytes[1]) ||
(ret > offsetof(struct fscrypt_nokey_name, sha256) &&
ret != FSCRYPT_NOKEY_NAME_MAX)) {
+ /* Again, this could be an unencrypted name. */
+ if (dir->i_sb->s_cop->flags & FS_CFLG_ALLOW_PARTIAL) {
+ kfree(fname->crypto_buf.name);
+ fname->crypto_buf.name = NULL;
+ goto unencrypted;
+ }
ret = -ENOENT;
goto errout;
}
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 6020b738c3b2..fb48961c46f6 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -102,6 +102,8 @@ struct fscrypt_nokey_name {
* pages for writes and therefore won't need the fscrypt bounce page pool.
*/
#define FS_CFLG_OWN_PAGES (1U << 1)
+/* The filesystem allows partially encrypted directories/files. */
+#define FS_CFLG_ALLOW_PARTIAL (1U << 2)
/* Crypto operations for filesystems */
struct fscrypt_operations {
--
2.35.1
Powered by blists - more mailing lists