From patchwork Mon Oct 9 19:15:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 823441 X-Patchwork-Delegate: richard@nod.at 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=65.50.211.133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="PhSE6UkO"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="tnHQc9XD"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.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 3y9qqL1LmWz9t44 for ; Tue, 10 Oct 2017 06:21:34 +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:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: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=MaQFSudb9a7lo52zxczSTBZIG3DkG1fruXUBDLZRVoI=; b=PhSE6UkOX5h+6TQa4RUNj5spg9 b1p432G+b/3fMYAVy+mnhHkMXSvgUsCINMYsLNpRR6rXhspXf6oPngcnA00RbpOCtpam1wZsLdfhI RkuNmtlOaT2q7Dc/FfxZMKZ1HFKB1C4K0ksNp/R8KaIfhmpJmfHeWvqxsG8W1ITpITtbP2zsrS3o4 bmSNP1Ge8k3BiVc15pnReDnRx8qxhuiU5DsBnFFdTbXenZNab9rW75uXOnxY8MfMvmIuWbKIIWW4B U02tfnJjnqectd5fCydoLEPg1kqh6sjh9kiMfHE40+f3I3WLri+u9yva1WN28fcyGQvyxegLtds1x vPDwHEoQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1e1dcF-0003Fo-6L; Mon, 09 Oct 2017 19:21:27 +0000 Received: from mail-pf0-x241.google.com ([2607:f8b0:400e:c00::241]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1e1daH-0000FR-7S for linux-mtd@lists.infradead.org; Mon, 09 Oct 2017 19:19:37 +0000 Received: by mail-pf0-x241.google.com with SMTP id z11so12491790pfk.3 for ; Mon, 09 Oct 2017 12:19:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=i1oVWzEz3lZqOzC2AReyLfoTNURRuv9RDQzYZFnToqs=; b=tnHQc9XDf2HDUDUWAgzxPbA/aPW6QaxfLelkFQ4HZuvn/iE5vIXzp+Zqa3cujL/oW4 yxXoUUv3BjpZq1gu4riGr3V1TqtjkGbg/rEa1LA3HGFKQOQQkGTgHqmfz+ErytzkA7Q6 AthpKInf6xwp52tnLxydM2u9pOf5jHS19VjybQHy2VIF7JrlQ5fi+CgFPhP4KwZzjSqc cxXU76o9qnaRl9fyCwRITtZv+rmOMloR/024BoweRHseO8eXLe792v654wXXWUM3pymj pYo4mARflUByFmIvu152580PrZ5kxyn3C1UKV3zpymHaj6is3ZpiUFwBj44wmoUTRycf PLCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=i1oVWzEz3lZqOzC2AReyLfoTNURRuv9RDQzYZFnToqs=; b=AowUpy8powq25Nn948lEpqA0CLEfpuOL5Na8YeYGQy2nqkUfWN5YZzHsLi0GdfoX6e yUJ2+VOP6gvCZBaJ76YrczkhQpRYfiAFyvX45BOn9N5mPwsR4FIosmRA7/nXXshV2sbn fAxQgqnQJpuLrNrbZhotb53svQQSJ8hNgaJAHeiEFQWuhz5sRH2t0TdZg1M8zPaZwKOs FUVv1mF9wM5b7PVlCLe+3nJb3jiFcAGtRxNOO6mybsi6Dw8H3Bi+F24aT8wrbUOOq9TP c2OQ3Wv6eosxAH5a8fbHUqJf/oVNKbhemScFT/0nEXpMxbo7XWbvCQ8s4sb77k+WdnlY vDvQ== X-Gm-Message-State: AMCzsaUfo4LonlZxoFyHdRmEes6KhgnjW/S2LDjVhrvcACzDjGuzsA1L y3BC1QLv/qCAtXqK6OctW0U= X-Google-Smtp-Source: AOwi7QAl/Vc3gonhN0YTDkcp50w3LYXHwBHhX2BF8W+ecSmvylCnSIIxUbZYNjdvVZ461mhZJ8NRvA== X-Received: by 10.99.173.74 with SMTP id y10mr9834819pgo.107.1507576748979; Mon, 09 Oct 2017 12:19:08 -0700 (PDT) Received: from ebiggers-linuxstation.kir.corp.google.com ([100.66.174.81]) by smtp.gmail.com with ESMTPSA id n29sm17039819pgf.44.2017.10.09.12.19.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Oct 2017 12:19:08 -0700 (PDT) From: Eric Biggers To: linux-fscrypt@vger.kernel.org, "Theodore Y . Ts'o" Subject: [PATCH v2 09/11] fscrypt: new helper function - fscrypt_prepare_rename() Date: Mon, 9 Oct 2017 12:15:42 -0700 Message-Id: <20171009191544.43656-10-ebiggers3@gmail.com> X-Mailer: git-send-email 2.14.2.920.gcf0c67979c-goog In-Reply-To: <20171009191544.43656-1-ebiggers3@gmail.com> References: <20171009191544.43656-1-ebiggers3@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171009_121926_280370_5AC93BD8 X-CRM114-Status: GOOD ( 15.39 ) X-Spam-Score: -1.8 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.8 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [2607:f8b0:400e:c00:0:0:0:241 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit (ebiggers3[at]gmail.com) 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (ebiggers3[at]gmail.com) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 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: Eric Biggers , linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, linux-fsdevel@vger.kernel.org, Jaegeuk Kim , linux-ext4@vger.kernel.org MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Eric Biggers Introduce a helper function which prepares to rename a file into a possibly encrypted directory. It handles loading the encryption keys for the source and target directories if needed, and it handles enforcing that if the target directory (and the source directory for a cross-rename) is encrypted, then the file being moved into the directory has the same encryption policy as its containing directory. Acked-by: Dave Chinner Signed-off-by: Eric Biggers --- fs/crypto/hooks.c | 30 ++++++++++++++++++++++++++++++ include/linux/fscrypt.h | 33 +++++++++++++++++++++++++++++++++ include/linux/fscrypt_notsupp.h | 9 +++++++++ include/linux/fscrypt_supp.h | 5 +++++ 4 files changed, 77 insertions(+) diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c index 8b90217320dd..822cb78f9b45 100644 --- a/fs/crypto/hooks.c +++ b/fs/crypto/hooks.c @@ -62,3 +62,33 @@ int __fscrypt_prepare_link(struct inode *inode, struct inode *dir) return 0; } EXPORT_SYMBOL_GPL(__fscrypt_prepare_link); + +int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + unsigned int flags) +{ + int err; + + err = fscrypt_require_key(old_dir); + if (err) + return err; + + err = fscrypt_require_key(new_dir); + if (err) + return err; + + if (old_dir != new_dir) { + if (IS_ENCRYPTED(new_dir) && + !fscrypt_has_permitted_context(new_dir, + d_inode(old_dentry))) + return -EPERM; + + if ((flags & RENAME_EXCHANGE) && + IS_ENCRYPTED(old_dir) && + !fscrypt_has_permitted_context(old_dir, + d_inode(new_dentry))) + return -EPERM; + } + return 0; +} +EXPORT_SYMBOL_GPL(__fscrypt_prepare_rename); diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 9c9a53f99327..c422367baed9 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -204,4 +204,37 @@ static inline int fscrypt_prepare_link(struct dentry *old_dentry, return 0; } +/** + * fscrypt_prepare_rename - prepare for a rename between possibly-encrypted directories + * @old_dir: source directory + * @old_dentry: dentry for source file + * @new_dir: target directory + * @new_dentry: dentry for target location (may be negative unless exchanging) + * @flags: rename flags (we care at least about %RENAME_EXCHANGE) + * + * Prepare for ->rename() where the source and/or target directories may be + * encrypted. A new link can only be added to an encrypted directory if the + * directory's encryption key is available --- since otherwise we'd have no way + * to encrypt the filename. A rename to an existing name, on the other hand, + * *is* cryptographically possible without the key. However, we take the more + * conservative approach and just forbid all no-key renames. + * + * We also verify that the rename will not violate the constraint that all files + * in an encrypted directory tree use the same encryption policy. + * + * Return: 0 on success, -ENOKEY if an encryption key is missing, -EPERM if the + * rename would cause inconsistent encryption policies, or another -errno code. + */ +static inline int fscrypt_prepare_rename(struct inode *old_dir, + struct dentry *old_dentry, + struct inode *new_dir, + struct dentry *new_dentry, + unsigned int flags) +{ + if (IS_ENCRYPTED(old_dir) || IS_ENCRYPTED(new_dir)) + return __fscrypt_prepare_rename(old_dir, old_dentry, + new_dir, new_dentry, flags); + return 0; +} + #endif /* _LINUX_FSCRYPT_H */ diff --git a/include/linux/fscrypt_notsupp.h b/include/linux/fscrypt_notsupp.h index d7d1039eb6b5..6af378d8126e 100644 --- a/include/linux/fscrypt_notsupp.h +++ b/include/linux/fscrypt_notsupp.h @@ -192,4 +192,13 @@ static inline int __fscrypt_prepare_link(struct inode *inode, return -EOPNOTSUPP; } +static inline int __fscrypt_prepare_rename(struct inode *old_dir, + struct dentry *old_dentry, + struct inode *new_dir, + struct dentry *new_dentry, + unsigned int flags) +{ + return -EOPNOTSUPP; +} + #endif /* _LINUX_FSCRYPT_NOTSUPP_H */ diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h index 80706283da75..40f35073145f 100644 --- a/include/linux/fscrypt_supp.h +++ b/include/linux/fscrypt_supp.h @@ -146,5 +146,10 @@ 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_rename(struct inode *old_dir, + struct dentry *old_dentry, + struct inode *new_dir, + struct dentry *new_dentry, + unsigned int flags); #endif /* _LINUX_FSCRYPT_SUPP_H */