linux/fs/ext4
Eric Biggers 69f8a7991f ext4: fix race between writepages and enabling EXT4_EXTENTS_FL
commit cb85f4d23f upstream.

If EXT4_EXTENTS_FL is set on an inode while ext4_writepages() is running
on it, the following warning in ext4_add_complete_io() can be hit:

WARNING: CPU: 1 PID: 0 at fs/ext4/page-io.c:234 ext4_put_io_end_defer+0xf0/0x120

Here's a minimal reproducer (not 100% reliable) (root isn't required):

        while true; do
                sync
        done &
        while true; do
                rm -f file
                touch file
                chattr -e file
                echo X >> file
                chattr +e file
        done

The problem is that in ext4_writepages(), ext4_should_dioread_nolock()
(which only returns true on extent-based files) is checked once to set
the number of reserved journal credits, and also again later to select
the flags for ext4_map_blocks() and copy the reserved journal handle to
ext4_io_end::handle.  But if EXT4_EXTENTS_FL is being concurrently set,
the first check can see dioread_nolock disabled while the later one can
see it enabled, causing the reserved handle to unexpectedly be NULL.

Since changing EXT4_EXTENTS_FL is uncommon, and there may be other races
related to doing so as well, fix this by synchronizing changing
EXT4_EXTENTS_FL with ext4_writepages() via the existing
s_writepages_rwsem (previously called s_journal_flag_rwsem).

This was originally reported by syzbot without a reproducer at
https://syzkaller.appspot.com/bug?extid=2202a584a00fffd19fbf,
but now that dioread_nolock is the default I also started seeing this
when running syzkaller locally.

Link: https://lore.kernel.org/r/20200219183047.47417-3-ebiggers@kernel.org
Reported-by: syzbot+2202a584a00fffd19fbf@syzkaller.appspotmail.com
Fixes: 6b523df4fb ("ext4: use transaction reservation for extent conversion in ext4_end_io")
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
Cc: stable@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2020-02-28 17:23:39 +01: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: fix potential race between online resizing and write operations 2020-02-28 17:23:38 +01: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: add cond_resched() to ext4_protect_reserved_inode 2020-02-19 19:54:03 +01:00
dir.c ext4: fix checksum errors with indexed dirs 2020-02-19 19:54:03 +01:00
ext4.h ext4: fix race between writepages and enabling EXT4_EXTENTS_FL 2020-02-28 17:23:39 +01:00
ext4_extents.h ext4: adjust reserved cluster count when removing extents 2018-10-01 14:25:08 -04:00
ext4_jbd2.c ext4: Reserve revoke credits for freed blocks 2019-11-05 16:00:49 -05:00
ext4_jbd2.h ext4: Reserve revoke credits for freed blocks 2019-11-05 16:00:49 -05:00
extents.c Merge branch 'mb/dio' into master 2019-11-05 16:21:09 -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
file.c ext4: fix ext4_dax_read/write inode locking sequence for IOCB_NOWAIT 2020-02-24 08:38:01 +01: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: fix potential race between s_flex_groups online resizing and access 2020-02-28 17:23:38 +01:00
indirect.c ext4: Reserve revoke credits for freed blocks 2019-11-05 16:00:49 -05:00
inline.c ext4: set error return correctly when ext4_htree_store_dirent fails 2019-08-12 14:29:38 -04: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: rename s_journal_flag_rwsem to s_writepages_rwsem 2020-02-28 17:23:39 +01:00
ioctl.c fs: compat_ioctl: move FITRIM emulation into file systems 2019-10-23 17:23:46 +02:00
Kconfig ext4: add kunit test for decoding extended timestamps 2019-10-23 10:28:23 -06:00
Makefile ext4: add kunit test for decoding extended timestamps 2019-10-23 10:28:23 -06:00
mballoc.c ext4: fix potential race between s_flex_groups online resizing and access 2020-02-28 17:23:38 +01:00
mballoc.h ext4: fix up remaining files with SPDX cleanups 2017-12-17 22:00:59 -05:00
migrate.c ext4: fix race between writepages and enabling EXT4_EXTENTS_FL 2020-02-28 17:23:39 +01:00
mmp.c ext4: don't assume that mmp_nodename/bdevname have NUL 2020-02-19 19:54:02 +01:00
move_extent.c ext4: use jbd2_inode dirty range scoping 2019-06-20 17:26:26 -04:00
namei.c ext4: add cond_resched() to __ext4_find_entry() 2020-02-28 17:23:38 +01:00
page-io.c ext4: fix deadlock allocating crypto bounce page from mempool 2020-02-11 04:37:02 -08:00
readpage.c ext4: fix deadlock allocating bio_post_read_ctx from mempool 2020-02-24 08:38:06 +01:00
resize.c ext4: fix potential race between s_flex_groups online resizing and access 2020-02-28 17:23:38 +01:00
super.c ext4: rename s_journal_flag_rwsem to s_writepages_rwsem 2020-02-28 17:23:39 +01:00
symlink.c ext4: switch to fscrypt_get_symlink() 2018-01-11 22:10:40 -05:00
sysfs.c ext4: add basic fs-verity support 2019-08-12 19:33:50 -07: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.c ext4: Reserve revoke credits for freed blocks 2019-11-05 16:00:49 -05:00
xattr.h ext4: add extra checks to ext4_xattr_block_get() 2018-03-30 20:04:11 -04: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