From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Theodore Tso <tytso@mit.edu>,
Eric Biggers <ebiggers@google.com>
Subject: [PATCH 4.4 16/20] ext4 crypto: revalidate dentry after adding or removing the key
Date: Fri, 5 May 2017 11:33:06 -0700 [thread overview]
Message-ID: <20170505183231.572456338@linuxfoundation.org> (raw)
In-Reply-To: <20170505183230.937615081@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <tytso@mit.edu>
commit 28b4c263961c47da84ed8b5be0b5116bad1133eb upstream.
Add a validation check for dentries for encrypted directory to make
sure we're not caching stale data after a key has been added or removed.
Also check to make sure that status of the encryption key is updated
when readdir(2) is executed.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/ext4/crypto.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
fs/ext4/dir.c | 6 ++++++
fs/ext4/ext4.h | 1 +
fs/ext4/namei.c | 18 ++++++++++++++++++
4 files changed, 75 insertions(+)
--- a/fs/ext4/crypto.c
+++ b/fs/ext4/crypto.c
@@ -469,3 +469,53 @@ uint32_t ext4_validate_encryption_key_si
return size;
return 0;
}
+
+/*
+ * Validate dentries for encrypted directories to make sure we aren't
+ * potentially caching stale data after a key has been added or
+ * removed.
+ */
+static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags)
+{
+ struct inode *dir = d_inode(dentry->d_parent);
+ struct ext4_crypt_info *ci = EXT4_I(dir)->i_crypt_info;
+ int dir_has_key, cached_with_key;
+
+ if (!ext4_encrypted_inode(dir))
+ return 0;
+
+ /* this should eventually be an flag in d_flags */
+ cached_with_key = dentry->d_fsdata != NULL;
+ dir_has_key = (ci != NULL);
+
+ /*
+ * If the dentry was cached without the key, and it is a
+ * negative dentry, it might be a valid name. We can't check
+ * if the key has since been made available due to locking
+ * reasons, so we fail the validation so ext4_lookup() can do
+ * this check.
+ *
+ * We also fail the validation if the dentry was created with
+ * the key present, but we no longer have the key, or vice versa.
+ */
+ if ((!cached_with_key && d_is_negative(dentry)) ||
+ (!cached_with_key && dir_has_key) ||
+ (cached_with_key && !dir_has_key)) {
+#if 0 /* Revalidation debug */
+ char buf[80];
+ char *cp = simple_dname(dentry, buf, sizeof(buf));
+
+ if (IS_ERR(cp))
+ cp = (char *) "???";
+ pr_err("revalidate: %s %p %d %d %d\n", cp, dentry->d_fsdata,
+ cached_with_key, d_is_negative(dentry),
+ dir_has_key);
+#endif
+ return 0;
+ }
+ return 1;
+}
+
+const struct dentry_operations ext4_encrypted_d_ops = {
+ .d_revalidate = ext4_d_revalidate,
+};
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -111,6 +111,12 @@ static int ext4_readdir(struct file *fil
int dir_has_error = 0;
struct ext4_str fname_crypto_str = {.name = NULL, .len = 0};
+ if (ext4_encrypted_inode(inode)) {
+ err = ext4_get_encryption_info(inode);
+ if (err && err != -ENOKEY)
+ return err;
+ }
+
if (is_dx_dir(inode)) {
err = ext4_dx_readdir(file, ctx);
if (err != ERR_BAD_DX_DIR) {
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2268,6 +2268,7 @@ struct page *ext4_encrypt(struct inode *
struct page *plaintext_page);
int ext4_decrypt(struct page *page);
int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex);
+extern const struct dentry_operations ext4_encrypted_d_ops;
#ifdef CONFIG_EXT4_FS_ENCRYPTION
int ext4_init_crypto(void);
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1557,6 +1557,24 @@ static struct dentry *ext4_lookup(struct
struct ext4_dir_entry_2 *de;
struct buffer_head *bh;
+ if (ext4_encrypted_inode(dir)) {
+ int res = ext4_get_encryption_info(dir);
+
+ /*
+ * This should be a properly defined flag for
+ * dentry->d_flags when we uplift this to the VFS.
+ * d_fsdata is set to (void *) 1 if if the dentry is
+ * created while the directory was encrypted and we
+ * don't have access to the key.
+ */
+ dentry->d_fsdata = NULL;
+ if (ext4_encryption_info(dir))
+ dentry->d_fsdata = (void *) 1;
+ d_set_d_op(dentry, &ext4_encrypted_d_ops);
+ if (res && res != -ENOKEY)
+ return ERR_PTR(res);
+ }
+
if (dentry->d_name.len > EXT4_NAME_LEN)
return ERR_PTR(-ENAMETOOLONG);
next prev parent reply other threads:[~2017-05-05 18:36 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-05 18:32 [PATCH 4.4 00/20] 4.4.67-stable review Greg Kroah-Hartman
2017-05-05 18:32 ` [PATCH 4.4 01/20] timerfd: Protect the might cancel mechanism proper Greg Kroah-Hartman
2017-05-05 18:32 ` [PATCH 4.4 02/20] Handle mismatched open calls Greg Kroah-Hartman
2017-05-05 18:32 ` [PATCH 4.4 03/20] ASoC: intel: Fix PM and non-atomic crash in bytcr drivers Greg Kroah-Hartman
2017-05-05 18:32 ` [PATCH 4.4 04/20] ALSA: ppc/awacs: shut up maybe-uninitialized warning Greg Kroah-Hartman
2017-05-05 18:32 ` [PATCH 4.4 05/20] drbd: avoid redefinition of BITS_PER_PAGE Greg Kroah-Hartman
2017-05-05 18:32 ` [PATCH 4.4 06/20] mtd: avoid stack overflow in MTD CFI code Greg Kroah-Hartman
2017-05-05 18:32 ` [PATCH 4.4 07/20] net: tg3: avoid uninitialized variable warning Greg Kroah-Hartman
2017-05-05 18:32 ` [PATCH 4.4 08/20] scsi: cxlflash: Scan host only after the port is ready for I/O Greg Kroah-Hartman
2017-05-05 18:32 ` [PATCH 4.4 09/20] scsi: cxlflash: Fix to avoid EEH and host reset collisions Greg Kroah-Hartman
2017-05-05 18:33 ` [PATCH 4.4 10/20] scsi: cxlflash: Improve EEH recovery time Greg Kroah-Hartman
2017-05-05 18:33 ` [PATCH 4.4 11/20] 8250_pci: Fix potential use-after-free in error path Greg Kroah-Hartman
2017-05-05 18:33 ` [PATCH 4.4 12/20] netlink: Allow direct reclaim for fallback allocation Greg Kroah-Hartman
2017-05-05 18:33 ` [PATCH 4.4 13/20] IB/qib: rename BITS_PER_PAGE to RVT_BITS_PER_PAGE Greg Kroah-Hartman
2017-05-05 18:33 ` [PATCH 4.4 14/20] IB/ehca: fix maybe-uninitialized warnings Greg Kroah-Hartman
2017-05-05 18:33 ` [PATCH 4.4 15/20] ext4: require encryption feature for EXT4_IOC_SET_ENCRYPTION_POLICY Greg Kroah-Hartman
2017-05-05 18:33 ` Greg Kroah-Hartman [this message]
2017-05-05 18:33 ` [PATCH 4.4 17/20] ext4 crypto: use dget_parent() in ext4_d_revalidate() Greg Kroah-Hartman
2017-05-05 18:33 ` [PATCH 4.4 18/20] ext4/fscrypto: avoid RCU lookup in d_revalidate Greg Kroah-Hartman
2017-05-05 18:33 ` [PATCH 4.4 19/20] nfsd4: minor NFSv2/v3 write decoding cleanup Greg Kroah-Hartman
2017-05-06 1:58 ` [PATCH 4.4 00/20] 4.4.67-stable review Shuah Khan
2017-05-06 3:41 ` Greg Kroah-Hartman
2017-05-07 20:53 ` Guenter Roeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170505183231.572456338@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=ebiggers@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.