From patchwork Wed Mar 20 18:39:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 1059478 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="RaupsZvT"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="Qye2SP4y"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44Pdyc4j2sz9sPn for ; Thu, 21 Mar 2019 05:40:24 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=3rY5fiEq5v+mf4mophu056gE+dfnVavZi445HA0KUUY=; b=RaupsZvT4a+3JB 05OuBKjp/c/SXo8PPYHRKolcXATFW+13l7h4tgWfq52LeqTkwjWBuCQk3odvNf2IH0WnnPmMzwcan BDMsvcm06mzBeScCJhVgoyRq0NTZUemrWwqbUenQO45kLiCb7qp8g6+jm1QzL1+/IDV/mKT5jrz4W DX/bpzvIavzOtDhqGW1+Z8uv2AQMQqvy0WxxzdXuRD5CEdFwp2dhsfzVe8MKj3O6FXPuQc+hduZQ/ /yG3/TabJ5Z/8TZP62aV1VFivXwvMJux80lHtJkTFk6ys2+NDzHAQu7Lh/TX4D2MIuiVgeWUvNo6Q kDQEY5npSN+YfE5yLJFg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1h6g8Q-00005J-TX; Wed, 20 Mar 2019 18:40:18 +0000 Received: from mail.kernel.org ([198.145.29.99]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1h6g8N-0008Uv-7H for linux-mtd@lists.infradead.org; Wed, 20 Mar 2019 18:40:16 +0000 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6FE002184D; Wed, 20 Mar 2019 18:40:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1553107214; bh=gw7hzL2AWULkDpqnra8Btn4G36d3e2QHfPxFEHxuM+Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Qye2SP4yuT5Mn/ZZSTmiWX1eRJQP2xdtgpmqL0MfroLwNJuTe0KmM5BHjAxFeQ6GS dueVl8MsoLVeMGaUZc3y+gRl9R5CqJltDFCcsy4uJBrCUYtZycfq/+HWHtxm1xO3X7 xODg9CUj76XYwKA0NZbwW9jxbvBq/M5BugWipLIE= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Subject: [PATCH v2 2/5] fscrypt: fix race allowing rename() and link() of ciphertext dentries Date: Wed, 20 Mar 2019 11:39:10 -0700 Message-Id: <20190320183913.12686-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.225.g810b269d1ac-goog In-Reply-To: <20190320183913.12686-1-ebiggers@kernel.org> References: <20190320183913.12686-1-ebiggers@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190320_114015_304314_8CE266BF X-CRM114-Status: GOOD ( 12.55 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gao Xiang , linux-unionfs@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Sarthak Kukreti , linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Eric Biggers Close some race conditions where fscrypt allowed rename() and link() on ciphertext dentries that had been looked up just prior to the key being concurrently added. It's better to return -ENOKEY in this case. This avoids doing the nonsensical thing of encrypting the names a second time when searching for the actual on-disk dir entries. It also guarantees that DCACHE_ENCRYPTED_NAME dentries are never rename()d, so the dcache won't have support all possible combinations of moving DCACHE_ENCRYPTED_NAME around during __d_move(). Signed-off-by: Eric Biggers --- fs/crypto/hooks.c | 12 +++++++++++- include/linux/fscrypt.h | 9 +++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c index a9492f75bbe13..2e7498a821a48 100644 --- a/fs/crypto/hooks.c +++ b/fs/crypto/hooks.c @@ -49,7 +49,8 @@ int fscrypt_file_open(struct inode *inode, struct file *filp) } EXPORT_SYMBOL_GPL(fscrypt_file_open); -int __fscrypt_prepare_link(struct inode *inode, struct inode *dir) +int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, + struct dentry *dentry) { int err; @@ -57,6 +58,10 @@ int __fscrypt_prepare_link(struct inode *inode, struct inode *dir) if (err) return err; + /* ... in case we looked up ciphertext name before key was added */ + if (dentry->d_flags & DCACHE_ENCRYPTED_NAME) + return -ENOKEY; + if (!fscrypt_has_permitted_context(dir, inode)) return -EXDEV; @@ -78,6 +83,11 @@ int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry, if (err) return err; + /* ... in case we looked up ciphertext name(s) before key was added */ + if ((old_dentry->d_flags | new_dentry->d_flags) & + DCACHE_ENCRYPTED_NAME) + return -ENOKEY; + if (old_dir != new_dir) { if (IS_ENCRYPTED(new_dir) && !fscrypt_has_permitted_context(new_dir, diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 5a0c3fee1ea2b..4ad7a856e0f1c 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -214,7 +214,8 @@ extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t, /* hooks.c */ extern int fscrypt_file_open(struct inode *inode, struct file *filp); -extern int __fscrypt_prepare_link(struct inode *inode, struct inode *dir); +extern int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, + struct dentry *dentry); extern int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, @@ -401,8 +402,8 @@ static inline int fscrypt_file_open(struct inode *inode, struct file *filp) return 0; } -static inline int __fscrypt_prepare_link(struct inode *inode, - struct inode *dir) +static inline int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, + struct dentry *dentry) { return -EOPNOTSUPP; } @@ -497,7 +498,7 @@ static inline int fscrypt_prepare_link(struct dentry *old_dentry, struct dentry *dentry) { if (IS_ENCRYPTED(dir)) - return __fscrypt_prepare_link(d_inode(old_dentry), dir); + return __fscrypt_prepare_link(d_inode(old_dentry), dir, dentry); return 0; }