From patchwork Fri Aug 21 18:28:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730249 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9CB771731 for ; Fri, 21 Aug 2020 18:29:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8633C230FF for ; Fri, 21 Aug 2020 18:29:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034558; bh=0WSGg0EIU7FP0CS/ruZRELlwNGgiar1sXoK/2aZAuow=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=ZXLbrY7QEvU5yfrsrgcuirQFxbBe9nPP51LVTRUAN/2y+C1U3fPdfXApIvSA+PONg pl3Kul1qDAnNl5DQMIvy8itBjCg9wuJ8iIBp+Vf3/obdhM9OvjDUlqdvYzksrtQhn9 2IM9qjMBEwfBIraVGLA9AYbBy9Z5nc4pD8GLgjfw= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726600AbgHUS2S (ORCPT ); Fri, 21 Aug 2020 14:28:18 -0400 Received: from mail.kernel.org ([198.145.29.99]:59354 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725867AbgHUS2Q (ORCPT ); Fri, 21 Aug 2020 14:28:16 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 30A8C230FF; Fri, 21 Aug 2020 18:28:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034495; bh=0WSGg0EIU7FP0CS/ruZRELlwNGgiar1sXoK/2aZAuow=; h=From:To:Subject:Date:In-Reply-To:References:From; b=pU8sMNT5RMfSa1UlHp1iWwLC0wCNdi4qx3Ttfv/r9K0imGE5NJesWl9dOhzTdz6u2 iNQ0QKKkgqeBKMz1GW0M6VMgjFgm6C0qPzqRLqQCtqu9tnr7b3ApM7bZTqCin6k6Qw 0W/G+5D1bj5vZzihTlWJYIzXlWYH3mypBzUVcnww= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 01/14] fscrypt: drop unused inode argument from fscrypt_fname_alloc_buffer Date: Fri, 21 Aug 2020 14:28:00 -0400 Message-Id: <20200821182813.52570-2-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Signed-off-by: Jeff Layton --- fs/crypto/fname.c | 5 +---- fs/crypto/hooks.c | 2 +- fs/ext4/dir.c | 2 +- fs/ext4/namei.c | 7 +++---- fs/f2fs/dir.c | 2 +- fs/ubifs/dir.c | 2 +- include/linux/fscrypt.h | 5 ++--- 7 files changed, 10 insertions(+), 15 deletions(-) diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 011830f84d8d..47bcfddb278b 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -260,8 +260,6 @@ bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len, /** * fscrypt_fname_alloc_buffer() - allocate a buffer for presented filenames - * @inode: inode of the parent directory (for regular filenames) - * or of the symlink (for symlink targets) * @max_encrypted_len: maximum length of encrypted filenames the buffer will be * used to present * @crypto_str: (output) buffer to allocate @@ -271,8 +269,7 @@ bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len, * * Return: 0 on success, -errno on failure */ -int fscrypt_fname_alloc_buffer(const struct inode *inode, - u32 max_encrypted_len, +int fscrypt_fname_alloc_buffer(u32 max_encrypted_len, struct fscrypt_str *crypto_str) { const u32 max_encoded_len = BASE64_CHARS(FSCRYPT_NOKEY_NAME_MAX); diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c index 09fb8aa0f2e9..491b252843eb 100644 --- a/fs/crypto/hooks.c +++ b/fs/crypto/hooks.c @@ -319,7 +319,7 @@ const char *fscrypt_get_symlink(struct inode *inode, const void *caddr, if (cstr.len + sizeof(*sd) - 1 > max_size) return ERR_PTR(-EUCLEAN); - err = fscrypt_fname_alloc_buffer(inode, cstr.len, &pstr); + err = fscrypt_fname_alloc_buffer(cstr.len, &pstr); if (err) return ERR_PTR(err); diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 1d82336b1cd4..efe77cffc322 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -148,7 +148,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx) } if (IS_ENCRYPTED(inode)) { - err = fscrypt_fname_alloc_buffer(inode, EXT4_NAME_LEN, &fstr); + err = fscrypt_fname_alloc_buffer(EXT4_NAME_LEN, &fstr); if (err < 0) return err; } diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 56738b538ddf..f41c8bfe8b5a 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -663,8 +663,7 @@ static struct stats dx_show_leaf(struct inode *dir, /* Directory is encrypted */ res = fscrypt_fname_alloc_buffer( - dir, len, - &fname_crypto_str); + len, &fname_crypto_str); if (res) printk(KERN_WARNING "Error " "allocating crypto " @@ -1016,8 +1015,8 @@ static int htree_dirblock_to_tree(struct file *dir_file, brelse(bh); return err; } - err = fscrypt_fname_alloc_buffer(dir, EXT4_NAME_LEN, - &fname_crypto_str); + err = fscrypt_fname_alloc_buffer(EXT4_NAME_LEN, + &fname_crypto_str); if (err < 0) { brelse(bh); return err; diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 069f498af1e3..b2530b9507bd 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -1032,7 +1032,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) if (err) goto out; - err = fscrypt_fname_alloc_buffer(inode, F2FS_NAME_LEN, &fstr); + err = fscrypt_fname_alloc_buffer(F2FS_NAME_LEN, &fstr); if (err < 0) goto out; } diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 9d042942d8b2..a9c1f5a9c9bd 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -515,7 +515,7 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx) if (err) return err; - err = fscrypt_fname_alloc_buffer(dir, UBIFS_MAX_NLEN, &fstr); + err = fscrypt_fname_alloc_buffer(UBIFS_MAX_NLEN, &fstr); if (err) return err; diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 991ff8575d0e..eaf16eb55788 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -197,7 +197,7 @@ static inline void fscrypt_free_filename(struct fscrypt_name *fname) kfree(fname->crypto_buf.name); } -int fscrypt_fname_alloc_buffer(const struct inode *inode, u32 max_encrypted_len, +int fscrypt_fname_alloc_buffer(u32 max_encrypted_len, struct fscrypt_str *crypto_str); void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str); int fscrypt_fname_disk_to_usr(const struct inode *inode, @@ -428,8 +428,7 @@ static inline void fscrypt_free_filename(struct fscrypt_name *fname) return; } -static inline int fscrypt_fname_alloc_buffer(const struct inode *inode, - u32 max_encrypted_len, +static inline int fscrypt_fname_alloc_buffer(u32 max_encrypted_len, struct fscrypt_str *crypto_str) { return -EOPNOTSUPP; From patchwork Fri Aug 21 18:28:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730201 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DF042618 for ; Fri, 21 Aug 2020 18:28:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C687523106 for ; Fri, 21 Aug 2020 18:28:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034500; bh=fpltE6CsINdq5JTodJ6i1B2vTSGZq6xV+oRtSc2jF0Q=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=SRfs2Q1fapNcC1ns8qN1A27a11dU2v7z9e7eW2HsTzv6/uqhjUM5Ziz68wVhwR0WY uYtVKwvhEEX3wHIjXG/ug+BvvrXKrlOWi8ZDj/jxx5cLwqDN4NX8f1zjwLVdw17wlR 0CObP8y9L20Smy+viUYMlOO7AhlJHBnM6ZGk9Pbc= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726633AbgHUS2S (ORCPT ); Fri, 21 Aug 2020 14:28:18 -0400 Received: from mail.kernel.org ([198.145.29.99]:59364 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725772AbgHUS2Q (ORCPT ); Fri, 21 Aug 2020 14:28:16 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id AE5AC23100; Fri, 21 Aug 2020 18:28:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034496; bh=fpltE6CsINdq5JTodJ6i1B2vTSGZq6xV+oRtSc2jF0Q=; h=From:To:Subject:Date:In-Reply-To:References:From; b=2mmFNCUnCcFDCCVUQ3AK4EU06TnCDTzaMH5NGuTntrT8KOvD0Ww0cwKe1LvZCecM5 7ulbBmEg7dd+v8m9LbjHRrQOfdpQF5bgIbYasR+WAQUA9iCEY4nOqTCwEJaIQ9TAJ+ nsnxfWCw61Fcj+QkTYsPUF1hYlV7nxQYb5RV2/eg= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 02/14] fscrypt: add fscrypt_new_context_from_parent Date: Fri, 21 Aug 2020 14:28:01 -0400 Message-Id: <20200821182813.52570-3-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Network filesystems usually don't know what inode number they'll have until after the reply to a create RPC comes in. But we do need a (blank) crypto context before that point. Break out the part of fscrypt_inherit_context that creates a new context without setting it into the new inode just yet. Signed-off-by: Jeff Layton --- fs/crypto/policy.c | 42 ++++++++++++++++++++++++++++++----------- include/linux/fscrypt.h | 6 ++++++ 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index 2d73fd39ad96..13e0a50157d5 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -621,19 +621,19 @@ int fscrypt_has_permitted_context(struct inode *parent, struct inode *child) EXPORT_SYMBOL(fscrypt_has_permitted_context); /** - * fscrypt_inherit_context() - Sets a child context from its parent + * fscrypt_new_context_from_parent() - generate a new fscrypt context from its parent * @parent: Parent inode from which the context is inherited. - * @child: Child inode that inherits the context from @parent. - * @fs_data: private data given by FS. - * @preload: preload child i_crypt_info if true + * @ctx: destination for new encryption context * - * Return: 0 on success, -errno on failure + * Generate a new encryption context for an inode from its parent, suitable + * for later installation into a child dentry's inode. Returns positive + * length of the new context on success, or -errno on failure. + * + * Note that the caller must ensure that it provides sufficient buffer space + * to write out the context (at least FSCRYPT_SET_CONTEXT_MAX_SIZE bytes). */ -int fscrypt_inherit_context(struct inode *parent, struct inode *child, - void *fs_data, bool preload) +int fscrypt_new_context_from_parent(struct inode *parent, void *ctx) { - union fscrypt_context ctx; - int ctxsize; struct fscrypt_info *ci; int res; @@ -645,10 +645,30 @@ int fscrypt_inherit_context(struct inode *parent, struct inode *child, if (ci == NULL) return -ENOKEY; - ctxsize = fscrypt_new_context_from_policy(&ctx, &ci->ci_policy); + return fscrypt_new_context_from_policy(ctx, &ci->ci_policy); +} +EXPORT_SYMBOL(fscrypt_new_context_from_parent); + +/** + * fscrypt_inherit_context() - Sets a child context from its parent + * @parent: Parent inode from which the context is inherited. + * @child: Child inode that inherits the context from @parent. + * @fs_data: private data given by FS. + * @preload: preload child i_crypt_info if true + * + * Return: 0 on success, -errno on failure + */ +int fscrypt_inherit_context(struct inode *parent, struct inode *child, + void *fs_data, bool preload) +{ + union fscrypt_context ctx; + int res; BUILD_BUG_ON(sizeof(ctx) != FSCRYPT_SET_CONTEXT_MAX_SIZE); - res = parent->i_sb->s_cop->set_context(child, &ctx, ctxsize, fs_data); + res = fscrypt_new_context_from_parent(parent, &ctx); + if (res < 0) + return res; + res = parent->i_sb->s_cop->set_context(child, &ctx, res, fs_data); if (res) return res; return preload ? fscrypt_get_encryption_info(child): 0; diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index eaf16eb55788..c5fe6f334a1d 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -156,6 +156,7 @@ int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg); int fscrypt_ioctl_get_policy_ex(struct file *filp, void __user *arg); int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg); int fscrypt_has_permitted_context(struct inode *parent, struct inode *child); +int fscrypt_new_context_from_parent(struct inode *parent, void *); int fscrypt_inherit_context(struct inode *parent, struct inode *child, void *fs_data, bool preload); @@ -340,6 +341,11 @@ static inline int fscrypt_has_permitted_context(struct inode *parent, return 0; } +static inline int fscrypt_new_context_from_parent(struct inode *parent, void *ctx); +{ + return -EOPNOTSUPP; +} + static inline int fscrypt_inherit_context(struct inode *parent, struct inode *child, void *fs_data, bool preload) From patchwork Fri Aug 21 18:28:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730253 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8AE81618 for ; Fri, 21 Aug 2020 18:29:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 72DB0230FF for ; Fri, 21 Aug 2020 18:29:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034566; bh=ND4FcgD/NUSJ8C4KRjBaer7sEEz7pzhowVhqTtPqG0U=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=GJZq6emCGI3Z3dlKF7BfEd1sPn2OVAeMSsSncgtpM4tKeMw5bBLsRku0h1jJt99uG eQ0kP+o8wRdmlvipRNVZd3uiUMTiLJS09INoeVGO4WS79mD1VPfBNETysx7AZOek3k sG4zG/K7T/YC0p1w8mFC2lSHao189gPnp0aVQt6o= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726829AbgHUS3Y (ORCPT ); Fri, 21 Aug 2020 14:29:24 -0400 Received: from mail.kernel.org ([198.145.29.99]:59370 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725916AbgHUS2Q (ORCPT ); Fri, 21 Aug 2020 14:28:16 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 378C823101; Fri, 21 Aug 2020 18:28:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034496; bh=ND4FcgD/NUSJ8C4KRjBaer7sEEz7pzhowVhqTtPqG0U=; h=From:To:Subject:Date:In-Reply-To:References:From; b=BbdAviWSwqSwfnEpaHQYLHh/5oyL+NVvNkC/ZgwAFLbVICvQYYCxlb+XkaeU+nlm1 r6xd9SLq8ssVootlbvvcjZTrOFrydCzTiAuiVcWPFiJF/vy9m1P9/h2piDF828RwJo kypdvqDmHp0KVCkKz3h+XDB0/ediGyhDGQzgiPTA= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 03/14] fscrypt: don't balk when inode is already marked encrypted Date: Fri, 21 Aug 2020 14:28:02 -0400 Message-Id: <20200821182813.52570-4-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Cephfs (currently) sets this flag early and only fetches the context later. Eventually we may not need this, but for now it prevents this warning from popping. Signed-off-by: Jeff Layton --- fs/crypto/keysetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index fea6226afc2b..587335dc7cb9 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -474,7 +474,7 @@ int fscrypt_get_encryption_info(struct inode *inode) const union fscrypt_context *dummy_ctx = fscrypt_get_dummy_context(inode->i_sb); - if (IS_ENCRYPTED(inode) || !dummy_ctx) { + if (!dummy_ctx) { fscrypt_warn(inode, "Error %d getting encryption context", res); From patchwork Fri Aug 21 18:28:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730251 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ADFE41731 for ; Fri, 21 Aug 2020 18:29:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8DDBE23100 for ; Fri, 21 Aug 2020 18:29:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034564; bh=T/M4OXWBroU11ggvljowQQvLMcwOL2ubdcuKlfIqQhM=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=sqeoqyTHHNS8T7lgS4z9yDBTFXkI5xkyR+vfkOfEv4G3plGtN5t0lqm8HKrRssoDM nSYj7VjN/KAHxSx6jnvG8Ubh145v8stvAZZJDJjLCUL4qdbGli1rql6BXXgXRFyVPs 9UGtYh3MRqh1O1YkuEZfh0a5uBRqnVKqkk2muvZE= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726461AbgHUS3Y (ORCPT ); Fri, 21 Aug 2020 14:29:24 -0400 Received: from mail.kernel.org ([198.145.29.99]:59380 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726057AbgHUS2R (ORCPT ); Fri, 21 Aug 2020 14:28:17 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id B4E3D23102; Fri, 21 Aug 2020 18:28:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034497; bh=T/M4OXWBroU11ggvljowQQvLMcwOL2ubdcuKlfIqQhM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Ws7WjprIgvWrQ/Ea1qTDlaAZQIAZKCF1KvLsGG5FQaWdWPisP730+LZ4UMd2iDU6t LRDgWix4Su3gJmUc7Pzrdh3yPkzh89ePrWkHE+HPs6wEGoMsxhNKpI+TmsROh0p2e0 HKodvJTk6AV4a6qUKIiMoaIn/qLP9Y2qrkQ9gSas= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 04/14] fscrypt: export fscrypt_d_revalidate Date: Fri, 21 Aug 2020 14:28:03 -0400 Message-Id: <20200821182813.52570-5-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org ceph already has its own d_revalidate op so we can't rely on fscrypt using that directly. Export this symbol so filesystems can call it from their own d_revalidate op. Signed-off-by: Jeff Layton --- fs/crypto/fname.c | 3 ++- include/linux/fscrypt.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 47bcfddb278b..9440a44e24ac 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -538,7 +538,7 @@ EXPORT_SYMBOL_GPL(fscrypt_fname_siphash); * Validate dentries in encrypted directories to make sure we aren't potentially * caching stale dentries after a key has been added. */ -static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) +int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) { struct dentry *dir; int err; @@ -577,6 +577,7 @@ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) return valid; } +EXPORT_SYMBOL_GPL(fscrypt_d_revalidate); const struct dentry_operations fscrypt_d_ops = { .d_revalidate = fscrypt_d_revalidate, diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index c5fe6f334a1d..41300eac45a4 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -208,6 +208,7 @@ int fscrypt_fname_disk_to_usr(const struct inode *inode, bool fscrypt_match_name(const struct fscrypt_name *fname, const u8 *de_name, u32 de_name_len); u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name); +int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags); /* bio.c */ void fscrypt_decrypt_bio(struct bio *bio); From patchwork Fri Aug 21 18:28:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730207 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 16F361744 for ; Fri, 21 Aug 2020 18:28:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 00F8923106 for ; Fri, 21 Aug 2020 18:28:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034507; bh=SZwwaY4kzg1f2etJWydeWhfXiR5upplKAGhJlRtoNnA=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=JylLr77+SbNAx5YF5BbbXnd2CXhVgzbDbMsztxH+p9SQEKBKlway9JL4yZ2/t4uNZ e44ETKBiIyghQtUC2Z904D8Tkhq4aTxiegIo9aJccLvKowAm40X3QiUs80rH8BrYeK HEB37LZqizHIJm8nT/ChChLM48TfajzaTF9eLqLg= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726670AbgHUS2Y (ORCPT ); Fri, 21 Aug 2020 14:28:24 -0400 Received: from mail.kernel.org ([198.145.29.99]:59388 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726118AbgHUS2S (ORCPT ); Fri, 21 Aug 2020 14:28:18 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 3E92C23105; Fri, 21 Aug 2020 18:28:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034497; bh=SZwwaY4kzg1f2etJWydeWhfXiR5upplKAGhJlRtoNnA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=XZEx2CU8YW4wKk63ME5WADq6CWBvbjBmFkOTe8PpqgHRKtCS88O5dUdndv9k3wOGW q2sX9fm1nPXkBa4Ycgomm5r4nzyNSQKLL4psiCDzWJT7WjdheAkYav18JRc59jnNZh zE1B96l7cBGPc2qp5dryrkYBrtNjIUjiT33MLljQ= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 05/14] lib: lift fscrypt base64 conversion into lib/ Date: Fri, 21 Aug 2020 14:28:04 -0400 Message-Id: <20200821182813.52570-6-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Once we allow encrypted filenames we'll end up with names that may have illegal characters in them (embedded '\0' or '/'), or characters that aren't printable. It'll be safer to use strings that are printable. It turns out that the MDS doesn't really care about the length of filenames, so we can just base64 encode and decode filenames before writing and reading them. Lift the base64 implementation that's in fscrypt into lib/. Make fscrypt select it when it's enabled. Signed-off-by: Jeff Layton --- fs/crypto/Kconfig | 1 + fs/crypto/fname.c | 59 +---------------------------------- include/linux/base64.h | 11 +++++++ lib/Kconfig | 3 ++ lib/Makefile | 1 + lib/base64.c | 71 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 88 insertions(+), 58 deletions(-) create mode 100644 include/linux/base64.h create mode 100644 lib/base64.c diff --git a/fs/crypto/Kconfig b/fs/crypto/Kconfig index a5f5c30368a2..49219017f7e9 100644 --- a/fs/crypto/Kconfig +++ b/fs/crypto/Kconfig @@ -6,6 +6,7 @@ config FS_ENCRYPTION select CRYPTO_SKCIPHER select CRYPTO_LIB_SHA256 select KEYS + select BASE64 help Enable encryption of files and directories. This feature is similar to ecryptfs, but it is more memory diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 9440a44e24ac..6a6bbe8f8db7 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -11,6 +11,7 @@ * This has not yet undergone a rigorous security audit. */ +#include #include #include #include @@ -184,64 +185,6 @@ static int fname_decrypt(const struct inode *inode, return 0; } -static const char lookup_table[65] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"; - -#define BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3) - -/** - * base64_encode() - base64-encode some bytes - * @src: the bytes to encode - * @len: number of bytes to encode - * @dst: (output) the base64-encoded string. Not NUL-terminated. - * - * Encodes the input string using characters from the set [A-Za-z0-9+,]. - * The encoded string is roughly 4/3 times the size of the input string. - * - * Return: length of the encoded string - */ -static int base64_encode(const u8 *src, int len, char *dst) -{ - int i, bits = 0, ac = 0; - char *cp = dst; - - for (i = 0; i < len; i++) { - ac += src[i] << bits; - bits += 8; - do { - *cp++ = lookup_table[ac & 0x3f]; - ac >>= 6; - bits -= 6; - } while (bits >= 6); - } - if (bits) - *cp++ = lookup_table[ac & 0x3f]; - return cp - dst; -} - -static int base64_decode(const char *src, int len, u8 *dst) -{ - int i, bits = 0, ac = 0; - const char *p; - u8 *cp = dst; - - for (i = 0; i < len; i++) { - p = strchr(lookup_table, src[i]); - if (p == NULL || src[i] == 0) - return -2; - ac += (p - lookup_table) << bits; - bits += 6; - if (bits >= 8) { - *cp++ = ac & 0xff; - ac >>= 8; - bits -= 8; - } - } - if (ac) - return -1; - return cp - dst; -} - bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len, u32 max_len, u32 *encrypted_len_ret) { diff --git a/include/linux/base64.h b/include/linux/base64.h new file mode 100644 index 000000000000..bde7a936ed21 --- /dev/null +++ b/include/linux/base64.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 + +#ifndef _LIB_BASE64_H +#define _LIB_BASE64_H +#include + +#define BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3) + +int base64_encode(const u8 *src, int len, char *dst); +int base64_decode(const char *src, int len, u8 *dst); +#endif /* _LIB_BASE64_H */ diff --git a/lib/Kconfig b/lib/Kconfig index b4b98a03ff98..507e851d220b 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -684,3 +684,6 @@ config GENERIC_LIB_UCMPDI2 config PLDMFW bool default n + +config BASE64 + tristate diff --git a/lib/Makefile b/lib/Makefile index e290fc5707ea..4d76755e609c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -166,6 +166,7 @@ obj-$(CONFIG_LIBCRC32C) += libcrc32c.o obj-$(CONFIG_CRC8) += crc8.o obj-$(CONFIG_XXHASH) += xxhash.o obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o +obj-$(CONFIG_BASE64) += base64.o obj-$(CONFIG_842_COMPRESS) += 842/ obj-$(CONFIG_842_DECOMPRESS) += 842/ diff --git a/lib/base64.c b/lib/base64.c new file mode 100644 index 000000000000..5f1480da6559 --- /dev/null +++ b/lib/base64.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * base64 encode/decode functions + * + * Originally lifted from fs/crypto/fname.c + * + * Copyright (C) 2015, Jaegeuk Kim + * Copyright (C) 2015, Eric Biggers + */ + +#include +#include +#include + +static const char lookup_table[65] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"; + +/** + * base64_encode() - base64-encode some bytes + * @src: the bytes to encode + * @len: number of bytes to encode + * @dst: (output) the base64-encoded string. Not NUL-terminated. + * + * Encodes the input string using characters from the set [A-Za-z0-9+,]. + * The encoded string is roughly 4/3 times the size of the input string. + * + * Return: length of the encoded string + */ +int base64_encode(const u8 *src, int len, char *dst) +{ + int i, bits = 0, ac = 0; + char *cp = dst; + + for (i = 0; i < len; i++) { + ac += src[i] << bits; + bits += 8; + do { + *cp++ = lookup_table[ac & 0x3f]; + ac >>= 6; + bits -= 6; + } while (bits >= 6); + } + if (bits) + *cp++ = lookup_table[ac & 0x3f]; + return cp - dst; +} +EXPORT_SYMBOL(base64_encode); + +int base64_decode(const char *src, int len, u8 *dst) +{ + int i, bits = 0, ac = 0; + const char *p; + u8 *cp = dst; + + for (i = 0; i < len; i++) { + p = strchr(lookup_table, src[i]); + if (p == NULL || src[i] == 0) + return -2; + ac += (p - lookup_table) << bits; + bits += 6; + if (bits >= 8) { + *cp++ = ac & 0xff; + ac >>= 8; + bits -= 8; + } + } + if (ac) + return -1; + return cp - dst; +} +EXPORT_SYMBOL(base64_decode); From patchwork Fri Aug 21 18:28:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730205 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BE7561731 for ; Fri, 21 Aug 2020 18:28:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9E78323106 for ; Fri, 21 Aug 2020 18:28:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034506; bh=G5SLYptlAQ4JAFL5GEkqLWRhYSCKv0S/WO0G7hzpNk4=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=oO2kEZ1cTUqR6Gg+bR687WwDvVxxtdhStoUwdsv89LkDIgy1JEEONFqYMtE8Mnx+s bBRKt5LDNkDKweTi0vBD8FLa9QYo6unbCrz0FegULXOdZepsZF9XqrFgHJu5C4vzdV 2rzTFWn3GJIU+JRfg8xbMlZ5F+wOrw3/19lpHiTw= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726666AbgHUS2W (ORCPT ); Fri, 21 Aug 2020 14:28:22 -0400 Received: from mail.kernel.org ([198.145.29.99]:59394 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726332AbgHUS2S (ORCPT ); Fri, 21 Aug 2020 14:28:18 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id BCA3922EBF; Fri, 21 Aug 2020 18:28:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034498; bh=G5SLYptlAQ4JAFL5GEkqLWRhYSCKv0S/WO0G7hzpNk4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=TqLrG1PM3mfc8mmeFVOq0K/Flqfcz6Jw79sBUbiBXnNJwa8FlUEmQfxiRjpJ2dw6c rLyP0ien8I+DtDIp51kOPWmEznjboIH7fa2dI5ZvXrQQUIN7zcZ2fj3JENaeN+Sqz/ KW91am8/rFgM4lSR3nP0ZMrs1WJ+PS5Bo9SYQc4Y= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 06/14] ceph: add fscrypt ioctls Date: Fri, 21 Aug 2020 14:28:05 -0400 Message-Id: <20200821182813.52570-7-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Boilerplate ioctls for controlling encryption. Signed-off-by: Jeff Layton --- fs/ceph/ioctl.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index 6e061bf62ad4..4400b170eca9 100644 --- a/fs/ceph/ioctl.c +++ b/fs/ceph/ioctl.c @@ -6,6 +6,7 @@ #include "mds_client.h" #include "ioctl.h" #include +#include /* * ioctls @@ -289,6 +290,31 @@ long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case CEPH_IOC_SYNCIO: return ceph_ioctl_syncio(file); +#ifdef CONFIG_FS_ENCRYPTION + case FS_IOC_SET_ENCRYPTION_POLICY: + return fscrypt_ioctl_set_policy(file, (const void __user *)arg); + + case FS_IOC_GET_ENCRYPTION_POLICY: + return fscrypt_ioctl_get_policy(file, (void __user *)arg); + + case FS_IOC_GET_ENCRYPTION_POLICY_EX: + return fscrypt_ioctl_get_policy_ex(file, (void __user *)arg); + + case FS_IOC_ADD_ENCRYPTION_KEY: + return fscrypt_ioctl_add_key(file, (void __user *)arg); + + case FS_IOC_REMOVE_ENCRYPTION_KEY: + return fscrypt_ioctl_remove_key(file, (void __user *)arg); + + case FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS: + return fscrypt_ioctl_remove_key_all_users(file, (void __user *)arg); + + case FS_IOC_GET_ENCRYPTION_KEY_STATUS: + return fscrypt_ioctl_get_key_status(file, (void __user *)arg); + + case FS_IOC_GET_ENCRYPTION_NONCE: + return fscrypt_ioctl_get_nonce(file, (void __user *)arg); +#endif /* CONFIG_FS_ENCRYPTION */ } return -ENOTTY; From patchwork Fri Aug 21 18:28:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730211 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 97E9E618 for ; Fri, 21 Aug 2020 18:28:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7C48F23100 for ; Fri, 21 Aug 2020 18:28:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034512; bh=1DfYOxWFy3g7yCl/mAi33qZBVTOj8rAn6OxzkU4ZsS4=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=O7D1sCM8kkcOmLkgrNIlT580NMe1HmrtTvxUuvj2Q+bMosakXAqekoVUa/0ileZxt s+vrVET5dXBTWDe/m5U4RCm0rYT/j+51wfJQYluFouz7ab64b56PFG0LRz2BzyM3lf rJamgnKUG+eW438hiFDazRz7glVLsJDJ09fzY58M= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726688AbgHUS23 (ORCPT ); Fri, 21 Aug 2020 14:28:29 -0400 Received: from mail.kernel.org ([198.145.29.99]:59404 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726541AbgHUS2T (ORCPT ); Fri, 21 Aug 2020 14:28:19 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 45DA0230FF; Fri, 21 Aug 2020 18:28:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034498; bh=1DfYOxWFy3g7yCl/mAi33qZBVTOj8rAn6OxzkU4ZsS4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=LkY7/ZKNOhyfpbRNHxLBiFlaa39u0w9SR0KbZREfMlRAQHj4+F14beybhRfhfqxOh R2rvAUQ+dGM2c0VHXLnKo16dy/d/iZcucIuEw0hCe/TEDDHoTohddpvmx+m5ffRjs7 pAIjrHrsOJGV37fzNZDh1IQCUlDcH3TwBWdgsdJk= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 07/14] ceph: crypto context handling for ceph Date: Fri, 21 Aug 2020 14:28:06 -0400 Message-Id: <20200821182813.52570-8-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Eventually, we'll probably want to store the crypto context in a dedicated field in the inode, but for now it's stored in a (plain) xattr. Also add support for "dummy" encryption (useful for testing with automated test harnesses like xfstests). Signed-off-by: Jeff Layton --- fs/ceph/Makefile | 1 + fs/ceph/crypto.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/ceph/crypto.h | 26 ++++++++++++++++++ fs/ceph/inode.c | 3 +++ fs/ceph/super.c | 37 ++++++++++++++++++++++++++ fs/ceph/super.h | 6 ++++- 6 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 fs/ceph/crypto.c create mode 100644 fs/ceph/crypto.h diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile index 50c635dc7f71..1f77ca04c426 100644 --- a/fs/ceph/Makefile +++ b/fs/ceph/Makefile @@ -12,3 +12,4 @@ ceph-y := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \ ceph-$(CONFIG_CEPH_FSCACHE) += cache.o ceph-$(CONFIG_CEPH_FS_POSIX_ACL) += acl.o +ceph-$(CONFIG_FS_ENCRYPTION) += crypto.o diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c new file mode 100644 index 000000000000..22a09d422b72 --- /dev/null +++ b/fs/ceph/crypto.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +#include "super.h" +#include "crypto.h" + +static int ceph_crypt_get_context(struct inode *inode, void *ctx, size_t len) +{ + int ret = __ceph_getxattr(inode, CEPH_XATTR_NAME_ENCRYPTION_CONTEXT, ctx, len); + + if (ret > 0) + inode_set_flags(inode, S_ENCRYPTED, S_ENCRYPTED); + return ret; +} + +static int ceph_crypt_set_context(struct inode *inode, const void *ctx, size_t len, void *fs_data) +{ + int ret; + + WARN_ON_ONCE(fs_data); + ret = __ceph_setxattr(inode, CEPH_XATTR_NAME_ENCRYPTION_CONTEXT, ctx, len, XATTR_CREATE); + if (ret == 0) + inode_set_flags(inode, S_ENCRYPTED, S_ENCRYPTED); + return ret; +} + +static bool ceph_crypt_empty_dir(struct inode *inode) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + + return ci->i_rsubdirs + ci->i_rfiles == 1; +} + +static const union fscrypt_context * +ceph_get_dummy_context(struct super_block *sb) +{ + return ceph_sb_to_client(sb)->dummy_enc_ctx.ctx; +} + +static struct fscrypt_operations ceph_fscrypt_ops = { + .key_prefix = "ceph:", + .get_context = ceph_crypt_get_context, + .set_context = ceph_crypt_set_context, + .get_dummy_context = ceph_get_dummy_context, + .empty_dir = ceph_crypt_empty_dir, + .max_namelen = NAME_MAX, +}; + +int ceph_fscrypt_set_ops(struct super_block *sb) +{ + struct ceph_fs_client *fsc = sb->s_fs_info; + + fscrypt_set_ops(sb, &ceph_fscrypt_ops); + + if (ceph_test_mount_opt(fsc, TEST_DUMMY_ENC)) { + substring_t arg = { }; + + /* Ewwwwwwww */ + if (fsc->mount_options->test_dummy_encryption) { + arg.from = fsc->mount_options->test_dummy_encryption; + arg.to = arg.from + strlen(arg.from) - 1; + } + + return fscrypt_set_test_dummy_encryption(sb, &arg, &fsc->dummy_enc_ctx); + } + return 0; +} diff --git a/fs/ceph/crypto.h b/fs/ceph/crypto.h new file mode 100644 index 000000000000..309925b345fc --- /dev/null +++ b/fs/ceph/crypto.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Ceph fscrypt functionality + */ + +#ifndef _CEPH_CRYPTO_H +#define _CEPH_CRYPTO_H + +#ifdef CONFIG_FS_ENCRYPTION + +#define DUMMY_ENCRYPTION_ENABLED(fsc) ((fsc)->dummy_enc_ctx.ctx != NULL) + +int ceph_fscrypt_set_ops(struct super_block *sb); + +#else /* CONFIG_FS_ENCRYPTION */ + +#define DUMMY_ENCRYPTION_ENABLED(fsc) (0) + +static inline int ceph_fscrypt_set_ops(struct super_block *sb) +{ + return 0; +} + +#endif /* CONFIG_FS_ENCRYPTION */ + +#endif diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 156b98bda6aa..877bdda40db8 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -532,6 +532,8 @@ void ceph_free_inode(struct inode *inode) struct ceph_inode_info *ci = ceph_inode(inode); kfree(ci->i_symlink); + // FIXME: only call this once we have symlink support + // fscrypt_free_inode(inode); kmem_cache_free(ceph_inode_cachep, ci); } @@ -543,6 +545,7 @@ void ceph_evict_inode(struct inode *inode) dout("evict_inode %p ino %llx.%llx\n", inode, ceph_vinop(inode)); + fscrypt_put_encryption_info(inode); truncate_inode_pages_final(&inode->i_data); clear_inode(inode); diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 7ec0e6d03d10..95f5a7cf60f2 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -20,6 +20,7 @@ #include "super.h" #include "mds_client.h" #include "cache.h" +#include "crypto.h" #include #include @@ -44,6 +45,7 @@ static void ceph_put_super(struct super_block *s) struct ceph_fs_client *fsc = ceph_sb_to_client(s); dout("put_super\n"); + fscrypt_free_dummy_context(&fsc->dummy_enc_ctx); ceph_mdsc_close_sessions(fsc->mdsc); } @@ -159,6 +161,7 @@ enum { Opt_quotadf, Opt_copyfrom, Opt_wsync, + Opt_test_dummy_encryption, }; enum ceph_recover_session_mode { @@ -197,6 +200,8 @@ static const struct fs_parameter_spec ceph_mount_parameters[] = { fsparam_u32 ("rsize", Opt_rsize), fsparam_string ("snapdirname", Opt_snapdirname), fsparam_string ("source", Opt_source), + fsparam_flag_no ("test_dummy_encryption", Opt_test_dummy_encryption), + fsparam_string ("test_dummy_encryption", Opt_test_dummy_encryption), fsparam_u32 ("wsize", Opt_wsize), fsparam_flag_no ("wsync", Opt_wsync), {} @@ -455,6 +460,21 @@ static int ceph_parse_mount_param(struct fs_context *fc, else fsopt->flags |= CEPH_MOUNT_OPT_ASYNC_DIROPS; break; + case Opt_test_dummy_encryption: + kfree(fsopt->test_dummy_encryption); + fsopt->test_dummy_encryption = NULL; + if (!result.negated) { +#ifdef CONFIG_FS_ENCRYPTION + fsopt->test_dummy_encryption = param->string; + param->string = NULL; + fsopt->flags |= CEPH_MOUNT_OPT_TEST_DUMMY_ENC; +#else + return warnfc(fc, "FS encryption not supported: test_dummy_encryption mount option ignored"); +#endif + } else { + fsopt->flags &= ~CEPH_MOUNT_OPT_TEST_DUMMY_ENC; + } + break; default: BUG(); } @@ -474,6 +494,7 @@ static void destroy_mount_options(struct ceph_mount_options *args) kfree(args->mds_namespace); kfree(args->server_path); kfree(args->fscache_uniq); + kfree(args->test_dummy_encryption); kfree(args); } @@ -581,6 +602,8 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root) if (fsopt->flags & CEPH_MOUNT_OPT_ASYNC_DIROPS) seq_puts(m, ",nowsync"); + fscrypt_show_test_dummy_encryption(m, ',', root->d_sb); + if (fsopt->wsize != CEPH_MAX_WRITE_SIZE) seq_printf(m, ",wsize=%u", fsopt->wsize); if (fsopt->rsize != CEPH_MAX_READ_SIZE) @@ -984,7 +1007,12 @@ static int ceph_set_super(struct super_block *s, struct fs_context *fc) s->s_time_min = 0; s->s_time_max = U32_MAX; + ret = ceph_fscrypt_set_ops(s); + if (ret) + goto out; + ret = set_anon_super_fc(s, fc); +out: if (ret != 0) fsc->sb = NULL; return ret; @@ -1140,6 +1168,15 @@ static int ceph_reconfigure_fc(struct fs_context *fc) else ceph_clear_mount_opt(fsc, ASYNC_DIROPS); + /* Don't allow test_dummy_encryption to change on remount */ + if (fsopt->flags & CEPH_MOUNT_OPT_TEST_DUMMY_ENC) { + if (!ceph_test_mount_opt(fsc, TEST_DUMMY_ENC)) + return -EEXIST; + } else { + if (ceph_test_mount_opt(fsc, TEST_DUMMY_ENC)) + return -EEXIST; + } + sync_filesystem(fc->root->d_sb); return 0; } diff --git a/fs/ceph/super.h b/fs/ceph/super.h index b3aa2395b66e..6327b5739286 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -44,6 +44,7 @@ #define CEPH_MOUNT_OPT_NOQUOTADF (1<<13) /* no root dir quota in statfs */ #define CEPH_MOUNT_OPT_NOCOPYFROM (1<<14) /* don't use RADOS 'copy-from' op */ #define CEPH_MOUNT_OPT_ASYNC_DIROPS (1<<15) /* allow async directory ops */ +#define CEPH_MOUNT_OPT_TEST_DUMMY_ENC (1<<16) /* enable dummy encryption (for testing) */ #define CEPH_MOUNT_OPT_DEFAULT \ (CEPH_MOUNT_OPT_DCACHE | \ @@ -96,6 +97,7 @@ struct ceph_mount_options { char *mds_namespace; /* default NULL */ char *server_path; /* default NULL (means "/") */ char *fscache_uniq; /* default NULL */ + char *test_dummy_encryption; /* default NULL */ }; struct ceph_fs_client { @@ -135,9 +137,11 @@ struct ceph_fs_client { #ifdef CONFIG_CEPH_FSCACHE struct fscache_cookie *fscache; #endif +#ifdef CONFIG_FS_ENCRYPTION + struct fscrypt_dummy_context dummy_enc_ctx; +#endif }; - /* * File i/o capability. This tracks shared state with the metadata * server that allows us to cache or writeback attributes or to read From patchwork Fri Aug 21 18:28:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730215 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0E9361731 for ; Fri, 21 Aug 2020 18:28:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EBD3B22EBF for ; Fri, 21 Aug 2020 18:28:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034515; bh=2iMgd9gzoGbTXYOv5cvo7OTc/B3IdOkCCK31kYZpqAs=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=J908ZFonTY0ARdD8gW2U5RgfV5vCE8p6u7hhfebVJMzv2dw8ZYP3FS1GcgHdWDVTW EtNCN3Js0npDXghOFNG9AxMXqj7e+IZxnHE6O1LXRgIOIhZ3tDjAV70ccQmO8GJtHW efq3nfkFwvmbGfK2q0afn9uMM7Ka08Bpa1BQdDJU= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725850AbgHUS2b (ORCPT ); Fri, 21 Aug 2020 14:28:31 -0400 Received: from mail.kernel.org ([198.145.29.99]:59416 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726635AbgHUS2T (ORCPT ); Fri, 21 Aug 2020 14:28:19 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C3CA823100; Fri, 21 Aug 2020 18:28:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034499; bh=2iMgd9gzoGbTXYOv5cvo7OTc/B3IdOkCCK31kYZpqAs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=fxTJctI3Fa5vwZlSuUzSj0EoOPzHKPMoKFDRf9DI08dOMNrMmlanw0Gkg445rKOiF x0bBYn7LwiKAuwH7Gcb3V9yynOB+NIC3m57DR0gaMgxnuLHxdyW/GNyE4jG7Aoo9lb /9KrdPqUrecRHsbxB0jafzVT7sfVX1Q5qohZl4G4= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 08/14] ceph: add routine to create context prior to RPC Date: Fri, 21 Aug 2020 14:28:07 -0400 Message-Id: <20200821182813.52570-9-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Allow the client to create a new encryption context prior to creating a new inode, and ensure that we set it in the ceph_acl_sec_ctx (alongside acls, selinux contexts, etc.). Signed-off-by: Jeff Layton --- fs/ceph/crypto.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/ceph/crypto.h | 8 +++++++ fs/ceph/dir.c | 15 +++++++++++++ fs/ceph/file.c | 4 ++++ fs/ceph/super.h | 4 ++++ 5 files changed, 86 insertions(+) diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c index 22a09d422b72..0e57497c2e55 100644 --- a/fs/ceph/crypto.c +++ b/fs/ceph/crypto.c @@ -67,3 +67,58 @@ int ceph_fscrypt_set_ops(struct super_block *sb) } return 0; } + +int ceph_fscrypt_new_context(struct inode *parent, struct ceph_acl_sec_ctx *as) +{ + int ret, ctxsize; + size_t name_len; + char *name; + struct ceph_pagelist *pagelist = as->pagelist; + + /* Do nothing if subtree isn't encrypted */ + if (!IS_ENCRYPTED(parent)) + return 0; + + ctxsize = fscrypt_new_context_from_parent(parent, as->fscrypt); + if (ctxsize <= 0) + return ctxsize; + + /* marshal it in page array */ + if (!pagelist) { + pagelist = ceph_pagelist_alloc(GFP_KERNEL); + if (!pagelist) + return -ENOMEM; + ret = ceph_pagelist_reserve(pagelist, PAGE_SIZE); + if (ret) + goto out; + ceph_pagelist_encode_32(pagelist, 1); + } + + name = CEPH_XATTR_NAME_ENCRYPTION_CONTEXT; + name_len = strlen(name); + ret = ceph_pagelist_reserve(pagelist, 4 * 2 + name_len + ctxsize); + if (ret) + goto out; + + if (as->pagelist) { + BUG_ON(pagelist->length <= sizeof(__le32)); + if (list_is_singular(&pagelist->head)) { + le32_add_cpu((__le32*)pagelist->mapped_tail, 1); + } else { + struct page *page = list_first_entry(&pagelist->head, + struct page, lru); + void *addr = kmap_atomic(page); + le32_add_cpu((__le32*)addr, 1); + kunmap_atomic(addr); + } + } + + ceph_pagelist_encode_32(pagelist, name_len); + ceph_pagelist_append(pagelist, name, name_len); + ceph_pagelist_encode_32(pagelist, ctxsize); + ceph_pagelist_append(pagelist, as->fscrypt, ctxsize); +out: + if (pagelist && !as->pagelist) + ceph_pagelist_release(pagelist); + return ret; +} diff --git a/fs/ceph/crypto.h b/fs/ceph/crypto.h index 309925b345fc..e7d00831ef36 100644 --- a/fs/ceph/crypto.h +++ b/fs/ceph/crypto.h @@ -8,9 +8,12 @@ #ifdef CONFIG_FS_ENCRYPTION +#define CEPH_XATTR_NAME_ENCRYPTION_CONTEXT "encryption.ctx" + #define DUMMY_ENCRYPTION_ENABLED(fsc) ((fsc)->dummy_enc_ctx.ctx != NULL) int ceph_fscrypt_set_ops(struct super_block *sb); +int ceph_fscrypt_new_context(struct inode *parent, struct ceph_acl_sec_ctx *as); #else /* CONFIG_FS_ENCRYPTION */ @@ -21,6 +24,11 @@ static inline int ceph_fscrypt_set_ops(struct super_block *sb) return 0; } +static int ceph_fscrypt_new_context(struct inode *parent, struct ceph_acl_sec_ctx *as) +{ + return 0; +} + #endif /* CONFIG_FS_ENCRYPTION */ #endif diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 34f669220a8b..2e7f2bfa2c12 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -9,6 +9,7 @@ #include "super.h" #include "mds_client.h" +#include "crypto.h" /* * Directory operations: readdir, lookup, create, link, unlink, @@ -848,6 +849,12 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry, if (err < 0) goto out; + if (S_ISREG(mode)) { + err = ceph_fscrypt_new_context(dir, &as_ctx); + if (err < 0) + goto out; + } + dout("mknod in dir %p dentry %p mode 0%ho rdev %d\n", dir, dentry, mode, rdev); req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKNOD, USE_AUTH_MDS); @@ -907,6 +914,10 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry, if (err < 0) goto out; + err = ceph_fscrypt_new_context(dir, &as_ctx); + if (err < 0) + goto out; + dout("symlink in dir %p dentry %p to '%s'\n", dir, dentry, dest); req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK, USE_AUTH_MDS); if (IS_ERR(req)) { @@ -975,6 +986,10 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) if (err < 0) goto out; + err = ceph_fscrypt_new_context(dir, &as_ctx); + if (err < 0) + goto out; + req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); if (IS_ERR(req)) { err = PTR_ERR(req); diff --git a/fs/ceph/file.c b/fs/ceph/file.c index cf3f66d75162..94558e04f34a 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -19,6 +19,7 @@ #include "cache.h" #include "io.h" #include "metric.h" +#include "crypto.h" static __le32 ceph_flags_sys2wire(u32 flags) { @@ -686,6 +687,9 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, err = ceph_security_init_secctx(dentry, mode, &as_ctx); if (err < 0) goto out_ctx; + err = ceph_fscrypt_new_context(dir, &as_ctx); + if (err < 0) + goto out_ctx; } else if (!d_in_lookup(dentry)) { /* If it's not being looked up, it's negative */ return -ENOENT; diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 6327b5739286..a481cacf775a 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -991,6 +992,9 @@ struct ceph_acl_sec_ctx { #ifdef CONFIG_CEPH_FS_SECURITY_LABEL void *sec_ctx; u32 sec_ctxlen; +#endif +#ifdef CONFIG_FS_ENCRYPTION + u8 fscrypt[FSCRYPT_SET_CONTEXT_MAX_SIZE]; #endif struct ceph_pagelist *pagelist; }; From patchwork Fri Aug 21 18:28:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730241 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C156C618 for ; Fri, 21 Aug 2020 18:29:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A963F230FF for ; Fri, 21 Aug 2020 18:29:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034549; bh=lMoBvQXizTQltZVaCAm6DjLIb4CnzsyzLlAI6w7Tdtk=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=qTFsA1FJEXaYPqlkj990TMTOt33FqosL/E1PcJ9PR6tx4ozyPtL+jB6U/M6Y4Zxdh O5Rb0DuUu7XOq/cJa0nZEqAiGJVOgKt4yGIOwFg1IXXfGKb2zwZvLz+H6QH5Bj+sug zXRpp+99KhmBv1wriBXHnSd+1JXO1WBovG4tBK6g= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726751AbgHUS2v (ORCPT ); Fri, 21 Aug 2020 14:28:51 -0400 Received: from mail.kernel.org ([198.145.29.99]:59442 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726636AbgHUS2U (ORCPT ); Fri, 21 Aug 2020 14:28:20 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 4D1EC23101; Fri, 21 Aug 2020 18:28:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034499; bh=lMoBvQXizTQltZVaCAm6DjLIb4CnzsyzLlAI6w7Tdtk=; h=From:To:Subject:Date:In-Reply-To:References:From; b=AIikmfjfq5tNKSUBihrKP14bMzumWqd4MYPm14tfU1tgt7kDrwyF3pgkBzF+7I0jz 8Cr3LBMSWzvDy4D2eIN6G/TCfFkK2drIF/4L64lgfJLd8QDKecxY8CLtAT7sgrpC0G A/6FQZ5pyc8tYYKFiHy8nm2f11n3dZE1pC+lfwhA= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 09/14] ceph: set S_ENCRYPTED bit if new inode has encryption.ctx xattr Date: Fri, 21 Aug 2020 14:28:08 -0400 Message-Id: <20200821182813.52570-10-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org This hack fixes a chicken-and-egg problem when fetching inodes from the server. Once we move to a dedicated field in the inode, then this should be able to go away. Signed-off-by: Jeff Layton --- fs/ceph/inode.c | 5 +++++ fs/ceph/super.h | 1 + fs/ceph/xattr.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 877bdda40db8..fe231d7bd892 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -18,6 +18,7 @@ #include "super.h" #include "mds_client.h" #include "cache.h" +#include "crypto.h" #include /* @@ -908,6 +909,10 @@ int ceph_fill_inode(struct inode *inode, struct page *locked_page, ceph_forget_all_cached_acls(inode); ceph_security_invalidate_secctx(inode); xattr_blob = NULL; + if ((inode->i_state & I_NEW) && + (DUMMY_ENCRYPTION_ENABLED(mdsc->fsc) || + ceph_inode_has_xattr(ci, CEPH_XATTR_NAME_ENCRYPTION_CONTEXT))) + inode_set_flags(inode, S_ENCRYPTED, S_ENCRYPTED); } /* finally update i_version */ diff --git a/fs/ceph/super.h b/fs/ceph/super.h index a481cacf775a..ea111c0eadba 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -983,6 +983,7 @@ extern ssize_t ceph_listxattr(struct dentry *, char *, size_t); extern struct ceph_buffer *__ceph_build_xattrs_blob(struct ceph_inode_info *ci); extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci); extern const struct xattr_handler *ceph_xattr_handlers[]; +bool ceph_inode_has_xattr(struct ceph_inode_info *ci, char *name); struct ceph_acl_sec_ctx { #ifdef CONFIG_CEPH_FS_POSIX_ACL diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 3a733ac33d9b..9dcb060cba9a 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1283,6 +1283,38 @@ void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx) ceph_pagelist_release(as_ctx->pagelist); } +/* Return true if inode's xattr blob has an xattr named "name" */ +bool ceph_inode_has_xattr(struct ceph_inode_info *ci, char *name) +{ + void *p, *end; + u32 numattr; + size_t namelen; + + lockdep_assert_held(&ci->i_ceph_lock); + + if (!ci->i_xattrs.blob || ci->i_xattrs.blob->vec.iov_len <= 4) + return false; + + namelen = strlen(name); + p = ci->i_xattrs.blob->vec.iov_base; + end = p + ci->i_xattrs.blob->vec.iov_len; + ceph_decode_32_safe(&p, end, numattr, bad); + + while (numattr--) { + u32 len; + + ceph_decode_32_safe(&p, end, len, bad); + ceph_decode_need(&p, end, len, bad); + if (len == namelen && !memcmp(p, name, len)) + return true; + p += len; + ceph_decode_32_safe(&p, end, len, bad); + ceph_decode_skip_n(&p, end, len, bad); + } +bad: + return false; +} + /* * List of handlers for synthetic system.* attributes. Other * attributes are handled directly. From patchwork Fri Aug 21 18:28:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730229 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5A3AF618 for ; Fri, 21 Aug 2020 18:28:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3BDA622EBF for ; Fri, 21 Aug 2020 18:28:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034531; bh=rVGNEkwJRFoafwsqs23yuHpm2uwAcP8LYOC9fqLA4cU=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=ejOc802WlV+CyrKfoM7QcNNy5k5C8kR0DvG12NlwIO5Y5XbG2UZ9vFta9rH40WnwR /aDwyDdqBa4Hm1jHM2wRt/McFIeHyMghx2wIs38CiK1wTd7zAK0T/qkQDwR3V6uI61 6OmQtQptfgAsJzVq/Sw8g3egjZBKSSi907LH1Pas= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726740AbgHUS2u (ORCPT ); Fri, 21 Aug 2020 14:28:50 -0400 Received: from mail.kernel.org ([198.145.29.99]:59448 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726638AbgHUS2U (ORCPT ); Fri, 21 Aug 2020 14:28:20 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id CB17523102; Fri, 21 Aug 2020 18:28:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034500; bh=rVGNEkwJRFoafwsqs23yuHpm2uwAcP8LYOC9fqLA4cU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=oWu9OLw4Sj5UT4K1cMqo52qkq/TbK4xlHih3qz1/FHE9bdRPMA/zw2Uk2o3npPo5E POoQH1ZhPhU/wBspXEzZX7oySqLYUeJmw3HMsT9KhHTwQdrPLef6pXSL25V3o3xnzw 2SnLfTsD89OPVQAjf9MeAvwjT1styRx8VVL7g7Uo= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 10/14] ceph: make ceph_msdc_build_path use ref-walk Date: Fri, 21 Aug 2020 14:28:09 -0400 Message-Id: <20200821182813.52570-11-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Encryption potentially requires allocation, at which point we'll need to be in a non-atomic context. Convert ceph_msdc_build_path to take dentry spinlocks and references instead of using rcu_read_lock to walk the path. This is slightly less efficient, and we may want to eventually allow using RCU when the leaf dentry isn't encrypted. Signed-off-by: Jeff Layton --- fs/ceph/mds_client.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 76d8d9495d1d..c4bfa383e8c4 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2326,7 +2326,8 @@ static inline u64 __get_oldest_tid(struct ceph_mds_client *mdsc) char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase, int stop_on_nosnap) { - struct dentry *temp; + struct dentry *cur; + struct inode *inode; char *path; int pos; unsigned seq; @@ -2343,34 +2344,35 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase, path[pos] = '\0'; seq = read_seqbegin(&rename_lock); - rcu_read_lock(); - temp = dentry; + cur = dget(dentry); for (;;) { - struct inode *inode; + struct dentry *temp; - spin_lock(&temp->d_lock); - inode = d_inode(temp); + spin_lock(&cur->d_lock); + inode = d_inode(cur); if (inode && ceph_snap(inode) == CEPH_SNAPDIR) { dout("build_path path+%d: %p SNAPDIR\n", - pos, temp); - } else if (stop_on_nosnap && inode && dentry != temp && + pos, cur); + } else if (stop_on_nosnap && inode && dentry != cur && ceph_snap(inode) == CEPH_NOSNAP) { - spin_unlock(&temp->d_lock); + spin_unlock(&cur->d_lock); pos++; /* get rid of any prepended '/' */ break; } else { - pos -= temp->d_name.len; + pos -= cur->d_name.len; if (pos < 0) { - spin_unlock(&temp->d_lock); + spin_unlock(&cur->d_lock); break; } - memcpy(path + pos, temp->d_name.name, temp->d_name.len); + memcpy(path + pos, cur->d_name.name, cur->d_name.len); } + temp = cur; + cur = dget(temp->d_parent); spin_unlock(&temp->d_lock); - temp = READ_ONCE(temp->d_parent); + dput(temp); /* Are we at the root? */ - if (IS_ROOT(temp)) + if (IS_ROOT(cur)) break; /* Are we out of buffer? */ @@ -2379,8 +2381,9 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase, path[pos] = '/'; } - base = ceph_ino(d_inode(temp)); - rcu_read_unlock(); + inode = d_inode(cur); + base = inode ? ceph_ino(inode) : 0; + dput(cur); if (read_seqretry(&rename_lock, seq)) goto retry; From patchwork Fri Aug 21 18:28:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730231 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D88951731 for ; Fri, 21 Aug 2020 18:28:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BC738230FF for ; Fri, 21 Aug 2020 18:28:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034531; bh=CAfhgqN/6g98bVKb1tCN2jUYbN58/s2E3Mac8EK4Irc=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=vsHyhAwUr41pOIGaMu5iwlQhL53UK9fiYdBdzlf6lNDVu2zEVyxeBEf3GaA+RDW0y zMt/F4oMbCo6pX6H/wPMcSNabR71cxK6N2n/Vu9SB7A31iDgF4Bqnl0vwiS7RXEPmy S7ijf5RrlJhbWIppYyV34PgdEJkGCSIakxe/UWgA= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726664AbgHUS2u (ORCPT ); Fri, 21 Aug 2020 14:28:50 -0400 Received: from mail.kernel.org ([198.145.29.99]:59394 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726641AbgHUS2U (ORCPT ); Fri, 21 Aug 2020 14:28:20 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 54A6623104; Fri, 21 Aug 2020 18:28:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034500; bh=CAfhgqN/6g98bVKb1tCN2jUYbN58/s2E3Mac8EK4Irc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ajCfk2Cx7i1rv6+yULm62zhhwTbQyL128CIl2/KFV6KyohFEZANdFkK9VJ+s0Rm4g vzU/7It9uk6NqSRT2qcQ/zYkdjXHgiQgG1gJIpwM6ahkvY0zl083+khgsDOKBFPjww 67/w6p4Oxqs2zsIfMxAb09cRM2VMK2/EOY90Sm7A= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 11/14] ceph: add encrypted fname handling to ceph_mdsc_build_path Date: Fri, 21 Aug 2020 14:28:10 -0400 Message-Id: <20200821182813.52570-12-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Allow ceph_mdsc_build_path to encrypt and base64 encode the filename when the parent is encrypted and we're sending the path to the MDS. Signed-off-by: Jeff Layton --- fs/ceph/mds_client.c | 51 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index c4bfa383e8c4..08e173b821b5 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "super.h" #include "mds_client.h" @@ -2323,8 +2324,7 @@ static inline u64 __get_oldest_tid(struct ceph_mds_client *mdsc) * Encode hidden .snap dirs as a double /, i.e. * foo/.snap/bar -> foo//bar */ -char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase, - int stop_on_nosnap) +char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase, int for_wire) { struct dentry *cur; struct inode *inode; @@ -2346,30 +2346,59 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase, seq = read_seqbegin(&rename_lock); cur = dget(dentry); for (;;) { - struct dentry *temp; + struct dentry *parent; spin_lock(&cur->d_lock); inode = d_inode(cur); + parent = cur->d_parent; if (inode && ceph_snap(inode) == CEPH_SNAPDIR) { dout("build_path path+%d: %p SNAPDIR\n", pos, cur); - } else if (stop_on_nosnap && inode && dentry != cur && - ceph_snap(inode) == CEPH_NOSNAP) { + dget(parent); + spin_unlock(&cur->d_lock); + } else if (for_wire && inode && dentry != cur && ceph_snap(inode) == CEPH_NOSNAP) { spin_unlock(&cur->d_lock); pos++; /* get rid of any prepended '/' */ break; - } else { + } else if (!for_wire || !IS_ENCRYPTED(d_inode(parent))) { pos -= cur->d_name.len; if (pos < 0) { spin_unlock(&cur->d_lock); break; } memcpy(path + pos, cur->d_name.name, cur->d_name.len); + dget(parent); + spin_unlock(&cur->d_lock); + } else { + int err; + struct fscrypt_name fname = { }; + int len; + char buf[BASE64_CHARS(NAME_MAX)]; + + dget(parent); + spin_unlock(&cur->d_lock); + + err = fscrypt_setup_filename(d_inode(parent), &cur->d_name, 1, &fname); + if (err) { + dput(parent); + dput(cur); + return ERR_PTR(err); + } + + /* base64 encode the encrypted name */ + len = base64_encode(fname.disk_name.name, fname.disk_name.len, buf); + pos -= len; + if (pos < 0) { + dput(parent); + fscrypt_free_filename(&fname); + break; + } + memcpy(path + pos, buf, len); + dout("non-ciphertext name = %.*s\n", len, buf); + fscrypt_free_filename(&fname); } - temp = cur; - cur = dget(temp->d_parent); - spin_unlock(&temp->d_lock); - dput(temp); + dput(cur); + cur = parent; /* Are we at the root? */ if (IS_ROOT(cur)) @@ -2414,7 +2443,7 @@ static int build_dentry_path(struct dentry *dentry, struct inode *dir, rcu_read_lock(); if (!dir) dir = d_inode_rcu(dentry->d_parent); - if (dir && parent_locked && ceph_snap(dir) == CEPH_NOSNAP) { + if (dir && parent_locked && ceph_snap(dir) == CEPH_NOSNAP && !IS_ENCRYPTED(dir)) { *pino = ceph_ino(dir); rcu_read_unlock(); *ppath = dentry->d_name.name; From patchwork Fri Aug 21 18:28:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730243 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 82266618 for ; Fri, 21 Aug 2020 18:29:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 64B1F230FF for ; Fri, 21 Aug 2020 18:29:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034552; bh=cjzcWCBqDYAC8jfa7JWsBDeyu4qvfdbuM7y+EFHiyZ4=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=rRbTrbXTgF1FsM8y4m5QfBM1uKLQJHXxm8NCo5YeCgq2GHdhs2hBJe7UxfqjEb+RH HoS8qc1+y+KRWiFkpGpLrz7DbhWd1zi8JWMrqHK3BTtMSpNu/38qgPwOO4vDb1OcS5 aDwqBC6F86Sm2qxNWAohPoyRf+eMT4KJMy9rAFm4= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726730AbgHUS2u (ORCPT ); Fri, 21 Aug 2020 14:28:50 -0400 Received: from mail.kernel.org ([198.145.29.99]:59468 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726646AbgHUS2V (ORCPT ); Fri, 21 Aug 2020 14:28:21 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D25E023108; Fri, 21 Aug 2020 18:28:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034501; bh=cjzcWCBqDYAC8jfa7JWsBDeyu4qvfdbuM7y+EFHiyZ4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=dse5czlsz8bEjgZwlvTylPNHXJaYQP68GJ3RdAwHGUjSBaFGfzEY6wdo/A5EXq6fd kp7x3YDPOTwIzhRixPbP8MTKYC9k7KDBOfkgn/BYCNp2euBx5Qc0PAivcgPdYG/aGs KnmkcbhfnWCJA4MDDz2ZfuqbxcoFQl6gKtxqUbEg= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 12/14] ceph: make d_revalidate call fscrypt revalidator for encrypted dentries Date: Fri, 21 Aug 2020 14:28:11 -0400 Message-Id: <20200821182813.52570-13-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org If we have an encrypted dentry, then we need to test whether a new key might have been established or removed. Do that before we test anything else about the dentry. Signed-off-by: Jeff Layton --- fs/ceph/dir.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 2e7f2bfa2c12..d2104c115868 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -1701,6 +1701,12 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) dout("d_revalidate %p '%pd' inode %p offset 0x%llx\n", dentry, dentry, inode, ceph_dentry(dentry)->offset); + if (IS_ENCRYPTED(dir)) { + valid = fscrypt_d_revalidate(dentry, flags); + if (valid <= 0) + return valid; + } + mdsc = ceph_sb_to_client(dir->i_sb)->mdsc; /* always trust cached snapped dentries, snapdir dentry */ From patchwork Fri Aug 21 18:28:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730219 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BBEA01731 for ; Fri, 21 Aug 2020 18:28:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9967722EBF for ; Fri, 21 Aug 2020 18:28:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034518; bh=Q+MJnbA9qqdWu85d9FD7xdHXi2VA6CG1F408a69CUfQ=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=mZUPuBMff6cPWMThU+gT1c+Rncda0SiWhFBo0/nfBuXZi5koZe0iMFu+GSTrSA1Qe CGUTHnVQ0aXpYlumNA/4APvWrNh2kSJewdcLawXYkFCMznx1JqkZYre5FpJaMwdbB0 SXKkftTy0qSVaUHTOAz9qRvgvs4GUs1uvBqcqW3k= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726541AbgHUS2i (ORCPT ); Fri, 21 Aug 2020 14:28:38 -0400 Received: from mail.kernel.org ([198.145.29.99]:59474 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726661AbgHUS2W (ORCPT ); Fri, 21 Aug 2020 14:28:22 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 5C9DD22EBF; Fri, 21 Aug 2020 18:28:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034501; bh=Q+MJnbA9qqdWu85d9FD7xdHXi2VA6CG1F408a69CUfQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=FPpcQk3sarokgbIdsniTP2lSBDqclihXoMgY/r2pv7tIqW20A7jq2Oz/DGg6iiV/y rJTGrLI5gLzX9YWZqu2DfRPhXe3wkfp1+MvIkrBhfqlPobk5i8tDxDVjvTIqI06RIW WeZwld+2fscSlpNBambw3PaTQKs6lillHmNs4B04= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 13/14] ceph: add support to readdir for encrypted filenames Date: Fri, 21 Aug 2020 14:28:12 -0400 Message-Id: <20200821182813.52570-14-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Add helper functions for buffer management and for decrypting filenames returned by the MDS. Wire those into the readdir codepaths. Signed-off-by: Jeff Layton --- fs/ceph/crypto.c | 47 ++++++++++++++++++++++++++++++ fs/ceph/crypto.h | 49 ++++++++++++++++++++++++++++++- fs/ceph/dir.c | 76 ++++++++++++++++++++++++++++++++++++++++-------- fs/ceph/inode.c | 30 +++++++++++++++++-- 4 files changed, 186 insertions(+), 16 deletions(-) diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c index 0e57497c2e55..521163ef3653 100644 --- a/fs/ceph/crypto.c +++ b/fs/ceph/crypto.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "super.h" #include "crypto.h" @@ -122,3 +123,49 @@ int ceph_fscrypt_new_context(struct inode *parent, struct ceph_acl_sec_ctx *as) ceph_pagelist_release(pagelist); return ret; } + +int ceph_fname_to_usr(struct inode *parent, char *name, u32 len, + struct fscrypt_str *tname, struct fscrypt_str *oname) +{ + int ret, declen; + u32 save_len; + struct fscrypt_str myname = FSTR_INIT(NULL, 0); + + if (!IS_ENCRYPTED(parent)) { + oname->name = name; + oname->len = len; + return 0; + } + + ret = fscrypt_get_encryption_info(parent); + if (ret) + return ret; + + if (tname) { + save_len = tname->len; + } else { + int err; + + save_len = 0; + err = fscrypt_fname_alloc_buffer(NAME_MAX, &myname); + if (err) + return err; + tname = &myname; + } + + declen = base64_decode(name, len, tname->name); + if (declen < 0 || declen > NAME_MAX) { + ret = -EIO; + goto out; + } + + tname->len = declen; + + ret = fscrypt_fname_disk_to_usr(parent, 0, 0, tname, oname); + + if (save_len) + tname->len = save_len; +out: + fscrypt_fname_free_buffer(&myname); + return ret; +} diff --git a/fs/ceph/crypto.h b/fs/ceph/crypto.h index e7d00831ef36..3ca4f469619a 100644 --- a/fs/ceph/crypto.h +++ b/fs/ceph/crypto.h @@ -6,6 +6,8 @@ #ifndef _CEPH_CRYPTO_H #define _CEPH_CRYPTO_H +#include + #ifdef CONFIG_FS_ENCRYPTION #define CEPH_XATTR_NAME_ENCRYPTION_CONTEXT "encryption.ctx" @@ -15,6 +17,29 @@ int ceph_fscrypt_set_ops(struct super_block *sb); int ceph_fscrypt_new_context(struct inode *parent, struct ceph_acl_sec_ctx *as); +static inline int ceph_fname_alloc_buffer(struct inode *parent, struct fscrypt_str *fname) +{ + if (!IS_ENCRYPTED(parent)) + return 0; + return fscrypt_fname_alloc_buffer(NAME_MAX, fname); +} + +static inline void ceph_fname_free_buffer(struct inode *parent, struct fscrypt_str *fname) +{ + if (IS_ENCRYPTED(parent)) + fscrypt_fname_free_buffer(fname); +} + +static inline int ceph_get_encryption_info(struct inode *inode) +{ + if (!IS_ENCRYPTED(inode)) + return 0; + return fscrypt_get_encryption_info(inode); +} + +int ceph_fname_to_usr(struct inode *parent, char *name, u32 len, + struct fscrypt_str *tname, struct fscrypt_str *oname); + #else /* CONFIG_FS_ENCRYPTION */ #define DUMMY_ENCRYPTION_ENABLED(fsc) (0) @@ -24,8 +49,30 @@ static inline int ceph_fscrypt_set_ops(struct super_block *sb) return 0; } -static int ceph_fscrypt_new_context(struct inode *parent, struct ceph_acl_sec_ctx *as) +static inline int ceph_fscrypt_new_context(struct inode *parent, struct ceph_acl_sec_ctx *as) +{ + return 0; +} + +static inline int ceph_fname_alloc_buffer(struct inode *parent, struct fscrypt_str *fname) +{ + return 0; +} + +static inline void ceph_fname_free_buffer(struct inode *parent, struct fscrypt_str *fname) +{ +} + +static inline int ceph_get_encryption_info(struct inode *inode) +{ + return 0; +} + +static inline int ceph_fname_to_usr(struct inode *inode, char *name, u32 len, + struct fscrypt_str *tname, struct fscrypt_str *oname) { + oname->name = dname; + oname->len = dlen; return 0; } diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index d2104c115868..858285d1cdfe 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "super.h" #include "mds_client.h" @@ -169,6 +170,27 @@ __dcache_find_get_entry(struct dentry *parent, u64 idx, return dentry ? : ERR_PTR(-EAGAIN); } +static bool fscrypt_key_status_change(struct dentry *dentry) +{ + struct inode *dir; + bool encrypted_name, have_key; + + lockdep_assert_held(&dentry->d_lock); + + dir = d_inode(dentry->d_parent); + if (!IS_ENCRYPTED(dir)) + return false; + + encrypted_name = dentry->d_flags & DCACHE_ENCRYPTED_NAME; + have_key = fscrypt_has_encryption_key(dir); + + if (encrypted_name == have_key) + ceph_dir_clear_complete(dir); + + dout("%s encrypted_name=%d have_key=%d\n", __func__, encrypted_name, have_key); + return encrypted_name == have_key; +} + /* * When possible, we try to satisfy a readdir by peeking at the * dcache. We make this work by carefully ordering dentries on @@ -239,11 +261,11 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx, goto out; } - spin_lock(&dentry->d_lock); di = ceph_dentry(dentry); if (d_unhashed(dentry) || d_really_is_negative(dentry) || - di->lease_shared_gen != shared_gen) { + di->lease_shared_gen != shared_gen || + fscrypt_key_status_change(dentry)) { spin_unlock(&dentry->d_lock); dput(dentry); err = -EAGAIN; @@ -315,6 +337,8 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) int err; unsigned frag = -1; struct ceph_mds_reply_info_parsed *rinfo; + struct fscrypt_str tname = FSTR_INIT(NULL, 0); + struct fscrypt_str oname = FSTR_INIT(NULL, 0); dout("readdir %p file %p pos %llx\n", inode, file, ctx->pos); if (dfi->file_info.flags & CEPH_F_ATEND) @@ -342,6 +366,10 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) ctx->pos = 2; } + err = ceph_get_encryption_info(inode); + if (err) + goto out; + spin_lock(&ci->i_ceph_lock); /* request Fx cap. if have Fx, we don't need to release Fs cap * for later create/unlink. */ @@ -362,6 +390,14 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) spin_unlock(&ci->i_ceph_lock); } + err = ceph_fname_alloc_buffer(inode, &tname); + if (err < 0) + goto out; + + err = ceph_fname_alloc_buffer(inode, &oname); + if (err < 0) + goto out; + /* proceed with a normal readdir */ more: /* do we have the correct frag content buffered? */ @@ -389,12 +425,14 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) dout("readdir fetching %llx.%llx frag %x offset '%s'\n", ceph_vinop(inode), frag, dfi->last_name); req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); - if (IS_ERR(req)) - return PTR_ERR(req); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto out; + } err = ceph_alloc_readdir_reply_buffer(req, inode); if (err) { ceph_mdsc_put_request(req); - return err; + goto out; } /* hints to request -> mds selection code */ req->r_direct_mode = USE_AUTH_MDS; @@ -407,7 +445,8 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) req->r_path2 = kstrdup(dfi->last_name, GFP_KERNEL); if (!req->r_path2) { ceph_mdsc_put_request(req); - return -ENOMEM; + err = -ENOMEM; + goto out; } } else if (is_hash_order(ctx->pos)) { req->r_args.readdir.offset_hash = @@ -428,7 +467,7 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) err = ceph_mdsc_do_request(mdsc, NULL, req); if (err < 0) { ceph_mdsc_put_request(req); - return err; + goto out; } dout("readdir got and parsed readdir result=%d on " "frag %x, end=%d, complete=%d, hash_order=%d\n", @@ -481,7 +520,7 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) err = note_last_dentry(dfi, rde->name, rde->name_len, next_offset); if (err) - return err; + goto out; } else if (req->r_reply_info.dir_end) { dfi->next_offset = 2; /* keep last name */ @@ -509,8 +548,10 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) } for (; i < rinfo->dir_nr; i++) { struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i; + u32 olen = oname.len; BUG_ON(rde->offset < ctx->pos); + BUG_ON(!rde->inode.in); ctx->pos = rde->offset; dout("readdir (%d/%d) -> %llx '%.*s' %p\n", @@ -519,12 +560,20 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) BUG_ON(!rde->inode.in); - if (!dir_emit(ctx, rde->name, rde->name_len, + err = ceph_fname_to_usr(inode, rde->name, rde->name_len, &tname, &oname); + if (err) + goto out; + + if (!dir_emit(ctx, oname.name, oname.len, ceph_present_ino(inode->i_sb, le64_to_cpu(rde->inode.in->ino)), le32_to_cpu(rde->inode.in->mode) >> 12)) { dout("filldir stopping us...\n"); - return 0; + err = 0; + goto out; } + + /* Reset the lengths to their original allocated vals */ + oname.len = olen; ctx->pos++; } @@ -579,9 +628,12 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) dfi->dir_ordered_count); spin_unlock(&ci->i_ceph_lock); } - + err = 0; dout("readdir %p file %p done.\n", inode, file); - return 0; +out: + ceph_fname_free_buffer(inode, &tname); + ceph_fname_free_buffer(inode, &oname); + return err; } static void reset_readdir(struct ceph_dir_file_info *dfi) diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index fe231d7bd892..007d01b7a2ba 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1593,7 +1593,8 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, struct ceph_mds_session *session) { struct dentry *parent = req->r_dentry; - struct ceph_inode_info *ci = ceph_inode(d_inode(parent)); + struct inode *inode = d_inode(parent); + struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info; struct qstr dname; struct dentry *dn; @@ -1604,6 +1605,8 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, u32 last_hash = 0; u32 fpos_offset; struct ceph_readdir_cache_control cache_ctl = {}; + struct fscrypt_str tname = FSTR_INIT(NULL, 0); + struct fscrypt_str oname = FSTR_INIT(NULL, 0); if (test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags)) return readdir_prepopulate_inodes_only(req, session); @@ -1655,14 +1658,28 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, cache_ctl.index = req->r_readdir_cache_idx; fpos_offset = req->r_readdir_offset; + err = ceph_fname_alloc_buffer(inode, &tname); + if (err < 0) + goto out; + + err = ceph_fname_alloc_buffer(inode, &oname); + if (err < 0) + goto out; + /* FIXME: release caps/leases if error occurs */ for (i = 0; i < rinfo->dir_nr; i++) { struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i; struct ceph_vino tvino; + u32 olen = oname.len; - dname.name = rde->name; - dname.len = rde->name_len; + err = ceph_fname_to_usr(inode, rde->name, rde->name_len, &tname, &oname); + if (err) + goto out; + + dname.name = oname.name; + dname.len = oname.len; dname.hash = full_name_hash(parent, dname.name, dname.len); + oname.len = olen; tvino.ino = le64_to_cpu(rde->inode.in->ino); tvino.snap = le64_to_cpu(rde->inode.in->snapid); @@ -1693,6 +1710,11 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, err = -ENOMEM; goto out; } + if (IS_ENCRYPTED(inode) && !fscrypt_has_encryption_key(inode)) { + spin_lock(&dn->d_lock); + dn->d_flags |= DCACHE_ENCRYPTED_NAME; + spin_unlock(&dn->d_lock); + } } else if (d_really_is_positive(dn) && (ceph_ino(d_inode(dn)) != tvino.ino || ceph_snap(d_inode(dn)) != tvino.snap)) { @@ -1783,6 +1805,8 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, req->r_readdir_cache_idx = cache_ctl.index; } ceph_readdir_cache_release(&cache_ctl); + ceph_fname_free_buffer(inode, &tname); + ceph_fname_free_buffer(inode, &oname); dout("readdir_prepopulate done\n"); return err; } From patchwork Fri Aug 21 18:28:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 11730245 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6C87E618 for ; Fri, 21 Aug 2020 18:29:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4BD2523105 for ; Fri, 21 Aug 2020 18:29:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034557; bh=9/0cF3waO5SHLTvMbsBohWY6v0JOypTyA4ajf/JdgJg=; h=From:To:Subject:Date:In-Reply-To:References:List-ID:From; b=OfEMgm/KaOGrgpNUcuffM2upTxqOB5YE75rXyBuDPQrG7Xz/vtkfO1Rx5FyUfi1Oz 5Wtg/4UH5xhH5IwSByIYbB4QWY67vKcYZOtLTNsnNEXcDnG0D6WYLJcod52gbyxun3 jr+PHpZFRh2O1oe3FjRi/XLU1d8OYTNyFja6jb/w= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726661AbgHUS2t (ORCPT ); Fri, 21 Aug 2020 14:28:49 -0400 Received: from mail.kernel.org ([198.145.29.99]:59388 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726664AbgHUS2W (ORCPT ); Fri, 21 Aug 2020 14:28:22 -0400 Received: from tleilax.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id DB0C623105; Fri, 21 Aug 2020 18:28:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598034502; bh=9/0cF3waO5SHLTvMbsBohWY6v0JOypTyA4ajf/JdgJg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=IjceX9vX0/fsLqLeelFXlLDVjFMCtoF9YEA9MA5rOJAx8I0y+duIsdsIo7TajcaQA wdd7J16wW0cdMpx9IY1dn0hkXFob7i7KGNxLpeu0Q+A4QlumvNzznoy6OvvD2BAJSe AZyXZaaRFyToCGYU3W0zyv3xt9AiA2S2QWso4fCI= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 14/14] ceph: add fscrypt support to ceph_fill_trace Date: Fri, 21 Aug 2020 14:28:13 -0400 Message-Id: <20200821182813.52570-15-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200821182813.52570-1-jlayton@kernel.org> References: <20200821182813.52570-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org When we get a dentry in a trace, decrypt the name so we can properly instantiate the dentry. Signed-off-by: Jeff Layton --- fs/ceph/inode.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 007d01b7a2ba..945c25e7ed20 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1273,6 +1273,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req) !test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags)) { struct qstr dname; struct dentry *dn, *parent; + struct fscrypt_str oname = FSTR_INIT(NULL, 0); BUG_ON(!rinfo->head->is_target); BUG_ON(req->r_dentry); @@ -1280,8 +1281,20 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req) parent = d_find_any_alias(dir); BUG_ON(!parent); - dname.name = rinfo->dname; - dname.len = rinfo->dname_len; + err = ceph_fname_alloc_buffer(dir, &oname); + if (err < 0) { + dput(parent); + goto done; + } + + err = ceph_fname_to_usr(dir, rinfo->dname, rinfo->dname_len, NULL, &oname); + if (err < 0) { + dput(parent); + ceph_fname_free_buffer(dir, &oname); + goto done; + } + dname.name = oname.name; + dname.len = oname.len; dname.hash = full_name_hash(parent, dname.name, dname.len); tvino.ino = le64_to_cpu(rinfo->targeti.in->ino); tvino.snap = le64_to_cpu(rinfo->targeti.in->snapid); @@ -1296,9 +1309,15 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req) dname.len, dname.name, dn); if (!dn) { dput(parent); + ceph_fname_free_buffer(dir, &oname); err = -ENOMEM; goto done; } + if (IS_ENCRYPTED(dir) && !fscrypt_has_encryption_key(dir)) { + spin_lock(&dn->d_lock); + dn->d_flags |= DCACHE_ENCRYPTED_NAME; + spin_unlock(&dn->d_lock); + } err = 0; } else if (d_really_is_positive(dn) && (ceph_ino(d_inode(dn)) != tvino.ino || @@ -1310,6 +1329,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req) dput(dn); goto retry_lookup; } + ceph_fname_free_buffer(dir, &oname); req->r_dentry = dn; dput(parent);