From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Eric Biggers <ebiggers@google.com>,
Theodore Tso <tytso@mit.edu>
Subject: [PATCH 4.9 67/80] fscrypt: fix context consistency check when key(s) unavailable
Date: Thu, 18 May 2017 12:48:49 +0200 [thread overview]
Message-ID: <20170518104836.993435308@linuxfoundation.org> (raw)
In-Reply-To: <20170518104833.667298773@linuxfoundation.org>
4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@google.com>
commit 272f98f6846277378e1758a49a49d7bf39343c02 upstream.
To mitigate some types of offline attacks, filesystem encryption is
designed to enforce that all files in an encrypted directory tree use
the same encryption policy (i.e. the same encryption context excluding
the nonce). However, the fscrypt_has_permitted_context() function which
enforces this relies on comparing struct fscrypt_info's, which are only
available when we have the encryption keys. This can cause two
incorrect behaviors:
1. If we have the parent directory's key but not the child's key, or
vice versa, then fscrypt_has_permitted_context() returned false,
causing applications to see EPERM or ENOKEY. This is incorrect if
the encryption contexts are in fact consistent. Although we'd
normally have either both keys or neither key in that case since the
master_key_descriptors would be the same, this is not guaranteed
because keys can be added or removed from keyrings at any time.
2. If we have neither the parent's key nor the child's key, then
fscrypt_has_permitted_context() returned true, causing applications
to see no error (or else an error for some other reason). This is
incorrect if the encryption contexts are in fact inconsistent, since
in that case we should deny access.
To fix this, retrieve and compare the fscrypt_contexts if we are unable
to set up both fscrypt_infos.
While this slightly hurts performance when accessing an encrypted
directory tree without the key, this isn't a case we really need to be
optimizing for; access *with* the key is much more important.
Furthermore, the performance hit is barely noticeable given that we are
already retrieving the fscrypt_context and doing two keyring searches in
fscrypt_get_encryption_info(). If we ever actually wanted to optimize
this case we might start by caching the fscrypt_contexts.
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/crypto/policy.c | 87 +++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 68 insertions(+), 19 deletions(-)
--- a/fs/crypto/policy.c
+++ b/fs/crypto/policy.c
@@ -161,27 +161,61 @@ int fscrypt_get_policy(struct inode *ino
}
EXPORT_SYMBOL(fscrypt_get_policy);
+/**
+ * fscrypt_has_permitted_context() - is a file's encryption policy permitted
+ * within its directory?
+ *
+ * @parent: inode for parent directory
+ * @child: inode for file being looked up, opened, or linked into @parent
+ *
+ * Filesystems must call this before permitting access to an inode in a
+ * situation where the parent directory is encrypted (either before allowing
+ * ->lookup() to succeed, or for a regular file before allowing it to be opened)
+ * and before any operation that involves linking an inode into an encrypted
+ * directory, including link, rename, and cross rename. It enforces the
+ * constraint that within a given encrypted directory tree, all files use the
+ * same encryption policy. The pre-access check is needed to detect potentially
+ * malicious offline violations of this constraint, while the link and rename
+ * checks are needed to prevent online violations of this constraint.
+ *
+ * Return: 1 if permitted, 0 if forbidden. If forbidden, the caller must fail
+ * the filesystem operation with EPERM.
+ */
int fscrypt_has_permitted_context(struct inode *parent, struct inode *child)
{
- struct fscrypt_info *parent_ci, *child_ci;
+ const struct fscrypt_operations *cops = parent->i_sb->s_cop;
+ const struct fscrypt_info *parent_ci, *child_ci;
+ struct fscrypt_context parent_ctx, child_ctx;
int res;
- if ((parent == NULL) || (child == NULL)) {
- printk(KERN_ERR "parent %p child %p\n", parent, child);
- BUG_ON(1);
- }
-
/* No restrictions on file types which are never encrypted */
if (!S_ISREG(child->i_mode) && !S_ISDIR(child->i_mode) &&
!S_ISLNK(child->i_mode))
return 1;
- /* no restrictions if the parent directory is not encrypted */
- if (!parent->i_sb->s_cop->is_encrypted(parent))
+ /* No restrictions if the parent directory is unencrypted */
+ if (!cops->is_encrypted(parent))
return 1;
- /* if the child directory is not encrypted, this is always a problem */
- if (!parent->i_sb->s_cop->is_encrypted(child))
+
+ /* Encrypted directories must not contain unencrypted files */
+ if (!cops->is_encrypted(child))
return 0;
+
+ /*
+ * Both parent and child are encrypted, so verify they use the same
+ * encryption policy. Compare the fscrypt_info structs if the keys are
+ * available, otherwise retrieve and compare the fscrypt_contexts.
+ *
+ * Note that the fscrypt_context retrieval will be required frequently
+ * when accessing an encrypted directory tree without the key.
+ * Performance-wise this is not a big deal because we already don't
+ * really optimize for file access without the key (to the extent that
+ * such access is even possible), given that any attempted access
+ * already causes a fscrypt_context retrieval and keyring search.
+ *
+ * In any case, if an unexpected error occurs, fall back to "forbidden".
+ */
+
res = fscrypt_get_encryption_info(parent);
if (res)
return 0;
@@ -190,17 +224,32 @@ int fscrypt_has_permitted_context(struct
return 0;
parent_ci = parent->i_crypt_info;
child_ci = child->i_crypt_info;
- if (!parent_ci && !child_ci)
- return 1;
- if (!parent_ci || !child_ci)
+
+ if (parent_ci && child_ci) {
+ return memcmp(parent_ci->ci_master_key, child_ci->ci_master_key,
+ FS_KEY_DESCRIPTOR_SIZE) == 0 &&
+ (parent_ci->ci_data_mode == child_ci->ci_data_mode) &&
+ (parent_ci->ci_filename_mode ==
+ child_ci->ci_filename_mode) &&
+ (parent_ci->ci_flags == child_ci->ci_flags);
+ }
+
+ res = cops->get_context(parent, &parent_ctx, sizeof(parent_ctx));
+ if (res != sizeof(parent_ctx))
+ return 0;
+
+ res = cops->get_context(child, &child_ctx, sizeof(child_ctx));
+ if (res != sizeof(child_ctx))
return 0;
- return (memcmp(parent_ci->ci_master_key,
- child_ci->ci_master_key,
- FS_KEY_DESCRIPTOR_SIZE) == 0 &&
- (parent_ci->ci_data_mode == child_ci->ci_data_mode) &&
- (parent_ci->ci_filename_mode == child_ci->ci_filename_mode) &&
- (parent_ci->ci_flags == child_ci->ci_flags));
+ return memcmp(parent_ctx.master_key_descriptor,
+ child_ctx.master_key_descriptor,
+ FS_KEY_DESCRIPTOR_SIZE) == 0 &&
+ (parent_ctx.contents_encryption_mode ==
+ child_ctx.contents_encryption_mode) &&
+ (parent_ctx.filenames_encryption_mode ==
+ child_ctx.filenames_encryption_mode) &&
+ (parent_ctx.flags == child_ctx.flags);
}
EXPORT_SYMBOL(fscrypt_has_permitted_context);
next prev parent reply other threads:[~2017-05-18 11:00 UTC|newest]
Thread overview: 79+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-18 10:47 [PATCH 4.9 00/80] 4.9.29-stable review Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 01/80] xen: adjust early dom0 p2m handling to xen hypervisor behavior Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 02/80] target: Fix compare_and_write_callback handling for non GOOD status Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 03/80] target/fileio: Fix zero-length READ and WRITE handling Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 04/80] iscsi-target: Set session_fall_back_to_erl0 when forcing reinstatement Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 05/80] usb: xhci: bInterval quirk for TI TUSB73x0 Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 06/80] usb: host: xhci: print correct command ring address Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 07/80] USB: serial: ftdi_sio: add device ID for Microsemi/Arrow SF2PLUS Dev Kit Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 08/80] USB: Proper handling of Race Condition when two USB class drivers try to call init_usb_class simultaneously Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 10/80] staging: vt6656: use off stack for in buffer USB transfers Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 11/80] staging: vt6656: use off stack for out " Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 12/80] staging: gdm724x: gdm_mux: fix use-after-free on module unload Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 13/80] staging: comedi: jr3_pci: fix possible null pointer dereference Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 14/80] staging: comedi: jr3_pci: cope with jiffies wraparound Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 15/80] usb: misc: add missing continue in switch Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 16/80] usb: gadget: legacy gadgets are optional Greg Kroah-Hartman
2017-05-18 10:47 ` [PATCH 4.9 17/80] usb: Make sure usb/phy/of gets built-in Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 18/80] usb: hub: Fix error loop seen after hub communication errors Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 19/80] usb: hub: Do not attempt to autosuspend disconnected devices Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 20/80] usb: misc: legousbtower: Fix buffers on stack Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 21/80] x86/boot: Fix BSS corruption/overwrite bug in early x86 kernel startup Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 22/80] selftests/x86/ldt_gdt_32: Work around a glibc sigaction() bug Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 23/80] x86, pmem: Fix cache flushing for iovec write < 8 bytes Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 24/80] um: Fix PTRACE_POKEUSER on x86_64 Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 25/80] perf/x86: Fix Broadwell-EP DRAM RAPL events Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 27/80] KVM: arm/arm64: fix races in kvm_psci_vcpu_on Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 28/80] arm64: KVM: Fix decoding of Rt/Rt2 when trapping AArch32 CP accesses Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 29/80] block: fix blk_integrity_register to use templates interval_exp if not 0 Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 30/80] crypto: algif_aead - Require setkey before accept(2) Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 31/80] crypto: ccp - Use only the relevant interrupt bits Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 32/80] crypto: ccp - Disable interrupts early on unload Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 33/80] crypto: ccp - Change ISR handler method for a v3 CCP Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 34/80] crypto: ccp - Change ISR handler method for a v5 CCP Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 35/80] dm era: save spacemap metadata root after the pre-commit Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 36/80] dm rq: check blk_mq_register_dev() return value in dm_mq_init_request_queue() Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 37/80] dm thin: fix a memory leak when passing discard bio down Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 38/80] vfio/type1: Remove locked page accounting workqueue Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 39/80] iov_iter: dont revert iov buffer if csum error Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 40/80] IB/core: Fix sysfs registration error flow Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 41/80] IB/core: For multicast functions, verify that LIDs are multicast LIDs Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 42/80] IB/IPoIB: ibX: failed to create mcg debug file Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 43/80] IB/mlx4: Fix ib device initialization error flow Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 44/80] IB/mlx4: Reduce SRIOV multicast cleanup warning message to debug level Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 45/80] IB/hfi1: Prevent kernel QP post send hard lockups Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 46/80] perf auxtrace: Fix no_size logic in addr_filter__resolve_kernel_syms() Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 47/80] ext4: evict inline data when writing to memory map Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 48/80] orangefs: fix bounds check for listxattr Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 49/80] orangefs: clean up oversize xattr validation Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 50/80] orangefs: do not set getattr_time on orangefs_lookup Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 51/80] orangefs: do not check possibly stale size on truncate Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 52/80] fs/xattr.c: zero out memory copied to userspace in getxattr Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 53/80] ceph: fix memory leak in __ceph_setxattr() Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 54/80] fs/block_dev: always invalidate cleancache in invalidate_bdev() Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 55/80] mm: prevent potential recursive reclaim due to clearing PF_MEMALLOC Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 56/80] Fix match_prepath() Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 57/80] Set unicode flag on cifs echo request to avoid Mac error Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 58/80] SMB3: Work around mount failure when using SMB3 dialect to Macs Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 60/80] cifs: fix leak in FSCTL_ENUM_SNAPS response handling Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 61/80] cifs: fix CIFS_ENUMERATE_SNAPSHOTS oops Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 62/80] CIFS: fix oplock break deadlocks Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 63/80] cifs: fix CIFS_IOC_GET_MNT_INFO oops Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 65/80] padata: free correct variable Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 66/80] device-dax: fix cdev leak Greg Kroah-Hartman
2017-05-18 10:48 ` Greg Kroah-Hartman [this message]
2017-05-18 10:48 ` [PATCH 4.9 68/80] serial: samsung: Use right device for DMA-mapping calls Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 69/80] serial: omap: fix runtime-pm handling on unbind Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 70/80] serial: omap: suspend device on probe errors Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 71/80] tty: pty: Fix ldisc flush after userspace become aware of the data already Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 72/80] Bluetooth: Fix user channel for 32bit userspace on 64bit kernel Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 73/80] Bluetooth: hci_bcm: add missing tty-device sanity check Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 74/80] Bluetooth: hci_intel: " Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 75/80] ipmi: Fix kernel panic at ipmi_ssif_thread() Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 76/80] libnvdimm, region: fix flush hint detection crash Greg Kroah-Hartman
2017-05-18 10:48 ` [PATCH 4.9 77/80] libnvdimm, pmem: fix a NULL pointer BUG in nd_pmem_notify Greg Kroah-Hartman
2017-05-18 10:49 ` [PATCH 4.9 78/80] libnvdimm, pfn: fix npfns vs section alignment Greg Kroah-Hartman
2017-05-18 10:49 ` [PATCH 4.9 79/80] pstore: Fix flags to enable dumps on powerpc Greg Kroah-Hartman
2017-05-18 10:49 ` [PATCH 4.9 80/80] pstore: Shut down worker when unregistering Greg Kroah-Hartman
2017-05-18 17:32 ` [PATCH 4.9 00/80] 4.9.29-stable review Shuah Khan
2017-05-19 1:10 ` 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=20170518104836.993435308@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).