linux/fs/btrfs
Qu Wenruo 6e9770de02 btrfs: avoid NULL pointer dereference if no valid csum tree
[ Upstream commit f95d186255 ]

[BUG]
When trying read-only scrub on a btrfs with rescue=idatacsums mount
option, it will crash with the following call trace:

  BUG: kernel NULL pointer dereference, address: 0000000000000208
  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  CPU: 1 UID: 0 PID: 835 Comm: btrfs Tainted: G           O        6.15.0-rc3-custom+ #236 PREEMPT(full)
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS unknown 02/02/2022
  RIP: 0010:btrfs_lookup_csums_bitmap+0x49/0x480 [btrfs]
  Call Trace:
   <TASK>
   scrub_find_fill_first_stripe+0x35b/0x3d0 [btrfs]
   scrub_simple_mirror+0x175/0x290 [btrfs]
   scrub_stripe+0x5f7/0x6f0 [btrfs]
   scrub_chunk+0x9a/0x150 [btrfs]
   scrub_enumerate_chunks+0x333/0x660 [btrfs]
   btrfs_scrub_dev+0x23e/0x600 [btrfs]
   btrfs_ioctl+0x1dcf/0x2f80 [btrfs]
   __x64_sys_ioctl+0x97/0xc0
   do_syscall_64+0x4f/0x120
   entry_SYSCALL_64_after_hwframe+0x76/0x7e

[CAUSE]
Mount option "rescue=idatacsums" will completely skip loading the csum
tree, so that any data read will not find any data csum thus we will
ignore data checksum verification.

Normally call sites utilizing csum tree will check the fs state flag
NO_DATA_CSUMS bit, but unfortunately scrub does not check that bit at all.

This results in scrub to call btrfs_search_slot() on a NULL pointer
and triggered above crash.

[FIX]
Check both extent and csum tree root before doing any tree search.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2025-05-29 11:03:12 +02:00
..
tests btrfs: tests: fix chunk map leak after failure to add it to the tree 2025-04-20 10:15:47 +02:00
accessors.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
accessors.h move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
acl.c btrfs: remove unused included headers 2024-03-04 16:24:46 +01:00
acl.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
async-thread.c btrfs: remove unused included headers 2024-03-04 16:24:46 +01:00
async-thread.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
backref.c btrfs: drop the backref cache during relocation if we commit 2024-10-01 19:10:26 +02:00
backref.h btrfs: uninline some static inline helpers from backref.h 2024-03-04 16:24:53 +01:00
bio.c btrfs: handle bio_split() errors 2025-01-09 13:33:44 +01:00
bio.h btrfs: fix error propagation of split bios 2024-10-23 18:17:43 +02:00
block-group.c btrfs: get zone unusable bytes while holding lock at btrfs_reclaim_bgs_work() 2025-05-29 11:02:12 +02:00
block-group.h btrfs: constify more pointer parameters 2024-09-10 16:51:22 +02:00
block-rsv.c btrfs: constify more pointer parameters 2024-09-10 16:51:22 +02:00
block-rsv.h btrfs: constify more pointer parameters 2024-09-10 16:51:22 +02:00
btrfs_inode.h btrfs: change btrfs_encoded_read() so that reading of extent is done by caller 2024-12-09 10:40:55 +01:00
compression.c btrfs: compression: adjust cb->compressed_folios allocation type 2025-05-29 11:03:12 +02:00
compression.h btrfs: convert btrfs_decompress() to take a folio 2024-09-10 16:51:21 +02:00
ctree.c btrfs: fix use-after-free when COWing tree bock and tracing is enabled 2025-01-02 10:34:24 +01:00
ctree.h btrfs: fix improper generation check in snapshot delete 2024-12-27 14:02:14 +01:00
defrag.c btrfs: fix defrag not merging contiguous extents due to merged extent maps 2024-10-31 16:46:41 +01:00
defrag.h btrfs: drop transaction parameter from btrfs_add_inode_defrag() 2024-09-10 16:51:19 +02:00
delalloc-space.c btrfs: constify pointer parameters where applicable 2024-07-11 15:33:22 +02:00
delalloc-space.h btrfs: constify pointer parameters where applicable 2024-07-11 15:33:22 +02:00
delayed-inode.c btrfs: pass a btrfs_inode to btrfs_readdir_get_delayed_items() 2024-07-11 15:33:28 +02:00
delayed-inode.h btrfs: pass a btrfs_inode to btrfs_readdir_get_delayed_items() 2024-07-11 15:33:28 +02:00
delayed-ref.c btrfs: fix incorrect comparison for delayed refs 2024-11-14 16:11:02 +01:00
delayed-ref.h btrfs: use sector numbers as keys for the dirty extents xarray 2024-10-11 18:33:35 +02:00
dev-replace.c btrfs: don't take dev_replace rwsem on task already holding it 2024-12-14 20:03:36 +01:00
dev-replace.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
dir-item.c btrfs: fix passing 0 to ERR_PTR in btrfs_search_dir_index_item() 2024-10-22 16:10:55 +02:00
dir-item.h btrfs: constify pointer parameters where applicable 2024-07-11 15:33:22 +02:00
direct-io.c btrfs: do not hold the extent lock for entire read 2024-09-10 16:51:20 +02:00
direct-io.h btrfs: move the direct IO code into its own file 2024-07-11 15:33:29 +02:00
discard.c btrfs: make btrfs_discard_workfn() block_group ref explicit 2025-05-29 11:02:12 +02:00
discard.h btrfs: unexport btrfs_run_discard_work and make it static 2023-06-19 13:59:25 +02:00
disk-io.c btrfs: fix non-empty delayed iputs list on unmount due to async workers 2025-05-29 11:02:12 +02:00
disk-io.h btrfs: drop unused parameter options from open_ctree() 2024-12-14 20:04:12 +01:00
export.c btrfs: remove super block argument from btrfs_iget() 2024-07-11 15:33:25 +02:00
export.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
extent-io-tree.c btrfs: introduce EXTENT_DIO_LOCKED 2024-09-10 16:51:20 +02:00
extent-io-tree.h btrfs: introduce EXTENT_DIO_LOCKED 2024-09-10 16:51:20 +02:00
extent-tree.c btrfs: harden block_group::bg_list against list_del() races 2025-04-20 10:15:21 +02:00
extent-tree.h btrfs: do not BUG_ON() when freeing tree block after error 2024-07-11 15:33:26 +02:00
extent_io.c btrfs: avoid linker error in btrfs_find_create_tree_block() 2025-05-29 11:02:12 +02:00
extent_io.h btrfs: handle empty eb->folios in num_extent_folios() 2025-05-29 11:03:12 +02:00
extent_map.c btrfs: fix extent map merging not happening for adjacent extents 2024-10-31 16:45:16 +01:00
extent_map.h btrfs: do not directly include rwlock_types.h 2024-07-11 15:33:22 +02:00
fiemap.c btrfs: initialize last_extent_end to fix -Wmaybe-uninitialized warning in extent_fiemap() 2024-08-26 16:58:13 +02:00
fiemap.h btrfs: move fiemap code into its own file 2024-07-11 15:33:20 +02:00
file-item.c btrfs: constify more pointer parameters 2024-09-10 16:51:22 +02:00
file-item.h btrfs: constify more pointer parameters 2024-09-10 16:51:22 +02:00
file.c btrfs: avoid page_lockend underflow in btrfs_punch_hole_lock_range() 2025-05-02 07:59:00 +02:00
file.h btrfs: move the direct IO code into its own file 2024-07-11 15:33:29 +02:00
free-space-cache.c btrfs: add cancellation points to trim loops 2024-10-07 23:21:56 +02:00
free-space-cache.h btrfs: add cancellation points to trim loops 2024-10-07 23:21:56 +02:00
free-space-tree.c btrfs: do not BUG_ON() when freeing tree block after error 2024-07-11 15:33:26 +02:00
free-space-tree.h btrfs: add forward declarations and headers, part 2 2024-03-04 16:24:49 +01:00
fs.c btrfs: sysfs: update fs features directory asynchronously 2023-02-13 17:50:35 +01:00
fs.h btrfs: add back warning for mount option commit values exceeding 300 2025-05-22 14:29:45 +02:00
inode-item.c btrfs: constify more pointer parameters 2024-09-10 16:51:22 +02:00
inode-item.h btrfs: constify more pointer parameters 2024-09-10 16:51:22 +02:00
inode.c btrfs: fix folio leak in submit_one_async_extent() 2025-05-22 14:29:45 +02:00
ioctl.c btrfs: change btrfs_encoded_read() so that reading of extent is done by caller 2024-12-09 10:40:55 +01:00
ioctl.h btrfs: constify pointer parameters where applicable 2024-07-11 15:33:22 +02:00
Kconfig btrfs: check-integrity: remove CONFIG_BTRFS_FS_CHECK_INTEGRITY option 2023-10-12 16:44:05 +02:00
locking.c btrfs: change root->root_key.objectid to btrfs_root_id() 2024-05-07 21:31:06 +02:00
locking.h btrfs: cleanup recursive include of the same header 2024-07-11 15:33:22 +02:00
lru_cache.c btrfs: fix typos found by codespell 2023-12-15 23:00:04 +01:00
lru_cache.h btrfs: cleanup recursive include of the same header 2024-07-11 15:33:22 +02:00
lzo.c btrfs: convert lzo_decompress() to take a folio 2024-09-10 16:51:21 +02:00
Makefile btrfs: move the direct IO code into its own file 2024-07-11 15:33:29 +02:00
messages.c btrfs: disable rate limiting when debug enabled 2024-10-01 19:29:41 +02:00
messages.h btrfs: constify fs_info parameter in __btrfs_panic() 2023-12-15 20:27:02 +01:00
misc.h btrfs: constify pointer parameters where applicable 2024-07-11 15:33:22 +02:00
ordered-data.c btrfs: fix assertion failure when splitting ordered extent after transaction abort 2025-02-17 10:04:42 +01:00
ordered-data.h btrfs: convert btrfs_mark_ordered_io_finished() to take a folio 2024-09-10 16:51:14 +02:00
orphan.c btrfs: BTRFS_PATH_AUTO_FREE in orphan.c 2024-09-10 16:51:22 +02:00
orphan.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
print-tree.c btrfs: avoid using fixed char array size for tree names 2024-08-02 22:44:27 +02:00
print-tree.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
props.c btrfs: pass a btrfs_inode to btrfs_set_prop() 2024-07-11 15:33:29 +02:00
props.h btrfs: pass a btrfs_inode to btrfs_set_prop() 2024-07-11 15:33:29 +02:00
qgroup.c btrfs: avoid starting new transaction when cleaning qgroup during subvolume drop 2025-03-22 12:54:14 -07:00
qgroup.h btrfs: qgroup: set a more sane default value for subtree drop threshold 2024-10-22 16:09:11 +02:00
raid-stripe-tree.c btrfs: change RST lookup error message level to debug 2024-09-10 16:51:17 +02:00
raid-stripe-tree.h btrfs: remove raid-stripe-tree encoding field from stripe_extent 2024-07-11 15:33:28 +02:00
raid56.c btrfs: rename the extra_gfp parameter of btrfs_alloc_page_array() 2024-07-11 15:33:30 +02:00
raid56.h btrfs: add forward declarations and headers, part 2 2024-03-04 16:24:49 +01:00
rcu-string.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
ref-verify.c btrfs: ref-verify: fix use-after-free after invalid ref action 2024-12-09 10:40:56 +01:00
ref-verify.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
reflink.c btrfs: convert copy_inline_to_page() to use folio 2024-09-10 16:51:21 +02:00
reflink.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
relocation.c btrfs: convert BUG_ON in btrfs_reloc_cow_block() to proper error handling 2025-02-17 10:04:43 +01:00
relocation.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
root-tree.c btrfs: change root->root_key.objectid to btrfs_root_id() 2024-05-07 21:31:06 +02:00
root-tree.h btrfs: qgroup: fix qgroup prealloc rsv leak in subvolume operations 2024-04-02 19:18:23 +02:00
scrub.c btrfs: avoid NULL pointer dereference if no valid csum tree 2025-05-29 11:03:12 +02:00
scrub.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
send.c btrfs: send: return -ENAMETOOLONG when attempting a path that is too long 2025-05-29 11:02:13 +02:00
send.h btrfs: pass a btrfs_inode to btrfs_ioctl_send() 2024-07-11 15:33:28 +02:00
space-info.c btrfs: constify more pointer parameters 2024-09-10 16:51:22 +02:00
space-info.h btrfs: constify more pointer parameters 2024-09-10 16:51:22 +02:00
subpage.c btrfs: rename btrfs_folio_(set|start|end)_writer_lock() 2025-02-27 04:30:14 -08:00
subpage.h btrfs: rename btrfs_folio_(set|start|end)_writer_lock() 2025-02-27 04:30:14 -08:00
super.c btrfs: add back warning for mount option commit values exceeding 300 2025-05-22 14:29:45 +02:00
super.h btrfs: change BTRFS_MOUNT_* flags to 64bit type 2024-07-19 17:20:23 +02:00
sysfs.c btrfs: sysfs: fix direct super block member reads 2025-01-02 10:34:24 +01:00
sysfs.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
transaction.c btrfs: harden block_group::bg_list against list_del() races 2025-04-20 10:15:21 +02:00
transaction.h btrfs: fix race between direct IO write and fsync when using same fd 2024-09-03 20:29:55 +02:00
tree-checker.c btrfs: tree-checker: reject inline extent items with 0 ref count 2024-12-27 14:02:14 +01:00
tree-checker.h btrfs: make sure that WRITTEN is set on all metadata blocks 2024-05-02 22:11:13 +02:00
tree-log.c btrfs: fix uninitialized pointer free on read_alloc_one_name() error 2024-10-11 19:55:04 +02:00
tree-log.h btrfs: avoid transaction commit on any fsync after subvolume creation 2024-07-11 15:33:24 +02:00
tree-mod-log.c btrfs: constify more pointer parameters 2024-09-10 16:51:22 +02:00
tree-mod-log.h btrfs: constify more pointer parameters 2024-09-10 16:51:22 +02:00
ulist.c btrfs: preallocate ulist memory for qgroup rsv 2024-07-11 15:33:26 +02:00
ulist.h btrfs: preallocate ulist memory for qgroup rsv 2024-07-11 15:33:26 +02:00
uuid-tree.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
uuid-tree.h btrfs: move uuid tree related code to uuid-tree.[ch] 2024-09-10 16:51:12 +02:00
verity.c btrfs: add and use helper to verify the calling task has locked the inode 2024-09-10 16:51:22 +02:00
verity.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
volumes.c Revert "btrfs: canonicalize the device path before adding it" 2025-05-18 08:24:46 +02:00
volumes.h btrfs: split remaining space to discard in chunks 2024-10-07 23:21:53 +02:00
xattr.c btrfs: add and use helper to verify the calling task has locked the inode 2024-09-10 16:51:22 +02:00
xattr.h btrfs: constify pointer parameters where applicable 2024-07-11 15:33:22 +02:00
zlib.c btrfs: zlib: fix avail_in bytes for s390 zlib HW compression path 2025-01-17 13:40:48 +01:00
zoned.c btrfs: zoned: return EIO on RAID1 block group write pointer mismatch 2025-05-02 07:59:00 +02:00
zoned.h btrfs: constify more pointer parameters 2024-09-10 16:51:22 +02:00
zstd.c btrfs: convert zstd_decompress() to take a folio 2024-09-10 16:51:21 +02:00