[syzbot] [btrfs?] BUG: unable to handle kernel paging request in find_first_extent_item

9 views
Skip to first unread message

syzbot

unread,
Jan 1, 2025, 11:11:35 AM1/1/25
to c...@fb.com, dst...@suse.com, jo...@toxicpanda.com, linux...@vger.kernel.org, linux-...@vger.kernel.org, syzkall...@googlegroups.com
Hello,

syzbot found the following issue on:

HEAD commit: 573067a5a685 Merge branch 'for-next/core' into for-kernelci
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-kernelci
console output: https://syzkaller.appspot.com/x/log.txt?x=1256d0b0580000
kernel config: https://syzkaller.appspot.com/x/.config?x=cd7202b56d469648
dashboard link: https://syzkaller.appspot.com/bug?extid=339e9dbe3a2ca419b85d
compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
userspace arch: arm64
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=1254c818580000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=172486df980000

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/9d3b5c855aa0/disk-573067a5.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/0c06fc1ead83/vmlinux-573067a5.xz
kernel image: https://storage.googleapis.com/syzbot-assets/3390e59b9e4b/Image-573067a5.gz.xz
mounted in repro: https://storage.googleapis.com/syzbot-assets/0d8dc2ed77bb/mount_0.gz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+339e9d...@syzkaller.appspotmail.com

BTRFS info (device loop0): scrub: started on devid 1
Unable to handle kernel paging request at virtual address dfff800000000041
KASAN: null-ptr-deref in range [0x0000000000000208-0x000000000000020f]
Mem abort info:
ESR = 0x0000000096000005
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x05: level 1 translation fault
Data abort info:
ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[dfff800000000041] address between user and kernel address ranges
Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
Modules linked in:
CPU: 1 UID: 0 PID: 6417 Comm: syz-executor153 Not tainted 6.13.0-rc3-syzkaller-g573067a5a685 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : find_first_extent_item+0xac/0x674 fs/btrfs/scrub.c:1375
lr : find_first_extent_item+0xa4/0x674 fs/btrfs/scrub.c:1374
sp : ffff8000a5be6e60
x29: ffff8000a5be6f80 x28: dfff800000000000 x27: 0000000000000000
x26: 0000000000400000 x25: 0000000000400000 x24: 1fffe0001848ab0a
x23: 0000000000000208 x22: ffff8000a5be6f20 x21: ffff0000c2455858
x20: ffff8000a5be6ec0 x19: ffff0000db072010 x18: ffff0000db072010
x17: 000000000000e32c x16: ffff80008b5fea08 x15: 0000000000000004
x14: 1fffe0001b60c031 x13: 0000000000000000 x12: ffff700014b7cdd8
x11: ffff80008257f234 x10: 0000000000ff0100 x9 : 0000000000000000
x8 : 0000000000000041 x7 : 0000000000000000 x6 : 000000000000003f
x5 : 0000000000000040 x4 : 0000000000000008 x3 : 0000000000400000
x2 : 0000000000100000 x1 : ffff0000db072010 x0 : 0000000000000000
Call trace:
find_first_extent_item+0xac/0x674 fs/btrfs/scrub.c:1375 (P)
scrub_find_fill_first_stripe+0x2c0/0xab8 fs/btrfs/scrub.c:1551
queue_scrub_stripe fs/btrfs/scrub.c:1921 [inline]
scrub_simple_mirror+0x440/0x7e4 fs/btrfs/scrub.c:2152
scrub_stripe+0x7e4/0x2174 fs/btrfs/scrub.c:2317
scrub_chunk+0x268/0x41c fs/btrfs/scrub.c:2443
scrub_enumerate_chunks+0xd38/0x1784 fs/btrfs/scrub.c:2707
btrfs_scrub_dev+0x5a8/0xb34 fs/btrfs/scrub.c:3029
btrfs_ioctl_scrub+0x1f4/0x3e8 fs/btrfs/ioctl.c:3248
btrfs_ioctl+0x6a8/0xb04 fs/btrfs/ioctl.c:5246
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:906 [inline]
__se_sys_ioctl fs/ioctl.c:892 [inline]
__arm64_sys_ioctl+0x14c/0x1cc fs/ioctl.c:892
__invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49
el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132
do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151
el0_svc+0x54/0x168 arch/arm64/kernel/entry-common.c:744
el0t_64_sync_handler+0x84/0x108 arch/arm64/kernel/entry-common.c:762
el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:600
Code: b900118a 97847832 91082377 d343fee8 (387c6908)
---[ end trace 0000000000000000 ]---
----------------
Code disassembly (best guess):
0: b900118a str w10, [x12, #16]
4: 97847832 bl 0xfffffffffe11e0cc
8: 91082377 add x23, x27, #0x208
c: d343fee8 lsr x8, x23, #3
* 10: 387c6908 ldrb w8, [x8, x28] <-- trapping instruction


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzk...@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

Lizhi Xu

unread,
Jan 1, 2025, 11:06:05 PM1/1/25
to syzbot+339e9d...@syzkaller.appspotmail.com, c...@fb.com, dst...@suse.com, jo...@toxicpanda.com, linux...@vger.kernel.org, linux-...@vger.kernel.org, syzkall...@googlegroups.com
syzbot reported a null-ptr-deref in find_first_extent_item. [1]

The btrfs filesystem did not successfully initialize extent root to the
global root tree when mounted, this is because extent buffer is not uptodate,
which causes the failure to read the tree root, which in turn causes extent
root to not be inserted into the global root tree.

To prevent this issue, add extent root check before using it.

[1]
Reported-by: syzbot+339e9d...@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=339e9dbe3a2ca419b85d
Signed-off-by: Lizhi Xu <lizh...@windriver.com>
---
fs/btrfs/scrub.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 204c928beaf9..6080839cec95 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -1372,10 +1372,14 @@ static int find_first_extent_item(struct btrfs_root *extent_root,
struct btrfs_path *path,
u64 search_start, u64 search_len)
{
- struct btrfs_fs_info *fs_info = extent_root->fs_info;
+ struct btrfs_fs_info *fs_info;
struct btrfs_key key;
int ret;

+ if (!extent_root)
+ return -ENOENT;
+
+ fs_info = extent_root->fs_info;
/* Continue using the existing path */
if (path->nodes[0])
goto search_forward;
--
2.43.0

Qu Wenruo

unread,
Jan 1, 2025, 11:42:45 PM1/1/25
to Lizhi Xu, syzbot+339e9d...@syzkaller.appspotmail.com, c...@fb.com, dst...@suse.com, jo...@toxicpanda.com, linux...@vger.kernel.org, linux-...@vger.kernel.org, syzkall...@googlegroups.com


在 2025/1/2 14:35, Lizhi Xu 写道:
> syzbot reported a null-ptr-deref in find_first_extent_item. [1]
>
> The btrfs filesystem did not successfully initialize extent root to the
> global root tree when mounted, this is because extent buffer is not uptodate,
> which causes the failure to read the tree root, which in turn causes extent
> root to not be inserted into the global root tree.

Sorry I didn't notice your fix and sent out my version.

I'd prefer your patch to mention that, this is not the common case.
As a btrfs can not be mounted with corrupted extent root.

Such fs can only be mounted with rescue=all,ro mount option as a data
salvage method.

And you do not need to go through all the global root/extent buffer
uptodate things, just mention a corrupted extent tree root is more than
good enough.
If you understand the reason why this is possible in the first place,
you can find out the offending commit, where the rescue=ibadroot mount
option is introduced.

Although in the latest kernel it's b979547513ff ("btrfs: scrub:
introduce helper to find and fill sector info for a scrub_stripe")
causing the problem, the same problem also happens before the scrub rework.

So next time please add related fixes: tag for similar reports.

Thanks,
Qu

Lizhi Xu

unread,
Jan 2, 2025, 1:30:37 AM1/2/25
to quwenru...@gmx.com, c...@fb.com, dst...@suse.com, jo...@toxicpanda.com, linux...@vger.kernel.org, linux-...@vger.kernel.org, lizh...@windriver.com, syzbot+339e9d...@syzkaller.appspotmail.com, syzkall...@googlegroups.com
syzbot reported a null-ptr-deref in find_first_extent_item. [1]

The btrfs filesystem did not successfully initialize extent root to the
global root tree when mounted(as the mount options contain ignorebadroots),
this is because extent buffer is not uptodate, which causes the failure to
read the tree root, which in turn causes extent root to not be inserted into
the global root tree.

To prevent this issue, if extent root is corrupt then exit the mount.
Fixes: abed4aaae4f7 ("btrfs: track the csum, extent, and free space trees in a rbtree")
Signed-off-by: Lizhi Xu <lizh...@windriver.com>
---
V1 -> V2: exit mount when extent root is corrupt

fs/btrfs/disk-io.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index eff0dd1ae62f..beb236c7fe1c 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2167,7 +2167,8 @@ static int load_global_roots_objectid(struct btrfs_root *tree_root,
found = true;
root = read_tree_root_path(tree_root, path, &key);
if (IS_ERR(root)) {
- if (!btrfs_test_opt(fs_info, IGNOREBADROOTS))
+ if (!btrfs_test_opt(fs_info, IGNOREBADROOTS) ||
+ objectid == BTRFS_EXTENT_TREE_OBJECTID)
ret = PTR_ERR(root);
break;
}
@@ -2188,7 +2189,8 @@ static int load_global_roots_objectid(struct btrfs_root *tree_root,
if (objectid == BTRFS_CSUM_TREE_OBJECTID)
set_bit(BTRFS_FS_STATE_NO_DATA_CSUMS, &fs_info->fs_state);

- if (!btrfs_test_opt(fs_info, IGNOREBADROOTS))
+ if (!btrfs_test_opt(fs_info, IGNOREBADROOTS) ||
+ (ret && objectid == BTRFS_EXTENT_TREE_OBJECTID))
ret = ret ? ret : -ENOENT;
else
ret = 0;
--
2.43.0

Qu Wenruo

unread,
Jan 2, 2025, 3:21:53 AM1/2/25
to Lizhi Xu, c...@fb.com, dst...@suse.com, jo...@toxicpanda.com, linux...@vger.kernel.org, linux-...@vger.kernel.org, syzbot+339e9d...@syzkaller.appspotmail.com, syzkall...@googlegroups.com


在 2025/1/2 17:00, Lizhi Xu 写道:
> syzbot reported a null-ptr-deref in find_first_extent_item. [1]
>
> The btrfs filesystem did not successfully initialize extent root to the
> global root tree when mounted(as the mount options contain ignorebadroots),
> this is because extent buffer is not uptodate,

The "not uptodate" is only the symptom, if you check the console output
carefully enough, it's because the extent tree root (and must be extent
tree root, any child node won't cause problem) is corrupted (csum mismatch).
I do not think that's the correct commit.

Even before that commit, inside scrub_stripe() we directly use
fs_info->extent_root without checking if it's NULL.

And pass that extent_root into btrfs_reada_add(), which later calls
"rc->fs_info = root->fs_info;", triggering exactly the same error.

Before 42437a6386ff ("btrfs: introduce mount option
rescue=ignorebadroots"), there is no error path like this at all,
because btrfs will just refuse to mount such fs with extent tree root
corrupted.

So please, understand what is really causing the problem then submit a fix.

Thanks,
Qu

Lizhi Xu

unread,
Jan 2, 2025, 3:39:59 AM1/2/25
to quwenru...@gmx.com, c...@fb.com, dst...@suse.com, jo...@toxicpanda.com, linux...@vger.kernel.org, linux-...@vger.kernel.org, lizh...@windriver.com, syzbot+339e9d...@syzkaller.appspotmail.com, syzkall...@googlegroups.com
syzbot reported a null-ptr-deref in find_first_extent_item. [1]

The btrfs filesystem did not successfully initialize extent root to the
global root tree when mounted(as the mount options contain ignorebadroots),
Fixes: 42437a6386ff ("btrfs: introduce mount option rescue=ignorebadroots")
Reported-by: syzbot+339e9d...@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=339e9dbe3a2ca419b85d
Signed-off-by: Lizhi Xu <lizh...@windriver.com>
---
V1 -> V2: exit mount when extent root is corrupt
V2 -> V3: correct comments and Fixes tag

fs/btrfs/disk-io.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index eff0dd1ae62f..beb236c7fe1c 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2167,7 +2167,8 @@ static int load_global_roots_objectid(struct btrfs_root *tree_root,
found = true;
root = read_tree_root_path(tree_root, path, &key);
if (IS_ERR(root)) {
- if (!btrfs_test_opt(fs_info, IGNOREBADROOTS))
+ if (!btrfs_test_opt(fs_info, IGNOREBADROOTS) ||
+ objectid == BTRFS_EXTENT_TREE_OBJECTID)
ret = PTR_ERR(root);
break;
}
@@ -2188,7 +2189,8 @@ static int load_global_roots_objectid(struct btrfs_root *tree_root,
if (objectid == BTRFS_CSUM_TREE_OBJECTID)
set_bit(BTRFS_FS_STATE_NO_DATA_CSUMS, &fs_info->fs_state);

- if (!btrfs_test_opt(fs_info, IGNOREBADROOTS))
+ if (!btrfs_test_opt(fs_info, IGNOREBADROOTS) ||
+ (ret && objectid == BTRFS_EXTENT_TREE_OBJECTID))
ret = ret ? ret : -ENOENT;
else
ret = 0;
--
2.43.0

Lizhi Xu

unread,
Jan 2, 2025, 4:05:12 AM1/2/25
to lizh...@windriver.com, c...@fb.com, dst...@suse.com, jo...@toxicpanda.com, linux...@vger.kernel.org, linux-...@vger.kernel.org, quwenru...@gmx.com, syzbot+339e9d...@syzkaller.appspotmail.com, syzkall...@googlegroups.com
syzbot reported a null-ptr-deref in find_first_extent_item. [1]

The btrfs filesystem did not successfully initialize extent root to the
global root tree when mounted, since the mount options contain ignorebadroots,
because commit 42437a6386ff, it can be mounted successfully, which causes
the failure to read the tree root, which in turn causes exten root to not
be inserted into the global root tree.

Add a extent root check when scrub calls scrub_find_fill_first_stripe.
V3 -> V4: check extent root before calling find_first_extent_item

fs/btrfs/scrub.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 204c928beaf9..560415fe1007 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -1548,6 +1548,9 @@ static int scrub_find_fill_first_stripe(struct btrfs_block_group *bg,
/* The range must be inside the bg. */
ASSERT(logical_start >= bg->start && logical_end <= bg->start + bg->length);

+ if (!extent_root)
+ return -ENOENT;
+
ret = find_first_extent_item(extent_root, extent_path, logical_start,
logical_len);
/* Either error or not found. */
--
2.43.0

Lizhi Xu

unread,
Jan 2, 2025, 4:45:41 AM1/2/25
to quwenru...@gmx.com, c...@fb.com, dst...@suse.com, jo...@toxicpanda.com, linux...@vger.kernel.org, linux-...@vger.kernel.org, lizh...@windriver.com, syzbot+339e9d...@syzkaller.appspotmail.com, syzkall...@googlegroups.com
On Thu, 2 Jan 2025 18:51:34 +1030, Qu Wenruo wrote:
> > syzbot reported a null-ptr-deref in find_first_extent_item. [1]
> >
> > The btrfs filesystem did not successfully initialize extent root to the
> > global root tree when mounted(as the mount options contain ignorebadroots),
> > this is because extent buffer is not uptodate,
>
> The "not uptodate" is only the symptom, if you check the console output
> carefully enough, it's because the extent tree root (and must be extent
> tree root, any child node won't cause problem) is corrupted (csum mismatch).
>
[ 35.752834][ T3330] BTRFS warning (device loop0): checksum verify failed on logical 5337088 mirror 1 wanted 0x324c5e2d0cac2dc8f61cbfdfc8cd69d9816061b1498b9e1bff0
According to the above log, it is clear that the failure of btrfs_validate_extent_buffer()
causes the extent buffer to be not uptodate, and it can be judged that extent root is corrupted.

BR,
Lizhi
Reply all
Reply to author
Forward
0 new messages