linux/fs/ext4
Eric Biggers ec772f0130 ext4: fix race conditions in ->d_compare() and ->d_hash()
Since ->d_compare() and ->d_hash() can be called in RCU-walk mode,
->d_parent and ->d_inode can be concurrently modified, and in
particular, ->d_inode may be changed to NULL.  For ext4_d_hash() this
resulted in a reproducible NULL dereference if a lookup is done in a
directory being deleted, e.g. with:

	int main()
	{
		if (fork()) {
			for (;;) {
				mkdir("subdir", 0700);
				rmdir("subdir");
			}
		} else {
			for (;;)
				access("subdir/file", 0);
		}
	}

... or by running the 't_encrypted_d_revalidate' program from xfstests.
Both repros work in any directory on a filesystem with the encoding
feature, even if the directory doesn't actually have the casefold flag.

I couldn't reproduce a crash in ext4_d_compare(), but it appears that a
similar crash is possible there.

Fix these bugs by reading ->d_parent and ->d_inode using READ_ONCE() and
falling back to the case sensitive behavior if the inode is NULL.

Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Fixes: b886ee3e77 ("ext4: Support case-insensitive file name lookups")
Cc: <stable@vger.kernel.org> # v5.2+
Signed-off-by: Eric Biggers <ebiggers@google.com>
Link: https://lore.kernel.org/r/20200124041234.159740-1-ebiggers@kernel.org
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2020-01-24 22:35:03 -05:00
..
acl.c ext4: compare old and new mode before setting update_mode flag 2018-12-10 00:22:38 -05:00
acl.h ext4: fix up remaining files with SPDX cleanups 2017-12-17 22:00:59 -05:00
balloc.c ext4: simulate various I/O and checksum errors when reading metadata 2019-12-26 11:28:31 -05:00
bitmap.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
block_validity.c ext4: use RCU API in debug_print_tree 2019-12-15 21:41:04 -05:00
dir.c ext4: fix race conditions in ->d_compare() and ->d_hash() 2020-01-24 22:35:03 -05:00
ext4_extents.h ext4: make some functions static in extents.c 2020-01-17 16:24:54 -05:00
ext4_jbd2.c ext4: uninline ext4_inode_journal_mode() 2020-01-17 16:24:52 -05:00
ext4_jbd2.h ext4: uninline ext4_inode_journal_mode() 2020-01-17 16:24:52 -05:00
ext4.h ext4: drop ext4_kvmalloc() 2020-01-17 16:24:55 -05:00
extents_status.c ext4: use percpu_counters for extent_status cache hits/misses 2019-08-28 11:19:23 -04:00
extents_status.h ext4: use percpu_counters for extent_status cache hits/misses 2019-08-28 11:19:23 -04:00
extents.c ext4: fix extent_status fragmentation for plain files 2020-01-23 12:02:15 -05:00
file.c ext4: Optimize ext4 DIO overwrites 2019-12-26 11:57:18 -05:00
fsmap.c ext4: fix miscellaneous sparse warnings 2019-05-12 04:49:47 -04:00
fsmap.h ext4: fix up remaining files with SPDX cleanups 2017-12-17 22:00:59 -05:00
fsync.c ext4: update ext4_sync_file() to not use __generic_file_fsync() 2019-11-05 11:31:40 -05:00
hash.c ext4: fix kernel oops caused by spurious casefold flag 2019-09-03 01:43:17 -04:00
ialloc.c ext4: simulate various I/O and checksum errors when reading metadata 2019-12-26 11:28:31 -05:00
indirect.c ext4: remove ext4_{ind,ext}_calc_metadata_amount() 2020-01-17 16:24:54 -05:00
inline.c ext4: save the error code which triggered an ext4_error() in the superblock 2019-12-26 11:28:23 -05:00
inode-test.c fs/ext4/inode-test: Fix inode test on 32 bit platforms. 2019-12-09 11:15:44 -07:00
inode.c ext4: remove unused macro MPAGE_DA_EXTENT_TAIL 2020-01-17 16:24:55 -05:00
ioctl.c ext4: Add EXT4_IOC_FSGETXATTR/EXT4_IOC_FSSETXATTR to compat_ioctl 2020-01-17 16:24:55 -05:00
Kconfig ext4: remove unnecessary selections from EXT3_FS 2020-01-17 16:24:53 -05:00
Makefile ext4: add kunit test for decoding extended timestamps 2019-10-23 10:28:23 -06:00
mballoc.c ext4: save the error code which triggered an ext4_error() in the superblock 2019-12-26 11:28:23 -05:00
mballoc.h ext4: fix up remaining files with SPDX cleanups 2017-12-17 22:00:59 -05:00
migrate.c ext4: Reserve revoke credits for freed blocks 2019-11-05 16:00:49 -05:00
mmp.c ext4: save the error code which triggered an ext4_error() in the superblock 2019-12-26 11:28:23 -05:00
move_extent.c ext4: use jbd2_inode dirty range scoping 2019-06-20 17:26:26 -04:00
namei.c ext4: remove unnecessary ifdefs in htree_dirblock_to_tree() 2020-01-17 16:24:52 -05:00
page-io.c ext4: fix deadlock allocating crypto bounce page from mempool 2020-01-17 16:24:54 -05:00
readpage.c ext4: remove unneeded check for error allocating bio_post_read_ctx 2020-01-17 16:24:54 -05:00
resize.c ext4: drop ext4_kvmalloc() 2020-01-17 16:24:55 -05:00
super.c ext4: make dioread_nolock the default 2020-01-24 21:23:12 -05:00
symlink.c ext4: switch to fscrypt_get_symlink() 2018-01-11 22:10:40 -05:00
sysfs.c ext4: export information about first/last errors via /sys/fs/ext4/<dev> 2019-12-26 11:29:10 -05:00
truncate.h ext4: handle layout changes to pinned DAX mappings 2018-07-29 17:00:22 -04:00
verity.c ext4: add basic fs-verity support 2019-08-12 19:33:50 -07:00
xattr_security.c ext4: use XATTR_CREATE in ext4_initxattrs() 2018-05-10 11:52:14 -04:00
xattr_trusted.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xattr_user.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xattr.c ext4: drop ext4_kvmalloc() 2020-01-17 16:24:55 -05:00
xattr.h ext4: add extra checks to ext4_xattr_block_get() 2018-03-30 20:04:11 -04:00