From patchwork Mon Sep 14 19:16:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 292032 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA207C2BC11 for ; Mon, 14 Sep 2020 19:19:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 77BBF208E4 for ; Mon, 14 Sep 2020 19:19:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111153; bh=gM6sCpb5yU4vQNbnGfPapdqAJL/5qq1Q4OJTc+Ei+eM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=kSjRqyOt/bpS2N1gfXU63bPDZi247Y5vYCETrb32fKMGuFHZ71mPRDhA/KE5a5cIx vGDMrCqPZZLU0n/nzjfFxI9geKIR4R85u1dvURBQvt0a9EYap4EK62THoa0NPBBEfD VZsu/wixJUfmD0EYg+rjP9RH+k3bimA/uNxxXzx4= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726086AbgINTTM (ORCPT ); Mon, 14 Sep 2020 15:19:12 -0400 Received: from mail.kernel.org ([198.145.29.99]:38950 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725964AbgINTRN (ORCPT ); Mon, 14 Sep 2020 15:17:13 -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 26FAC21974; Mon, 14 Sep 2020 19:17:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111032; bh=gM6sCpb5yU4vQNbnGfPapdqAJL/5qq1Q4OJTc+Ei+eM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EZ5oiRLwCH3xwkNGVtwTv6eCr+aNRI14JF44rWDpGU2I4q05noFrDS8cR4IGkTq1f qLvYJdpM7rEi7wnBBsXCaYdpllWmq1ew67s9LJ4kTd6cItjDGjhSCl8sm/rJUCYFgs Q/vmEtBsPfXli40LcCllmeTns7GTpC81QRb2e+cQ= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Subject: [RFC PATCH v3 03/16] fscrypt: export fscrypt_d_revalidate Date: Mon, 14 Sep 2020 15:16:54 -0400 Message-Id: <20200914191707.380444-4-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200914191707.380444-1-jlayton@kernel.org> References: <20200914191707.380444-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@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 a1cb6c2c50c4..0d41eb4a5493 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -578,7 +578,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; @@ -617,6 +617,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 95dddba3ed00..b547e1aabb00 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -204,6 +204,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 Mon Sep 14 19:16:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 292038 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96AAEC43461 for ; Mon, 14 Sep 2020 19:17:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5C6CE208E4 for ; Mon, 14 Sep 2020 19:17:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111064; bh=oKXMY3huJ4gH9ve2CTeuG+2SJx1r8vcdkKAnbDC++Mw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=Xz2pyctQIHyj3xdGmJQmjqYTPUTvHAfb3YV1eif5nxJUebyb1kNY2p79Ajlgk7fuG FxrI2tktF41O4gAlJjaH3gvqPAievEsUrZtDYYH2PqBwG6/JAssG18OLCSIaR1tmZw M8RNjfHkIE6IgIoCk8Fo+vcpFdpgn8nD67L1gbKs= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726053AbgINTRm (ORCPT ); Mon, 14 Sep 2020 15:17:42 -0400 Received: from mail.kernel.org ([198.145.29.99]:38960 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725984AbgINTRN (ORCPT ); Mon, 14 Sep 2020 15:17:13 -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 B263C21BE5; Mon, 14 Sep 2020 19:17:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111033; bh=oKXMY3huJ4gH9ve2CTeuG+2SJx1r8vcdkKAnbDC++Mw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pm/zGL7KXx+QZR4JPxbkkOgVJ9hpR5kYmu9R27peQQzPYlxy/HLskYeNVFwO4bDTD ANY5nJ1w+5+uAFFqizipW4UC31Z0bevrmaGBX8egjHUMN9afzQB++1InqVhHASfUNk tvpUsi7x4u9PYPVbWYYQN6K9NpACL34xpnl1qiZU= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Subject: [RFC PATCH v3 04/16] fscrypt: add fscrypt_context_for_new_inode Date: Mon, 14 Sep 2020 15:16:55 -0400 Message-Id: <20200914191707.380444-5-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200914191707.380444-1-jlayton@kernel.org> References: <20200914191707.380444-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org CephFS will need to be able to generate a context for a new "prepared" inode. Add a new routine for getting the context out of an in-core inode. Signed-off-by: Jeff Layton --- fs/crypto/policy.c | 35 ++++++++++++++++++++++++++++------- include/linux/fscrypt.h | 1 + 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index 97cf07543651..0888f950367b 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -655,6 +655,31 @@ const union fscrypt_policy *fscrypt_policy_to_inherit(struct inode *dir) return fscrypt_get_dummy_policy(dir->i_sb); } +/** + * fscrypt_context_for_new_inode() - create an encryption context for a new inode + * @ctx: where context should be written + * @inode: inode from which to fetch policy and nonce + * + * Given an in-core "prepared" (via fscrypt_prepare_new_inode) inode, + * generate a new context and write it to ctx. ctx _must_ be at least + * FSCRYPT_SET_CONTEXT_MAX_SIZE bytes. + * + * Returns size of the resulting context or a negative error code. + */ +int fscrypt_context_for_new_inode(void *ctx, struct inode *inode) +{ + struct fscrypt_info *ci = inode->i_crypt_info; + + BUILD_BUG_ON(sizeof(union fscrypt_context) != FSCRYPT_SET_CONTEXT_MAX_SIZE); + + /* fscrypt_prepare_new_inode() should have set up the key already. */ + if (WARN_ON_ONCE(!ci)) + return -ENOKEY; + + return fscrypt_new_context(ctx, &ci->ci_policy, ci->ci_nonce); +} +EXPORT_SYMBOL_GPL(fscrypt_context_for_new_inode); + /** * fscrypt_set_context() - Set the fscrypt context of a new inode * @inode: a new inode @@ -671,12 +696,9 @@ int fscrypt_set_context(struct inode *inode, void *fs_data) union fscrypt_context ctx; int ctxsize; - /* fscrypt_prepare_new_inode() should have set up the key already. */ - if (WARN_ON_ONCE(!ci)) - return -ENOKEY; - - BUILD_BUG_ON(sizeof(ctx) != FSCRYPT_SET_CONTEXT_MAX_SIZE); - ctxsize = fscrypt_new_context(&ctx, &ci->ci_policy, ci->ci_nonce); + ctxsize = fscrypt_context_for_new_inode(&ctx, inode); + if (ctxsize < 0) + return ctxsize; /* * This may be the first time the inode number is available, so do any @@ -689,7 +711,6 @@ int fscrypt_set_context(struct inode *inode, void *fs_data) fscrypt_hash_inode_number(ci, mk); } - return inode->i_sb->s_cop->set_context(inode, &ctx, ctxsize, fs_data); } EXPORT_SYMBOL_GPL(fscrypt_set_context); diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index b547e1aabb00..a57d2a9869eb 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -148,6 +148,7 @@ 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_set_context(struct inode *inode, void *fs_data); +int fscrypt_context_for_new_inode(void *ctx, struct inode *inode); struct fscrypt_dummy_policy { const union fscrypt_policy *policy; From patchwork Mon Sep 14 19:16:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 292037 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5F5BAC433E2 for ; Mon, 14 Sep 2020 19:17:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 176262193E for ; Mon, 14 Sep 2020 19:17:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111072; bh=HgVwdbGtocve/7WmBJzWMhD1oA0sq+cEIsf3lamsiHw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=lAqMVM8KBPT9znlGIBNGutR2Y57LgI2djO5V59aScyZOXHa9/vtfet3hlp2iQSnCP joxtNbKXfaLvnQcAv3/UjURGwBG3Q+elggBfifZrtK8QhEY29DsMSM8lmBldA4RKm/ iAKZVUITgM+N5a7ZGjUGZ8Z8QW3qNv4mpMOag4Zo= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726059AbgINTRt (ORCPT ); Mon, 14 Sep 2020 15:17:49 -0400 Received: from mail.kernel.org ([198.145.29.99]:38984 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725987AbgINTRS (ORCPT ); Mon, 14 Sep 2020 15:17: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 DC69F21D41; Mon, 14 Sep 2020 19:17:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111034; bh=HgVwdbGtocve/7WmBJzWMhD1oA0sq+cEIsf3lamsiHw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iShMjHq/m2XVFCwRgXul5Vl6QG6cRqqdt4BM6WFFwuNJtqByPZomO7pY3EnZo3UYU Al9a+TPl/zF5/69EkNdBwmD4e2ZwoyWPBaVtGmoJdhT8bBlHIhe2VSxBIBBABytpIS 4cAdVjlarlvtiejHhBFOvC3/dNSF1aKNqPh2ZXB4= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Subject: [RFC PATCH v3 06/16] ceph: add fscrypt ioctls Date: Mon, 14 Sep 2020 15:16:57 -0400 Message-Id: <20200914191707.380444-7-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200914191707.380444-1-jlayton@kernel.org> References: <20200914191707.380444-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org Boilerplate ioctls for controlling encryption. Signed-off-by: Jeff Layton --- fs/ceph/ioctl.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index 6e061bf62ad4..381e44b2d60a 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,30 @@ long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case CEPH_IOC_SYNCIO: return ceph_ioctl_syncio(file); + + 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); } return -ENOTTY; From patchwork Mon Sep 14 19:16:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 292036 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7944C433E2 for ; Mon, 14 Sep 2020 19:18:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9377E208E4 for ; Mon, 14 Sep 2020 19:18:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111098; bh=9GT8v41aJayrEVimcBe7OYnETYfPUvltP8JF0Wcztbc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=LeDpM4zkZK5JS1rKCQg0FK2BJseic3aqiegWJN7LVghuw8CN7ySi8OQHE7jgpZv5B NVEBr3X8HEidmCNEPmTGXrgVS8XYm4wlzlpmol6+cZOoR9PurZ856j7kwbfkHmxj4G PM3+fEV+0BQoIQlwnYGU35la8FyuV5lOdKLWGMDI= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726089AbgINTSD (ORCPT ); Mon, 14 Sep 2020 15:18:03 -0400 Received: from mail.kernel.org ([198.145.29.99]:39008 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726007AbgINTRW (ORCPT ); Mon, 14 Sep 2020 15:17: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 0F44B21D7E; Mon, 14 Sep 2020 19:17:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111035; bh=9GT8v41aJayrEVimcBe7OYnETYfPUvltP8JF0Wcztbc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kz/sz71yEG2XXd9JWMY1OckjLJkgJq1TjENoomL9OJVefxnYOFRxrZtlvCfPArdjR kwuYkTQgjld12qRvcagNtyS0ndHH2ni32sJY93urAxENXDBjNy04eWRiUONjQT33YH T/7xxhcJdlIhOuoXVW5XSjOAVrzzPJqOLMXGIHzI= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Subject: [RFC PATCH v3 08/16] ceph: implement -o test_dummy_encryption mount option Date: Mon, 14 Sep 2020 15:16:59 -0400 Message-Id: <20200914191707.380444-9-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200914191707.380444-1-jlayton@kernel.org> References: <20200914191707.380444-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org Signed-off-by: Jeff Layton --- fs/ceph/crypto.c | 7 ++--- fs/ceph/super.c | 74 +++++++++++++++++++++++++++++++++++++++++++----- fs/ceph/super.h | 7 ++++- 3 files changed, 76 insertions(+), 12 deletions(-) diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c index 74f07d44dbe9..879d9a0d3751 100644 --- a/fs/ceph/crypto.c +++ b/fs/ceph/crypto.c @@ -29,16 +29,15 @@ static bool ceph_crypt_empty_dir(struct inode *inode) return ci->i_rsubdirs + ci->i_rfiles == 1; } -static const union fscrypt_context * -ceph_get_dummy_context(struct super_block *sb) +static const union fscrypt_policy *ceph_get_dummy_policy(struct super_block *sb) { - return ceph_sb_to_client(sb)->dummy_enc_ctx.ctx; + return ceph_sb_to_client(sb)->dummy_enc_policy.policy; } static struct fscrypt_operations ceph_fscrypt_ops = { .get_context = ceph_crypt_get_context, .set_context = ceph_crypt_set_context, - .get_dummy_context = ceph_get_dummy_context, + .get_dummy_policy = ceph_get_dummy_policy, .empty_dir = ceph_crypt_empty_dir, .max_namelen = NAME_MAX, }; diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 055180218224..eefdea360c50 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -45,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_policy(&fsc->dummy_enc_policy); ceph_mdsc_close_sessions(fsc->mdsc); } @@ -160,6 +161,7 @@ enum { Opt_quotadf, Opt_copyfrom, Opt_wsync, + Opt_test_dummy_encryption, }; enum ceph_recover_session_mode { @@ -198,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 ("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), {} @@ -456,6 +460,16 @@ 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); +#ifdef CONFIG_FS_ENCRYPTION + fsopt->test_dummy_encryption = param->string; + param->string = NULL; + fsopt->flags |= CEPH_MOUNT_OPT_TEST_DUMMY_ENC; +#else + warnfc(fc, "FS encryption not supported: test_dummy_encryption mount option ignored"); +#endif + break; default: BUG(); } @@ -475,6 +489,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); } @@ -582,6 +597,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) @@ -964,6 +981,43 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc, return ERR_PTR(err); } +#ifdef CONFIG_FS_ENCRYPTION +static int ceph_set_test_dummy_encryption(struct super_block *sb, struct fs_context *fc, + struct ceph_mount_options *fsopt) +{ + struct ceph_fs_client *fsc = sb->s_fs_info; + + if (fsopt->flags & CEPH_MOUNT_OPT_TEST_DUMMY_ENC) { + substring_t arg = { }; + + /* + * No changing encryption context on remount. Note that + * fscrypt_set_test_dummy_encryption will validate the version + * string passed in (if any). + */ + if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE && !fsc->dummy_enc_policy.policy) + return -EEXIST; + + /* 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_policy); + } else { + if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE && fsc->dummy_enc_policy.policy) + return -EEXIST; + } + return 0; +} +#else +static inline int ceph_set_test_dummy_encryption(struct super_block *sb, struct fs_context *fc, + struct ceph_mount_options *fsopt) +{ + return 0; +} +#endif + static int ceph_set_super(struct super_block *s, struct fs_context *fc) { struct ceph_fs_client *fsc = s->s_fs_info; @@ -985,12 +1039,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; + ceph_fscrypt_set_ops(s); - ret = set_anon_super_fc(s, fc); - if (ret != 0) + ret = ceph_set_test_dummy_encryption(s, fc, fsc->mount_options); + if (!ret) + ret = set_anon_super_fc(s, fc); + if (ret) fsc->sb = NULL; return ret; } @@ -1136,16 +1190,22 @@ static void ceph_free_fc(struct fs_context *fc) static int ceph_reconfigure_fc(struct fs_context *fc) { + int err; struct ceph_parse_opts_ctx *pctx = fc->fs_private; struct ceph_mount_options *fsopt = pctx->opts; - struct ceph_fs_client *fsc = ceph_sb_to_client(fc->root->d_sb); + struct super_block *sb = fc->root->d_sb; + struct ceph_fs_client *fsc = ceph_sb_to_client(sb); if (fsopt->flags & CEPH_MOUNT_OPT_ASYNC_DIROPS) ceph_set_mount_opt(fsc, ASYNC_DIROPS); else ceph_clear_mount_opt(fsc, ASYNC_DIROPS); - sync_filesystem(fc->root->d_sb); + err = ceph_set_test_dummy_encryption(sb, fc, fsopt); + if (err) + return err; + + sync_filesystem(sb); return 0; } diff --git a/fs/ceph/super.h b/fs/ceph/super.h index cc39cc36de77..11032b30a14f 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -44,6 +45,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 +98,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 +138,11 @@ struct ceph_fs_client { #ifdef CONFIG_CEPH_FSCACHE struct fscache_cookie *fscache; #endif +#ifdef CONFIG_FS_ENCRYPTION + struct fscrypt_dummy_policy dummy_enc_policy; +#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 Mon Sep 14 19:17: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: 292035 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A41B7C2BBD1 for ; Mon, 14 Sep 2020 19:18:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 664D9217BA for ; Mon, 14 Sep 2020 19:18:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111100; bh=XBuKIJKYWo4X96EaNBsjlN57O/qWQZFBBji2cS8s4nA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=mtP2rLxQXBX50yW4Qkjl2nbIbvv9SeEORI5IFDbXG19XSq2pgLNIISN3L8szFa7/p habUG5LE6HpimFTeaR97++Dosb90VdzUN2JqvdEjysoXELVOCziCb7nLkiXnNwrzS9 32bHizlHdQG/aCUCMsOEuOErtjTLeH/9pwOZN/Bc= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726046AbgINTSR (ORCPT ); Mon, 14 Sep 2020 15:18:17 -0400 Received: from mail.kernel.org ([198.145.29.99]:39016 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726019AbgINTRW (ORCPT ); Mon, 14 Sep 2020 15:17: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 55756221E3; Mon, 14 Sep 2020 19:17:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111037; bh=XBuKIJKYWo4X96EaNBsjlN57O/qWQZFBBji2cS8s4nA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r3OAC3hSRtQhtrlGACMNL0A9TwZwl0LY8P48rqRMzEhjjvgvGfAOght8q7n+8WV87 h9K8Nyk2ahOhZUuf0NB+JbWoiHKTBJEYVoXBtoDZMcQX3JobEnpRZw9SMh4DoAsM7w vbwuH2szRsxIx9hGRN5RQp1+/Awepe7n53lu4diI= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Subject: [RFC PATCH v3 12/16] ceph: add encrypted fname handling to ceph_mdsc_build_path Date: Mon, 14 Sep 2020 15:17:03 -0400 Message-Id: <20200914191707.380444-13-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200914191707.380444-1-jlayton@kernel.org> References: <20200914191707.380444-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@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 | 70 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index e3dc061252d4..7eb504170981 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2314,18 +2314,27 @@ static inline u64 __get_oldest_tid(struct ceph_mds_client *mdsc) return mdsc->oldest_tid; } -/* - * Build a dentry's path. Allocate on heap; caller must kfree. Based - * on build_path_from_dentry in fs/cifs/dir.c. +/** + * ceph_mdsc_build_path - build a path string to a given dentry + * @dentry: dentry to which path should be built + * @plen: returned length of string + * @pbase: returned base inode number + * @for_wire: is this path going to be sent to the MDS? + * + * Build a string that represents the path to the dentry. This is mostly called + * for two different purposes: + * + * 1) we need to build a path string to send to the MDS (for_wire == true) + * 2) we need a path string for local presentation (e.g. debugfs) (for_wire == false) * - * If @stop_on_nosnap, generate path relative to the first non-snapped - * inode. + * The path is built in reverse, starting with the dentry. Walk back up toward + * the root, building the path until the first non-snapped inode is reached (for_wire) + * or the root inode is reached (!for_wire). * * 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; @@ -2347,30 +2356,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[FSCRYPT_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 = fscrypt_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)) @@ -2415,7 +2453,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 Mon Sep 14 19:17: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: 292031 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 19055C43461 for ; Mon, 14 Sep 2020 19:19:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D9B76208E4 for ; Mon, 14 Sep 2020 19:19:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111155; bh=rDemq33XJt6lQnTdk4QFnDjQ60aCNi5fWYRrwbTyZjY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=TnN7GL6x+PchhBsSjlYmjkRSsiA7UH5r5hwiCLfE3to7168AJ1VmvjRm/krldUJow gVYB+5+TkwzMvD8+8FGpkujacLXyyv642GiC++IwJpkFQJY0UVDmrHJoKZ0s6eHkGe Z37KeDHrLvGvc9/Wq5mLwmHorEBGEFnRNOXH3SiU= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726121AbgINTTJ (ORCPT ); Mon, 14 Sep 2020 15:19:09 -0400 Received: from mail.kernel.org ([198.145.29.99]:38982 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726020AbgINTRW (ORCPT ); Mon, 14 Sep 2020 15:17: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 E0F36221E5; Mon, 14 Sep 2020 19:17:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111038; bh=rDemq33XJt6lQnTdk4QFnDjQ60aCNi5fWYRrwbTyZjY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=igc/6RaTnba1YFRrooWazQEdvgr9QLoDr6e8jHVGKPwMx2h4DzCngUOUJVzBRwwMg B5/gtroU39YQOZDW7/xWjIBshYwa+PuZ7BkDEHvKeeISwUlreAF043k3XbJ3r2lVh/ d8aJ6Qz2Mj5dC/kN24dWmpcgl5oqPEG64YlCr2F8= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Subject: [RFC PATCH v3 13/16] ceph: make d_revalidate call fscrypt revalidator for encrypted dentries Date: Mon, 14 Sep 2020 15:17:04 -0400 Message-Id: <20200914191707.380444-14-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200914191707.380444-1-jlayton@kernel.org> References: <20200914191707.380444-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org If we have a dentry which represents a no-key name, then we need to test whether the parent directory's encryption key has since been added. Do that before we test anything else about the dentry. Signed-off-by: Jeff Layton --- fs/ceph/dir.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index b1e04d7d4b68..b6e5d751024d 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -1689,6 +1689,10 @@ 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); + 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 Mon Sep 14 19:17: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: 292034 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D7AB9C433E2 for ; Mon, 14 Sep 2020 19:18:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A1921217BA for ; Mon, 14 Sep 2020 19:18:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111111; bh=o3eFeTLsQ1ffdOk7Vk+hbU/rYNMA83Jo5MfcH3x9i18=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=CoVnT9HIaj1/iIlXiAhraFYePmI/wRLnFUaY76a8GACk+NRgO3wUNbXMoHQzDrgHx 86TFlFgfwImEtsBFC+mnATwhtMBHGEru9IQYp4nPJBYwoZogh46h4BsV3E0GDo/iFg fw2Pbb8bMj246pwVOfStnlYuhmY0ZLrIE23uVW0o= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726064AbgINTRz (ORCPT ); Mon, 14 Sep 2020 15:17:55 -0400 Received: from mail.kernel.org ([198.145.29.99]:39018 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726028AbgINTRX (ORCPT ); Mon, 14 Sep 2020 15:17:23 -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 78F71208E4; Mon, 14 Sep 2020 19:17:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111038; bh=o3eFeTLsQ1ffdOk7Vk+hbU/rYNMA83Jo5MfcH3x9i18=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D+nz/6rRdKJuabWmnHQVjy5wT9DCBBcpjTK+6/rJil8/72J3/JYSQGMGMSErdQhzU yFwFIbH7mQ8/dQhEarS1FnCsgv7nbZPNCfPYHQlzNZfKnzg1m1PMa9aeOUyXxvEi6e zw3md5p6b+fR5xGLicAhxpV8bksCXTa9hgtnp4j8= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Subject: [RFC PATCH v3 14/16] ceph: add support to readdir for encrypted filenames Date: Mon, 14 Sep 2020 15:17:05 -0400 Message-Id: <20200914191707.380444-15-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200914191707.380444-1-jlayton@kernel.org> References: <20200914191707.380444-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@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 | 35 +++++++++++++++++++++++++++++ fs/ceph/dir.c | 58 +++++++++++++++++++++++++++++++++++++++--------- fs/ceph/inode.c | 31 +++++++++++++++++++++++--- 4 files changed, 157 insertions(+), 14 deletions(-) diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c index f037a4939026..e3038c88c7a0 100644 --- a/fs/ceph/crypto.c +++ b/fs/ceph/crypto.c @@ -107,3 +107,50 @@ int ceph_fscrypt_prepare_context(struct inode *dir, struct inode *inode, 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, + bool *is_nokey) +{ + 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 = fscrypt_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, is_nokey); + + 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 c1b6ec4b2961..df1a093848bb 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" @@ -14,6 +16,22 @@ void ceph_fscrypt_set_ops(struct super_block *sb); int ceph_fscrypt_prepare_context(struct inode *dir, struct inode *inode, 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); +} + +int ceph_fname_to_usr(struct inode *parent, char *name, u32 len, struct fscrypt_str *tname, + struct fscrypt_str *oname, bool *is_nokey); + #else /* CONFIG_FS_ENCRYPTION */ static inline int ceph_fscrypt_set_ops(struct super_block *sb) @@ -27,6 +45,23 @@ static inline int ceph_fscrypt_prepare_context(struct inode *dir, struct inode * 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_fname_to_usr(struct inode *inode, char *name, u32 len, + struct fscrypt_str *tname, struct fscrypt_str *oname, bool *is_nokey) +{ + oname->name = dname; + oname->len = dlen; + return 0; +} + #endif /* CONFIG_FS_ENCRYPTION */ #endif diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index b6e5d751024d..e9fdb9c07320 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, @@ -241,7 +242,9 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx, 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 || + ((dentry->d_flags & DCACHE_ENCRYPTED_NAME) && + fscrypt_has_encryption_key(dir))) { spin_unlock(&dentry->d_lock); dput(dentry); err = -EAGAIN; @@ -313,6 +316,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) @@ -340,6 +345,12 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) ctx->pos = 2; } + if (IS_ENCRYPTED(inode)) { + err = fscrypt_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. */ @@ -360,6 +371,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? */ @@ -387,12 +406,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; @@ -405,7 +426,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 = @@ -426,7 +448,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", @@ -479,7 +501,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 */ @@ -506,9 +528,12 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) } } for (; i < rinfo->dir_nr; i++) { + bool is_nokey = false; 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", @@ -517,12 +542,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, &is_nokey); + 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++; } @@ -577,9 +610,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 2fda08518312..c3a7a9f5603d 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1653,7 +1653,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; @@ -1664,6 +1665,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); @@ -1715,14 +1718,29 @@ 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++) { + bool is_nokey = false; 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, &is_nokey); + 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); @@ -1753,6 +1771,11 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, err = -ENOMEM; goto out; } + if (is_nokey) { + 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)) { @@ -1843,6 +1866,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 Mon Sep 14 19:17: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: 292033 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6ACFC2BC11 for ; Mon, 14 Sep 2020 19:18:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9E258208E4 for ; Mon, 14 Sep 2020 19:18:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111130; bh=xpVBrva7sRk+AFgfdr5dXav+n0Np8UjCF1m/n4gOajU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=Kfh6PHx7g0OTNoGQi+QTGFJ9/R+StmllRbUzWon60IpTGtqUZRx7hphAsL0IrLR7J /RSvVpQJQyU4mOwtUhM8dqaMbGA1b1dncSvOKSUpG7qfz2+8gmPDmIwDmeLecLp2YY l39rt6DP3Z8uYwVGuAqS3bgNOxrouHwhKFFALmXY= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726100AbgINTSt (ORCPT ); Mon, 14 Sep 2020 15:18:49 -0400 Received: from mail.kernel.org ([198.145.29.99]:38984 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726022AbgINTRW (ORCPT ); Mon, 14 Sep 2020 15:17: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 0FFB6221E7; Mon, 14 Sep 2020 19:17:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600111039; bh=xpVBrva7sRk+AFgfdr5dXav+n0Np8UjCF1m/n4gOajU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pbv2ey8AyBXtMjz8nIgwnxwVK+1lWIHLaklJf3eqxWgzHaGne8oXJPBMasleJ4nL9 2nmjR+WlzJccwhNC/eoiUkQrutGK+WdC1PPeFdhp/KEbLreafSARm09ABr2XeUVIzv ifX2tR9ggCGUSJNAjR+R/OVvDL7qJycxkKNcIBXY= From: Jeff Layton To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Subject: [RFC PATCH v3 15/16] ceph: add fscrypt support to ceph_fill_trace Date: Mon, 14 Sep 2020 15:17:06 -0400 Message-Id: <20200914191707.380444-16-jlayton@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200914191707.380444-1-jlayton@kernel.org> References: <20200914191707.380444-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@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 | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index c3a7a9f5603d..8e9fb1311bb8 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1331,8 +1331,10 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req) if (dir && req->r_op == CEPH_MDS_OP_LOOKUPNAME && test_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags) && !test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags)) { + bool is_nokey = false; 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); @@ -1340,8 +1342,21 @@ 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, &is_nokey); + 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); @@ -1356,9 +1371,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_nokey) { + 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 || @@ -1370,6 +1391,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);