android_kernel_oneplus_msm8998/fs/btrfs
David Sterba cc8c67cadc btrfs: use correct types for page indices in btrfs_page_exists_in_range
commit cc2b702c52094b637a351d7491ac5200331d0445 upstream.

Variables start_idx and end_idx are supposed to hold a page index
derived from the file offsets. The int type is not the right one though,
offsets larger than 1 << 44 will get silently trimmed off the high bits.
(1 << 44 is 16TiB)

What can go wrong, if start is below the boundary and end gets trimmed:
- if there's a page after start, we'll find it (radix_tree_gang_lookup_slot)
- the final check "if (page->index <= end_idx)" will unexpectedly fail

The function will return false, ie. "there's no page in the range",
although there is at least one.

btrfs_page_exists_in_range is used to prevent races in:

* in hole punching, where we make sure there are not pages in the
  truncated range, otherwise we'll wait for them to finish and redo
  truncation, but we're going to replace the pages with holes anyway so
  the only problem is the intermediate state

* lock_extent_direct: we want to make sure there are no pages before we
  lock and start DIO, to prevent stale data reads

For practical occurence of the bug, there are several constaints.  The
file must be quite large, the affected range must cross the 16TiB
boundary and the internal state of the file pages and pending operations
must match.  Also, we must not have started any ordered data in the
range, otherwise we don't even reach the buggy function check.

DIO locking tries hard in several places to avoid deadlocks with
buffered IO and avoids waiting for ranges. The worst consequence seems
to be stale data read.

CC: Liu Bo <bo.li.liu@oracle.com>
Fixes: fc4adbff82 ("btrfs: Drop EXTENT_UPTODATE check in hole punching and direct locking")
Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-14 13:16:24 +02:00
..
tests Btrfs: tests: checking for NULL instead of IS_ERR() 2015-11-25 05:19:50 -08:00
acl.c posix_acl: Clear SGID bit when setting file permissions 2016-10-31 04:13:58 -06:00
async-thread.c btrfs: limit async_work allocation and worker func duration 2017-01-06 11:16:06 +01:00
async-thread.h btrfs: limit async_work allocation and worker func duration 2017-01-06 11:16:06 +01:00
backref.c Btrfs: fix hang on extent buffer lock caused by the inode_paths ioctl 2016-02-25 12:01:15 -08:00
backref.h
btrfs_inode.h Btrfs: Direct I/O: Fix space accounting 2015-09-21 13:47:55 -07:00
check-integrity.c Merge branch 'cleanups/for-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus-4.4 2015-10-21 18:21:40 -07:00
check-integrity.h
compression.c btrfs: assign error values to the correct bio structs 2016-10-22 12:26:54 +02:00
compression.h
ctree.c btrfs: account for non-CoW'd blocks in btrfs_abort_transaction 2016-07-27 09:47:33 -07:00
ctree.h btrfs: store and load values of stripes_min/stripes_max in balance status item 2017-01-06 11:16:06 +01:00
delayed-inode.c btrfs: limit async_work allocation and worker func duration 2017-01-06 11:16:06 +01:00
delayed-inode.h btrfs: properly set the termination value of ctx->pos in readdir 2016-02-25 12:01:15 -08:00
delayed-ref.c btrfs: qgroup: Fix a race in delayed_ref which leads to abort trans 2015-10-26 19:44:39 -07:00
delayed-ref.h btrfs: qgroup: Fix a race in delayed_ref which leads to abort trans 2015-10-26 19:44:39 -07:00
dev-replace.c Merge branch 'fix/waitqueue-barriers' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus-4.4 2015-10-12 16:24:40 -07:00
dev-replace.h
dir-item.c
disk-io.c btrfs: properly track when rescan worker is running 2016-09-07 08:32:43 +02:00
disk-io.h Btrfs: add btrfs_read_dev_one_super() to read one specific SB 2015-10-01 17:29:38 +02:00
export.c BTRFS: support NFSv2 export 2015-10-06 06:55:23 -07:00
export.h
extent-tree.c btrfs: fix error handling when run_delayed_extent_op fails 2017-01-19 20:17:21 +01:00
extent-tree.h
extent_io.c Btrfs: fix memory leak in reading btree blocks 2017-01-06 11:16:10 +01:00
extent_io.h btrfs: qgroup: Introduce btrfs_qgroup_reserve_data function 2015-10-21 18:37:45 -07:00
extent_map.c
extent_map.h
file-item.c
file.c fs: add i_blocksize() 2017-06-14 13:16:24 +02:00
free-space-cache.c Merge branch 'for-linus-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs 2015-12-18 15:35:08 -08:00
free-space-cache.h Btrfs: keep track of largest extent in bitmaps 2015-10-21 18:55:40 -07:00
hash.c
hash.h
inode-item.c Btrfs: consolidate btrfs_error() to btrfs_std_error() 2015-09-29 16:30:00 +02:00
inode-map.c Btrfs: Initialize btrfs_root->highest_objectid when loading tree root and subvolume roots 2016-03-03 15:07:12 -08:00
inode-map.h Btrfs: Initialize btrfs_root->highest_objectid when loading tree root and subvolume roots 2016-03-03 15:07:12 -08:00
inode.c btrfs: use correct types for page indices in btrfs_page_exists_in_range 2017-06-14 13:16:24 +02:00
ioctl.c btrfs: make file clone aware of fatal signals 2017-01-06 11:16:11 +01:00
Kconfig
locking.c btrfs: comment the rest of implicit barriers before waitqueue_active 2015-10-10 18:42:00 +02:00
locking.h
lzo.c
Makefile
math.h
ordered-data.c Btrfs: change how we wait for pending ordered extents 2015-10-21 18:51:40 -07:00
ordered-data.h Btrfs: change how we wait for pending ordered extents 2015-10-21 18:51:40 -07:00
orphan.c
print-tree.c
print-tree.h
props.c btrfs: cleanup iterating over prop_handlers array 2015-10-21 18:28:48 +02:00
props.h
qgroup.c Btrfs: fix qgroup rescan worker initialization 2017-01-06 11:16:06 +01:00
qgroup.h btrfs: waiting on qgroup rescan should not always be interruptible 2016-09-07 08:32:43 +02:00
raid56.c btrfs: comment waitqueue_active implied by locks 2015-10-10 18:35:10 +02:00
raid56.h Btrfs: add RAID 5/6 BTRFS_RBIO_REBUILD_MISSING operation 2015-08-09 07:34:26 -07:00
rcu-string.h
reada.c btrfs: reada: Fix returned errno code 2015-10-21 18:29:50 +02:00
relocation.c Btrfs: don't leak reloc root nodes on error 2017-01-06 11:16:10 +01:00
root-tree.c Btrfs: fix loading of orphan roots leading to BUG_ON 2016-03-09 15:34:53 -08:00
scrub.c Btrfs: fix scrub preventing unused block groups from being deleted 2015-11-25 05:22:08 -08:00
send.c Btrfs: send, don't BUG_ON() when an empty symlink is found 2016-03-03 15:07:11 -08:00
send.h
struct-funcs.c
super.c btrfs: account for non-CoW'd blocks in btrfs_abort_transaction 2016-07-27 09:47:33 -07:00
sysfs.c Btrfs: rename super_kobj to fsid_kobj 2015-09-29 16:29:59 +02:00
sysfs.h Btrfs: rename btrfs_kobj_rm_device to btrfs_sysfs_rm_device_link 2015-09-29 16:29:59 +02:00
transaction.c Btrfs: fix unprotected list move from unused_bgs to deleted_bgs list 2015-12-10 11:22:38 +00:00
transaction.h btrfs: account for non-CoW'd blocks in btrfs_abort_transaction 2016-07-27 09:47:33 -07:00
tree-defrag.c Btrfs: cleanup: remove unnecessary check before btrfs_free_path is called 2015-08-31 11:46:41 -07:00
tree-log.c Btrfs: fix tree search logic when replaying directory entry deletes 2017-01-06 11:16:06 +01:00
tree-log.h
ulist.c
ulist.h
uuid-tree.c
volumes.c btrfs: initialize the seq counter in struct btrfs_device 2016-03-03 15:07:12 -08:00
volumes.h btrfs: fix clashing number of the enhanced balance usage filter 2015-11-25 05:19:50 -08:00
xattr.c Btrfs: fix race when listing an inode's xattrs 2015-11-09 18:34:40 +00:00
xattr.h
zlib.c