* [PATCH AUTOSEL 6.12 02/11] btrfs: correct the order of prelim_ref arguments in btrfs__prelim_ref
2025-05-12 18:04 [PATCH AUTOSEL 6.12 01/11] btrfs: compression: adjust cb->compressed_folios allocation type Sasha Levin
@ 2025-05-12 18:04 ` Sasha Levin
2025-05-12 18:04 ` [PATCH AUTOSEL 6.12 03/11] btrfs: handle empty eb->folios in num_extent_folios() Sasha Levin
2025-05-12 18:04 ` [PATCH AUTOSEL 6.12 04/11] btrfs: avoid NULL pointer dereference if no valid csum tree Sasha Levin
2 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2025-05-12 18:04 UTC (permalink / raw)
To: patches, stable
Cc: Goldwyn Rodrigues, Goldwyn Rodrigues, David Sterba, Sasha Levin,
clm, josef, rostedt, mhiramat, linux-btrfs, linux-kernel,
linux-trace-kernel
From: Goldwyn Rodrigues <rgoldwyn@suse.de>
[ Upstream commit bc7e0975093567f51be8e1bdf4aa5900a3cf0b1e ]
btrfs_prelim_ref() calls the old and new reference variables in the
incorrect order. This causes a NULL pointer dereference because oldref
is passed as NULL to trace_btrfs_prelim_ref_insert().
Note, trace_btrfs_prelim_ref_insert() is being called with newref as
oldref (and oldref as NULL) on purpose in order to print out
the values of newref.
To reproduce:
echo 1 > /sys/kernel/debug/tracing/events/btrfs/btrfs_prelim_ref_insert/enable
Perform some writeback operations.
Backtrace:
BUG: kernel NULL pointer dereference, address: 0000000000000018
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 115949067 P4D 115949067 PUD 11594a067 PMD 0
Oops: Oops: 0000 [#1] SMP NOPTI
CPU: 1 UID: 0 PID: 1188 Comm: fsstress Not tainted 6.15.0-rc2-tester+ #47 PREEMPT(voluntary) 7ca2cef72d5e9c600f0c7718adb6462de8149622
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.3-2-gc13ff2cd-prebuilt.qemu.org 04/01/2014
RIP: 0010:trace_event_raw_event_btrfs__prelim_ref+0x72/0x130
Code: e8 43 81 9f ff 48 85 c0 74 78 4d 85 e4 0f 84 8f 00 00 00 49 8b 94 24 c0 06 00 00 48 8b 0a 48 89 48 08 48 8b 52 08 48 89 50 10 <49> 8b 55 18 48 89 50 18 49 8b 55 20 48 89 50 20 41 0f b6 55 28 88
RSP: 0018:ffffce44820077a0 EFLAGS: 00010286
RAX: ffff8c6b403f9014 RBX: ffff8c6b55825730 RCX: 304994edf9cf506b
RDX: d8b11eb7f0fdb699 RSI: ffff8c6b403f9010 RDI: ffff8c6b403f9010
RBP: 0000000000000001 R08: 0000000000000001 R09: 0000000000000010
R10: 00000000ffffffff R11: 0000000000000000 R12: ffff8c6b4e8fb000
R13: 0000000000000000 R14: ffffce44820077a8 R15: ffff8c6b4abd1540
FS: 00007f4dc6813740(0000) GS:ffff8c6c1d378000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000018 CR3: 000000010eb42000 CR4: 0000000000750ef0
PKRU: 55555554
Call Trace:
<TASK>
prelim_ref_insert+0x1c1/0x270
find_parent_nodes+0x12a6/0x1ee0
? __entry_text_end+0x101f06/0x101f09
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
btrfs_is_data_extent_shared+0x167/0x640
? fiemap_process_hole+0xd0/0x2c0
extent_fiemap+0xa5c/0xbc0
? __entry_text_end+0x101f05/0x101f09
btrfs_fiemap+0x7e/0xd0
do_vfs_ioctl+0x425/0x9d0
__x64_sys_ioctl+0x75/0xc0
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/trace/events/btrfs.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h
index af6b3827fb1d0..3b16b0cc1b7a6 100644
--- a/include/trace/events/btrfs.h
+++ b/include/trace/events/btrfs.h
@@ -1924,7 +1924,7 @@ DECLARE_EVENT_CLASS(btrfs__prelim_ref,
TP_PROTO(const struct btrfs_fs_info *fs_info,
const struct prelim_ref *oldref,
const struct prelim_ref *newref, u64 tree_size),
- TP_ARGS(fs_info, newref, oldref, tree_size),
+ TP_ARGS(fs_info, oldref, newref, tree_size),
TP_STRUCT__entry_btrfs(
__field( u64, root_id )
--
2.39.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH AUTOSEL 6.12 03/11] btrfs: handle empty eb->folios in num_extent_folios()
2025-05-12 18:04 [PATCH AUTOSEL 6.12 01/11] btrfs: compression: adjust cb->compressed_folios allocation type Sasha Levin
2025-05-12 18:04 ` [PATCH AUTOSEL 6.12 02/11] btrfs: correct the order of prelim_ref arguments in btrfs__prelim_ref Sasha Levin
@ 2025-05-12 18:04 ` Sasha Levin
2025-05-12 18:04 ` [PATCH AUTOSEL 6.12 04/11] btrfs: avoid NULL pointer dereference if no valid csum tree Sasha Levin
2 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2025-05-12 18:04 UTC (permalink / raw)
To: patches, stable
Cc: Boris Burkov, Qu Wenruo, David Sterba, Sasha Levin, clm, josef,
linux-btrfs, linux-kernel
From: Boris Burkov <boris@bur.io>
[ Upstream commit d6fe0c69b3aa5c985380b794bdf8e6e9b1811e60 ]
num_extent_folios() unconditionally calls folio_order() on
eb->folios[0]. If that is NULL this will be a segfault. It is reasonable
for it to return 0 as the number of folios in the eb when the first
entry is NULL, so do that instead.
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Boris Burkov <boris@bur.io>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/extent_io.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 8a36117ed4532..fcb60837d7dc6 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -293,6 +293,8 @@ static inline int num_extent_pages(const struct extent_buffer *eb)
*/
static inline int num_extent_folios(const struct extent_buffer *eb)
{
+ if (!eb->folios[0])
+ return 0;
if (folio_order(eb->folios[0]))
return 1;
return num_extent_pages(eb);
--
2.39.5
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH AUTOSEL 6.12 04/11] btrfs: avoid NULL pointer dereference if no valid csum tree
2025-05-12 18:04 [PATCH AUTOSEL 6.12 01/11] btrfs: compression: adjust cb->compressed_folios allocation type Sasha Levin
2025-05-12 18:04 ` [PATCH AUTOSEL 6.12 02/11] btrfs: correct the order of prelim_ref arguments in btrfs__prelim_ref Sasha Levin
2025-05-12 18:04 ` [PATCH AUTOSEL 6.12 03/11] btrfs: handle empty eb->folios in num_extent_folios() Sasha Levin
@ 2025-05-12 18:04 ` Sasha Levin
2 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2025-05-12 18:04 UTC (permalink / raw)
To: patches, stable
Cc: Qu Wenruo, Johannes Thumshirn, David Sterba, Sasha Levin, clm,
josef, linux-btrfs, linux-kernel
From: Qu Wenruo <wqu@suse.com>
[ Upstream commit f95d186255b319c48a365d47b69bd997fecb674e ]
[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>
---
fs/btrfs/scrub.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index c73a41b1ad560..d8fcc3eb85c88 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -1541,8 +1541,8 @@ static int scrub_find_fill_first_stripe(struct btrfs_block_group *bg,
u64 extent_gen;
int ret;
- if (unlikely(!extent_root)) {
- btrfs_err(fs_info, "no valid extent root for scrub");
+ if (unlikely(!extent_root || !csum_root)) {
+ btrfs_err(fs_info, "no valid extent or csum root for scrub");
return -EUCLEAN;
}
memset(stripe->sectors, 0, sizeof(struct scrub_sector_verification) *
--
2.39.5
^ permalink raw reply related [flat|nested] 4+ messages in thread