summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Gortmaker <paul.gortmaker@windriver.com>2017-06-02 13:20:49 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2017-06-02 13:20:49 -0400
commit5cc3f3752f9442fd814884fe7bd19bfe2ea3cf5c (patch)
tree101b72d8953f0d40708cc078e474c68a48c61cce
parent6d8de1ed5824e99fb6d3a7898dd5425d3b4ce6e8 (diff)
downloadlongterm-queue-4.8-5cc3f3752f9442fd814884fe7bd19bfe2ea3cf5c.tar.gz
fscrypt: drop broken crypt removal patch
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r--queue/fscrypt-remove-broken-support-for-detecting-keyring-.patch248
-rw-r--r--queue/series1
2 files changed, 0 insertions, 249 deletions
diff --git a/queue/fscrypt-remove-broken-support-for-detecting-keyring-.patch b/queue/fscrypt-remove-broken-support-for-detecting-keyring-.patch
deleted file mode 100644
index 283c250..0000000
--- a/queue/fscrypt-remove-broken-support-for-detecting-keyring-.patch
+++ /dev/null
@@ -1,248 +0,0 @@
-From 1b53cf9815bb4744958d41f3795d5d5a1d365e2d Mon Sep 17 00:00:00 2001
-From: Eric Biggers <ebiggers@google.com>
-Date: Tue, 21 Feb 2017 15:07:11 -0800
-Subject: [PATCH] fscrypt: remove broken support for detecting keyring key
- revocation
-
-commit 1b53cf9815bb4744958d41f3795d5d5a1d365e2d upstream.
-
-Filesystem encryption ostensibly supported revoking a keyring key that
-had been used to "unlock" encrypted files, causing those files to become
-"locked" again. This was, however, buggy for several reasons, the most
-severe of which was that when key revocation happened to be detected for
-an inode, its fscrypt_info was immediately freed, even while other
-threads could be using it for encryption or decryption concurrently.
-This could be exploited to crash the kernel or worse.
-
-This patch fixes the use-after-free by removing the code which detects
-the keyring key having been revoked, invalidated, or expired. Instead,
-an encrypted inode that is "unlocked" now simply remains unlocked until
-it is evicted from memory. Note that this is no worse than the case for
-block device-level encryption, e.g. dm-crypt, and it still remains
-possible for a privileged user to evict unused pages, inodes, and
-dentries by running 'sync; echo 3 > /proc/sys/vm/drop_caches', or by
-simply unmounting the filesystem. In fact, one of those actions was
-already needed anyway for key revocation to work even somewhat sanely.
-This change is not expected to break any applications.
-
-In the future I'd like to implement a real API for fscrypt key
-revocation that interacts sanely with ongoing filesystem operations ---
-waiting for existing operations to complete and blocking new operations,
-and invalidating and sanitizing key material and plaintext from the VFS
-caches. But this is a hard problem, and for now this bug must be fixed.
-
-This bug affected almost all versions of ext4, f2fs, and ubifs
-encryption, and it was potentially reachable in any kernel configured
-with encryption support (CONFIG_EXT4_ENCRYPTION=y,
-CONFIG_EXT4_FS_ENCRYPTION=y, CONFIG_F2FS_FS_ENCRYPTION=y, or
-CONFIG_UBIFS_FS_ENCRYPTION=y). Note that older kernels did not use the
-shared fs/crypto/ code, but due to the potential security implications
-of this bug, it may still be worthwhile to backport this fix to them.
-
-Fixes: b7236e21d55f ("ext4 crypto: reorganize how we store keys in the inode")
-Cc: stable@vger.kernel.org # v4.2+
-Signed-off-by: Eric Biggers <ebiggers@google.com>
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Acked-by: Michael Halcrow <mhalcrow@google.com>
-
-diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
-index 02a7a9286449..6d6eca394d4d 100644
---- a/fs/crypto/crypto.c
-+++ b/fs/crypto/crypto.c
-@@ -327,7 +327,6 @@ EXPORT_SYMBOL(fscrypt_decrypt_page);
- static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
- {
- struct dentry *dir;
-- struct fscrypt_info *ci;
- int dir_has_key, cached_with_key;
-
- if (flags & LOOKUP_RCU)
-@@ -339,18 +338,11 @@ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
- return 0;
- }
-
-- ci = d_inode(dir)->i_crypt_info;
-- if (ci && ci->ci_keyring_key &&
-- (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
-- (1 << KEY_FLAG_REVOKED) |
-- (1 << KEY_FLAG_DEAD))))
-- ci = NULL;
--
- /* this should eventually be an flag in d_flags */
- spin_lock(&dentry->d_lock);
- cached_with_key = dentry->d_flags & DCACHE_ENCRYPTED_WITH_KEY;
- spin_unlock(&dentry->d_lock);
-- dir_has_key = (ci != NULL);
-+ dir_has_key = (d_inode(dir)->i_crypt_info != NULL);
- dput(dir);
-
- /*
-diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
-index 13052b85c393..37b49894c762 100644
---- a/fs/crypto/fname.c
-+++ b/fs/crypto/fname.c
-@@ -350,7 +350,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
- fname->disk_name.len = iname->len;
- return 0;
- }
-- ret = fscrypt_get_crypt_info(dir);
-+ ret = fscrypt_get_encryption_info(dir);
- if (ret && ret != -EOPNOTSUPP)
- return ret;
-
-diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
-index fdbb8af32eaf..e39696e64494 100644
---- a/fs/crypto/fscrypt_private.h
-+++ b/fs/crypto/fscrypt_private.h
-@@ -67,7 +67,6 @@ struct fscrypt_info {
- u8 ci_filename_mode;
- u8 ci_flags;
- struct crypto_skcipher *ci_ctfm;
-- struct key *ci_keyring_key;
- u8 ci_master_key[FS_KEY_DESCRIPTOR_SIZE];
- };
-
-@@ -101,7 +100,4 @@ extern int fscrypt_do_page_crypto(const struct inode *inode,
- extern struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx,
- gfp_t gfp_flags);
-
--/* keyinfo.c */
--extern int fscrypt_get_crypt_info(struct inode *);
--
- #endif /* _FSCRYPT_PRIVATE_H */
-diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
-index 02eb6b9e4438..cb3e82abf034 100644
---- a/fs/crypto/keyinfo.c
-+++ b/fs/crypto/keyinfo.c
-@@ -95,6 +95,7 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
- kfree(description);
- if (IS_ERR(keyring_key))
- return PTR_ERR(keyring_key);
-+ down_read(&keyring_key->sem);
-
- if (keyring_key->type != &key_type_logon) {
- printk_once(KERN_WARNING
-@@ -102,11 +103,9 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
- res = -ENOKEY;
- goto out;
- }
-- down_read(&keyring_key->sem);
- ukp = user_key_payload(keyring_key);
- if (ukp->datalen != sizeof(struct fscrypt_key)) {
- res = -EINVAL;
-- up_read(&keyring_key->sem);
- goto out;
- }
- master_key = (struct fscrypt_key *)ukp->data;
-@@ -117,17 +116,11 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
- "%s: key size incorrect: %d\n",
- __func__, master_key->size);
- res = -ENOKEY;
-- up_read(&keyring_key->sem);
- goto out;
- }
- res = derive_key_aes(ctx->nonce, master_key->raw, raw_key);
-- up_read(&keyring_key->sem);
-- if (res)
-- goto out;
--
-- crypt_info->ci_keyring_key = keyring_key;
-- return 0;
- out:
-+ up_read(&keyring_key->sem);
- key_put(keyring_key);
- return res;
- }
-@@ -169,12 +162,11 @@ static void put_crypt_info(struct fscrypt_info *ci)
- if (!ci)
- return;
-
-- key_put(ci->ci_keyring_key);
- crypto_free_skcipher(ci->ci_ctfm);
- kmem_cache_free(fscrypt_info_cachep, ci);
- }
-
--int fscrypt_get_crypt_info(struct inode *inode)
-+int fscrypt_get_encryption_info(struct inode *inode)
- {
- struct fscrypt_info *crypt_info;
- struct fscrypt_context ctx;
-@@ -184,21 +176,15 @@ int fscrypt_get_crypt_info(struct inode *inode)
- u8 *raw_key = NULL;
- int res;
-
-+ if (inode->i_crypt_info)
-+ return 0;
-+
- res = fscrypt_initialize(inode->i_sb->s_cop->flags);
- if (res)
- return res;
-
- if (!inode->i_sb->s_cop->get_context)
- return -EOPNOTSUPP;
--retry:
-- crypt_info = ACCESS_ONCE(inode->i_crypt_info);
-- if (crypt_info) {
-- if (!crypt_info->ci_keyring_key ||
-- key_validate(crypt_info->ci_keyring_key) == 0)
-- return 0;
-- fscrypt_put_encryption_info(inode, crypt_info);
-- goto retry;
-- }
-
- res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx));
- if (res < 0) {
-@@ -229,7 +215,6 @@ retry:
- crypt_info->ci_data_mode = ctx.contents_encryption_mode;
- crypt_info->ci_filename_mode = ctx.filenames_encryption_mode;
- crypt_info->ci_ctfm = NULL;
-- crypt_info->ci_keyring_key = NULL;
- memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
- sizeof(crypt_info->ci_master_key));
-
-@@ -273,14 +258,8 @@ retry:
- if (res)
- goto out;
-
-- kzfree(raw_key);
-- raw_key = NULL;
-- if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) != NULL) {
-- put_crypt_info(crypt_info);
-- goto retry;
-- }
-- return 0;
--
-+ if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) == NULL)
-+ crypt_info = NULL;
- out:
- if (res == -ENOKEY)
- res = 0;
-@@ -288,6 +267,7 @@ out:
- kzfree(raw_key);
- return res;
- }
-+EXPORT_SYMBOL(fscrypt_get_encryption_info);
-
- void fscrypt_put_encryption_info(struct inode *inode, struct fscrypt_info *ci)
- {
-@@ -305,17 +285,3 @@ void fscrypt_put_encryption_info(struct inode *inode, struct fscrypt_info *ci)
- put_crypt_info(ci);
- }
- EXPORT_SYMBOL(fscrypt_put_encryption_info);
--
--int fscrypt_get_encryption_info(struct inode *inode)
--{
-- struct fscrypt_info *ci = inode->i_crypt_info;
--
-- if (!ci ||
-- (ci->ci_keyring_key &&
-- (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
-- (1 << KEY_FLAG_REVOKED) |
-- (1 << KEY_FLAG_DEAD)))))
-- return fscrypt_get_crypt_info(inode);
-- return 0;
--}
--EXPORT_SYMBOL(fscrypt_get_encryption_info);
---
-2.12.0
-
diff --git a/queue/series b/queue/series
index b618a46..83791b0 100644
--- a/queue/series
+++ b/queue/series
@@ -100,7 +100,6 @@ sparc-ptrace-Preserve-previous-registers-for-short-r.patch
metag-ptrace-Preserve-previous-registers-for-short-r.patch
metag-ptrace-Provide-default-TXSTATUS-for-short-NT_P.patch
metag-ptrace-Reject-partial-NT_METAG_RPIPE-writes.patch
-fscrypt-remove-broken-support-for-detecting-keyring-.patch
sched-rt-Add-a-missing-rescheduling-point.patch
libceph-force-GFP_NOIO-for-socket-allocations.patch
xen-setup-Don-t-relocate-p2m-over-existing-one.patch