android_kernel_sony_sdm845/fs
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Filipe Manana 511f3b9722 btrfs: fix use-after-free on readahead extent after failure to create it
commit 83bc1560e02e25c6439341352024ebe8488f4fbd upstream.

If we fail to find suitable zones for a new readahead extent, we end up
leaving a stale pointer in the global readahead extents radix tree
(fs_info->reada_tree), which can trigger the following trace later on:

  [13367.696354] BUG: kernel NULL pointer dereference, address: 00000000000000b0
  [13367.696802] #PF: supervisor read access in kernel mode
  [13367.697249] #PF: error_code(0x0000) - not-present page
  [13367.697721] PGD 0 P4D 0
  [13367.698171] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC PTI
  [13367.698632] CPU: 6 PID: 851214 Comm: btrfs Tainted: G        W         5.9.0-rc6-btrfs-next-69 #1
  [13367.699100] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
  [13367.700069] RIP: 0010:__lock_acquire+0x20a/0x3970
  [13367.700562] Code: ff 1f 0f b7 c0 48 0f (...)
  [13367.701609] RSP: 0018:ffffb14448f57790 EFLAGS: 00010046
  [13367.702140] RAX: 0000000000000000 RBX: 29b935140c15e8cf RCX: 0000000000000000
  [13367.702698] RDX: 0000000000000002 RSI: ffffffffb3d66bd0 RDI: 0000000000000046
  [13367.703240] RBP: ffff8a52ba8ac040 R08: 00000c2866ad9288 R09: 0000000000000001
  [13367.703783] R10: 0000000000000001 R11: 00000000b66d9b53 R12: ffff8a52ba8ac9b0
  [13367.704330] R13: 0000000000000000 R14: ffff8a532b6333e8 R15: 0000000000000000
  [13367.704880] FS:  00007fe1df6b5700(0000) GS:ffff8a5376600000(0000) knlGS:0000000000000000
  [13367.705438] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  [13367.705995] CR2: 00000000000000b0 CR3: 000000022cca8004 CR4: 00000000003706e0
  [13367.706565] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
  [13367.707127] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
  [13367.707686] Call Trace:
  [13367.708246]  ? ___slab_alloc+0x395/0x740
  [13367.708820]  ? reada_add_block+0xae/0xee0 [btrfs]
  [13367.709383]  lock_acquire+0xb1/0x480
  [13367.709955]  ? reada_add_block+0xe0/0xee0 [btrfs]
  [13367.710537]  ? reada_add_block+0xae/0xee0 [btrfs]
  [13367.711097]  ? rcu_read_lock_sched_held+0x5d/0x90
  [13367.711659]  ? kmem_cache_alloc_trace+0x8d2/0x990
  [13367.712221]  ? lock_acquired+0x33b/0x470
  [13367.712784]  _raw_spin_lock+0x34/0x80
  [13367.713356]  ? reada_add_block+0xe0/0xee0 [btrfs]
  [13367.713966]  reada_add_block+0xe0/0xee0 [btrfs]
  [13367.714529]  ? btrfs_root_node+0x15/0x1f0 [btrfs]
  [13367.715077]  btrfs_reada_add+0x117/0x170 [btrfs]
  [13367.715620]  scrub_stripe+0x21e/0x10d0 [btrfs]
  [13367.716141]  ? kvm_sched_clock_read+0x5/0x10
  [13367.716657]  ? __lock_acquire+0x41e/0x3970
  [13367.717184]  ? scrub_chunk+0x60/0x140 [btrfs]
  [13367.717697]  ? find_held_lock+0x32/0x90
  [13367.718254]  ? scrub_chunk+0x60/0x140 [btrfs]
  [13367.718773]  ? lock_acquired+0x33b/0x470
  [13367.719278]  ? scrub_chunk+0xcd/0x140 [btrfs]
  [13367.719786]  scrub_chunk+0xcd/0x140 [btrfs]
  [13367.720291]  scrub_enumerate_chunks+0x270/0x5c0 [btrfs]
  [13367.720787]  ? finish_wait+0x90/0x90
  [13367.721281]  btrfs_scrub_dev+0x1ee/0x620 [btrfs]
  [13367.721762]  ? rcu_read_lock_any_held+0x8e/0xb0
  [13367.722235]  ? preempt_count_add+0x49/0xa0
  [13367.722710]  ? __sb_start_write+0x19b/0x290
  [13367.723192]  btrfs_ioctl+0x7f5/0x36f0 [btrfs]
  [13367.723660]  ? __fget_files+0x101/0x1d0
  [13367.724118]  ? find_held_lock+0x32/0x90
  [13367.724559]  ? __fget_files+0x101/0x1d0
  [13367.724982]  ? __x64_sys_ioctl+0x83/0xb0
  [13367.725399]  __x64_sys_ioctl+0x83/0xb0
  [13367.725802]  do_syscall_64+0x33/0x80
  [13367.726188]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
  [13367.726574] RIP: 0033:0x7fe1df7add87
  [13367.726948] Code: 00 00 00 48 8b 05 09 91 (...)
  [13367.727763] RSP: 002b:00007fe1df6b4d48 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
  [13367.728179] RAX: ffffffffffffffda RBX: 000055ce1fb596a0 RCX: 00007fe1df7add87
  [13367.728604] RDX: 000055ce1fb596a0 RSI: 00000000c400941b RDI: 0000000000000003
  [13367.729021] RBP: 0000000000000000 R08: 00007fe1df6b5700 R09: 0000000000000000
  [13367.729431] R10: 00007fe1df6b5700 R11: 0000000000000246 R12: 00007ffd922b07de
  [13367.729842] R13: 00007ffd922b07df R14: 00007fe1df6b4e40 R15: 0000000000802000
  [13367.730275] Modules linked in: btrfs blake2b_generic xor (...)
  [13367.732638] CR2: 00000000000000b0
  [13367.733166] ---[ end trace d298b6805556acd9 ]---

What happens is the following:

1) At reada_find_extent() we don't find any existing readahead extent for
   the metadata extent starting at logical address X;

2) So we proceed to create a new one. We then call btrfs_map_block() to get
   information about which stripes contain extent X;

3) After that we iterate over the stripes and create only one zone for the
   readahead extent - only one because reada_find_zone() returned NULL for
   all iterations except for one, either because a memory allocation failed
   or it couldn't find the block group of the extent (it may have just been
   deleted);

4) We then add the new readahead extent to the readahead extents radix
   tree at fs_info->reada_tree;

5) Then we iterate over each zone of the new readahead extent, and find
   that the device used for that zone no longer exists, because it was
   removed or it was the source device of a device replace operation.
   Since this left 'have_zone' set to 0, after finishing the loop we jump
   to the 'error' label, call kfree() on the new readahead extent and
   return without removing it from the radix tree at fs_info->reada_tree;

6) Any future call to reada_find_extent() for the logical address X will
   find the stale pointer in the readahead extents radix tree, increment
   its reference counter, which can trigger the use-after-free right
   away or return it to the caller reada_add_block() that results in the
   use-after-free of the example trace above.

So fix this by making sure we delete the readahead extent from the radix
tree if we fail to setup zones for it (when 'have_zone = 0').

Fixes: 3194502118 ("btrfs: reada: bypass adding extent when all zone failed")
CC: stable@vger.kernel.org # 4.9+
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-11-10 10:23:57 +01:00
..
9p 9p: Fix memory leak in v9fs_mount 2020-08-21 11:02:06 +02:00
adfs fs/adfs: super: fix use-after-free bug 2019-08-06 18:29:35 +02:00
affs affs: fix basic permission bits to actually work 2020-09-12 11:47:39 +02:00
afs afs: Fix large file support 2020-01-29 10:24:34 +01:00
autofs4 autofs: fix a leak in autofs_expire_indirect() 2019-12-21 10:40:46 +01:00
befs
bfs bfs: add sanity check at bfs_fill_super() 2018-12-01 09:44:19 +01:00
btrfs btrfs: fix use-after-free on readahead extent after failure to create it 2020-11-10 10:23:57 +01:00
cachefiles cachefiles: Fix race between read_waiter and read_copier involving op->to_do 2020-06-03 08:16:36 +02:00
ceph ceph: fix potential race in ceph_check_caps 2020-10-01 20:40:15 +02:00
cifs cifs: remove bogus debug code 2020-10-29 09:05:32 +01:00
coda coda: add error handling for fget 2019-08-06 18:29:38 +02:00
configfs configfs: fix config_item refcnt leak in configfs_rmdir() 2020-05-27 16:41:45 +02:00
cramfs Cramfs: fix abad comparison when wrap-arounds occur 2018-11-13 11:17:03 -08:00
crypto fscrypt: use EEXIST when file already uses different policy 2020-11-10 10:23:51 +01:00
debugfs debugfs: fix use-after-free on symlink traversal 2019-05-08 07:19:10 +02:00
devpts fs/devpts: always delete dcache dentry-s in dput() 2019-03-23 13:19:47 +01:00
dlm fs: dlm: fix configfs memory leak 2020-10-29 09:05:43 +01:00
ecryptfs ecryptfs: Fix up bad backport of fe2e082f5da5b4a0a92ae32978f81507ef37ec66 2020-03-11 07:53:06 +01:00
efivarfs efivarfs: Replace invalid slashes with exclamation marks in dentries. 2020-11-10 10:23:50 +01:00
efs
exofs fs/exofs: fix potential memory leak in mount option parsing 2018-11-27 16:09:38 +01:00
exportfs exportfs: fix 'passing zero to ERR_PTR()' warning 2020-01-29 10:24:03 +01:00
ext2 ext2: fix missing percpu_counter_inc 2020-08-21 11:02:08 +02:00
ext4 ext4: Detect already used quota file early 2020-11-10 10:23:54 +01:00
f2fs f2fs: fix to check segment boundary during SIT page readahead 2020-11-10 10:23:52 +01:00
fat fat: don't allow to mount if the FAT length == 0 2020-06-20 10:24:13 +02:00
freevxfs
fscache fscache: fix race between enablement and dropping of object 2018-12-17 09:38:34 +01:00
fuse fuse: fix page dereference after free 2020-11-10 10:23:51 +01:00
gfs2 gfs2: add validation checks for size of superblock 2020-11-10 10:23:55 +01:00
hfs fs/hfs/extent.c: fix array out of bounds read of array extent 2019-11-28 18:28:50 +01:00
hfsplus hfsplus: fix crash and filesystem corruption when deleting files 2020-04-24 07:58:59 +02:00
hostfs
hpfs
hugetlbfs hugetlb: use same fault hash key for shared and private mappings 2019-05-31 06:48:12 -07:00
isofs isofs: fix timestamps beyond 2027 2017-11-30 08:39:04 +00:00
jbd2 jbd2: abort journal if free a async write error metadata buffer 2020-09-03 11:21:19 +02:00
jffs2 jffs2: fix UAF problem 2020-08-26 10:29:05 +02:00
jfs jfs: fix bogus variable self-initialization 2020-01-29 10:24:19 +01:00
kernfs kernfs: Fix range checks in kernfs_get_target_path 2019-11-25 09:52:23 +01:00
lockd lockd: fix access beyond unterminated strings in prints 2018-11-13 11:17:02 -08:00
logfs
minix fs/minix: reject too-large maximum file size 2020-08-21 11:02:06 +02:00
ncpfs ncpfs: fix build warning of strncpy 2019-03-13 14:04:52 -07:00
nfs NFS: fix nfs_path in case of a rename retry 2020-11-10 10:23:56 +01:00
nfs_common lockd: fix "list_add double add" caused by legacy signal interface 2018-02-03 17:05:38 +01:00
nfsd nfsd: Fix svc_xprt refcnt leak when setup callback client failed 2020-06-30 15:38:22 -04:00
nilfs2 nilfs2: fix null pointer dereference at nilfs_segctor_do_construct() 2020-06-20 10:24:09 +02:00
nls
notify fanotify: fix handling of events on child sub-directory 2019-02-06 17:33:30 +01:00
ntfs ntfs: add check for mft record size in superblock 2020-10-29 09:05:43 +01:00
ocfs2 ocfs2: change slot number type s16 to u16 2020-08-21 11:02:08 +02:00
omfs
openpromfs
orangefs help_next should increase position index 2020-02-28 15:42:43 +01:00
overlayfs ovl: initialize error in ovl_copy_xattr 2020-06-20 10:24:11 +02:00
proc proc: Use new_inode not new_inode_pseudo 2020-06-20 10:24:11 +02:00
pstore pstore/ram: Write new dumps to start of recycled zones 2020-01-12 11:24:20 +01:00
qnx4
qnx6
quota quota: clear padding in v2r1_mem2diskdqb() 2020-10-29 09:05:36 +01:00
ramfs
reiserfs reiserfs: Fix memory leak in reiserfs_parse_options() 2020-10-29 09:05:45 +01:00
romfs romfs: fix uninitialized memory leak in romfs_dev_read() 2020-08-26 10:29:03 +02:00
squashfs Squashfs: Compute expected length from inode size rather than block length 2018-09-05 09:20:03 +02:00
sysfs scsi: sysfs: Introduce sysfs_{un,}break_active_protection() 2018-09-05 09:20:10 +02:00
sysv sysv: return 'err' instead of 0 in __sysv_write_inode 2018-12-17 09:38:32 +01:00
tracefs
ubifs ubifs: Fix out-of-bounds memory access caused by abnormal value of node_len 2020-10-01 20:40:11 +02:00
udf udf: Avoid accessing uninitialized data on failed inode read 2020-10-29 09:05:44 +01:00
ufs fs/ufs: avoid potential u32 multiplication overflow 2020-08-21 11:02:11 +02:00
xfs xfs: fix realtime bitmap/summary file truncation when growing rt volume 2020-11-10 10:23:52 +01:00
aio.c aio: fix spectre gadget in lookup_ioctx 2018-12-21 14:11:31 +01:00
anon_inodes.c
attr.c
bad_inode.c
binfmt_aout.c
binfmt_elf.c fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info() 2020-06-03 08:16:42 +02:00
binfmt_elf_fdpic.c
binfmt_em86.c
binfmt_flat.c fs/binfmt_flat.c: make load_flat_shared_library() work 2019-07-10 09:55:38 +02:00
binfmt_misc.c fs/binfmt_misc.c: do not allow offset overflow 2018-06-26 08:08:09 +08:00
binfmt_script.c exec: load_script: Do not exec truncated interpreter path 2019-11-06 12:18:04 +01:00
block_dev.c bdev: Reduce time holding bd_mutex in sync in blkdev_close() 2020-10-01 20:40:12 +02:00
buffer.c fs: Don't invalidate page buffers in block_write_full_page() 2020-11-10 10:23:56 +01:00
char_dev.c chardev: add helper function to register char devs with a struct device 2020-05-20 08:15:32 +02:00
compat.c
compat_binfmt_elf.c binfmt_elf: compat: avoid unused function warning 2018-02-25 11:05:55 +01:00
compat_ioctl.c media: dvb_frontend: Add compat_ioctl callback 2020-06-30 15:38:35 -04:00
coredump.c coredump: Ensure proper size of sparse core files 2017-07-05 14:40:26 +02:00
dax.c fs/dax.c: fix inefficiency in dax_writeback_mapping_range() 2018-02-28 10:18:33 +01:00
dcache.c Hang/soft lockup in d_invalidate with simultaneous calls 2019-03-27 14:13:04 +09:00
dcookies.c
direct-io.c direct-io: allow direct writes to empty inodes 2019-03-05 17:57:05 +01:00
drop_caches.c fs/drop_caches.c: avoid softlockups in drop_pagecache_sb() 2019-03-13 14:04:58 -07:00
eventfd.c
eventpoll.c ep_create_wakeup_source(): dentry name can change under you... 2020-10-14 09:48:13 +02:00
exec.c exec: Move would_dump into flush_old_exec 2020-05-20 08:15:41 +02:00
fcntl.c fs/fcntl: f_setown, avoid undefined behaviour 2018-01-31 12:55:52 +01:00
fhandle.c
file.c fix multiplication overflow in copy_fdtable() 2020-05-27 16:41:40 +02:00
file_table.c
filesystems.c
fs-writeback.c writeback: Fix sync livelock due to b_dirty_time processing 2020-09-03 11:21:21 +02:00
fs_pin.c
fs_struct.c
inode.c futex: Fix inode life-time issue 2020-04-02 17:20:27 +02:00
internal.h xfs: evict all inodes involved with log redo item 2017-09-20 08:20:01 +02:00
ioctl.c
iomap.c iomap: fix integer truncation issues in the zeroing and dirtying helpers 2017-09-20 08:19:59 +02:00
Kconfig
Kconfig.binfmt
libfs.c libfs: fix infoleak in simple_attr_read() 2020-04-02 17:20:38 +02:00
locks.c locks: print unsigned ino in /proc/locks 2020-01-12 11:24:13 +01:00
Makefile
mbcache.c mbcache: initialize entry->e_referenced in mb_cache_entry_create() 2018-02-22 15:43:48 +01:00
mount.h mnt: In propgate_umount handle visiting mounts in any order 2017-07-21 07:42:22 +02:00
mpage.c fs/mpage.c: fix mpage_writepage() for pages with buffers 2017-10-18 09:35:39 +02:00
namei.c namei: only return -ECHILD from follow_dotdot_rcu() 2020-03-11 07:53:07 +01:00
namespace.c fs/namespace.c: fix mountpoint reference counter race 2020-05-02 17:23:10 +02:00
no-block.c
nsfs.c nsfs: mark dentry with DCACHE_RCUACCESS 2018-02-17 13:21:15 +01:00
open.c cifs_atomic_open(): fix double-put on late allocation failure 2020-03-20 09:07:44 +01:00
pipe.c fs: prevent page refcount overflow in pipe_buf_get 2019-06-11 12:22:45 +02:00
pnode.c propagate_one(): mnt_set_mountpoint() needs mount_lock 2020-05-02 17:23:20 +02:00
pnode.h mnt: Tuck mounts under others instead of creating shadow/side mounts. 2017-03-15 10:02:43 +08:00
posix_acl.c tmpfs: clear S_ISGID when setting posix ACLs 2017-01-26 08:24:37 +01:00
proc_namespace.c
read_write.c fs: stream_open - opener for stream-like files so that read and write can run simultaneously without deadlock 2019-06-11 12:22:49 +02:00
readdir.c filldir[64]: remove WARN_ON_ONCE() for bad directory entries 2020-01-04 13:41:06 +01:00
select.c
seq_file.c
signalfd.c
splice.c fs: prevent page refcount overflow in pipe_buf_get 2019-06-11 12:22:45 +02:00
stack.c
stat.c ufs: restore maintaining ->i_blocks 2017-06-14 15:06:01 +02:00
statfs.c
super.c fs: don't scan the inode cache before SB_BORN is set 2019-02-06 17:33:29 +01:00
sync.c
timerfd.c timerfd: Protect the might cancel mechanism proper 2017-05-08 07:47:54 +02:00
userfaultfd.c userfaultfd_release: always remove uffd flags and clear vm_userfaultfd_ctx 2019-09-06 10:19:37 +02:00
utimes.c
xattr.c xattr: break delegations in {set,remove}xattr 2020-08-21 11:01:55 +02:00