* [syzbot] [btrfs?] general protection fault in create_empty_buffers (5)
@ 2026-01-08 13:00 syzbot
2026-01-09 11:37 ` [PATCH] btrfs: Sync read disk supper and set block size Edward Adam Davis
2026-01-09 12:56 ` [PATCH] " Edward Adam Davis
0 siblings, 2 replies; 7+ messages in thread
From: syzbot @ 2026-01-08 13:00 UTC (permalink / raw)
To: clm, dsterba, josef, linux-btrfs, linux-kernel, syzkaller-bugs
Hello,
syzbot found the following issue on:
HEAD commit: f0b9d8eb98df Merge tag 'nfsd-6.19-3' of git://git.kernel.o..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=1311ef92580000
kernel config: https://syzkaller.appspot.com/x/.config?x=a11e0f726bfb6765
dashboard link: https://syzkaller.appspot.com/bug?extid=b4a2af3000eaa84d95d5
compiler: gcc (Debian 12.2.0-14+deb12u1) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=10663e9a580000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=14936074580000
Downloadable assets:
disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/d900f083ada3/non_bootable_disk-f0b9d8eb.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/d6eefae97e89/vmlinux-f0b9d8eb.xz
kernel image: https://storage.googleapis.com/syzbot-assets/a16fafcc4238/bzImage-f0b9d8eb.xz
IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+b4a2af3000eaa84d95d5@syzkaller.appspotmail.com
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
CPU: 2 UID: 0 PID: 6261 Comm: syz.0.73 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
RIP: 0010:create_empty_buffers+0x4d/0x480 fs/buffer.c:1694
Code: ec 6d ff 48 89 de ba 40 8c 40 00 4c 89 ef e8 0a f6 ff ff 49 89 c6 48 89 c3 eb 03 48 89 c3 e8 ea eb 6d ff 48 89 d8 48 c1 e8 03 <80> 3c 28 00 0f 85 81 03 00 00 48 8d 7b 08 4c 09 23 48 89 f8 48 c1
RSP: 0018:ffffc9000408f870 EFLAGS: 00010246
RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff8250f7ec
RDX: ffff88802a4d8000 RSI: ffffffff8250fcc6 RDI: ffff88802a4d9680
RBP: dffffc0000000000 R08: 0000000000000005 R09: 0000000000000000
R10: 0000000000000000 R11: ffff88802a4d8b30 R12: 0000000000000000
R13: ffffea0000a9e5c0 R14: 0000000000000000 R15: dffffc0000000000
FS: 00007f1ac84a46c0(0000) GS:ffff8880d6af5000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f1ac84a3f98 CR3: 000000002b14f000 CR4: 0000000000352ef0
Call Trace:
<TASK>
folio_create_buffers+0x109/0x150 fs/buffer.c:1802
block_read_full_folio+0x14c/0x850 fs/buffer.c:2403
filemap_read_folio+0xc8/0x2a0 mm/filemap.c:2496
do_read_cache_folio+0x266/0x5c0 mm/filemap.c:4096
do_read_cache_page mm/filemap.c:4162 [inline]
read_cache_page_gfp+0x29/0x120 mm/filemap.c:4195
btrfs_read_disk_super+0x192/0x500 fs/btrfs/volumes.c:1367
btrfs_scan_one_device+0x109/0x820 fs/btrfs/volumes.c:1475
btrfs_get_tree_super fs/btrfs/super.c:1860 [inline]
btrfs_get_tree_subvol fs/btrfs/super.c:2089 [inline]
btrfs_get_tree+0x5b3/0x2710 fs/btrfs/super.c:2123
vfs_get_tree+0x8e/0x330 fs/super.c:1751
fc_mount fs/namespace.c:1199 [inline]
do_new_mount_fc fs/namespace.c:3636 [inline]
do_new_mount fs/namespace.c:3712 [inline]
path_mount+0x7bf/0x23a0 fs/namespace.c:4022
do_mount fs/namespace.c:4035 [inline]
__do_sys_mount fs/namespace.c:4224 [inline]
__se_sys_mount fs/namespace.c:4201 [inline]
__x64_sys_mount+0x293/0x310 fs/namespace.c:4201
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xcd/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f1ac758f7c9
Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f1ac84a4038 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5
RAX: ffffffffffffffda RBX: 00007f1ac77e6090 RCX: 00007f1ac758f7c9
RDX: 00002000000000c0 RSI: 0000200000000080 RDI: 00002000000001c0
RBP: 00007f1ac7613f91 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000004418 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f1ac77e6128 R14: 00007f1ac77e6090 R15: 00007ffe5d1bb9d8
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:create_empty_buffers+0x4d/0x480 fs/buffer.c:1694
Code: ec 6d ff 48 89 de ba 40 8c 40 00 4c 89 ef e8 0a f6 ff ff 49 89 c6 48 89 c3 eb 03 48 89 c3 e8 ea eb 6d ff 48 89 d8 48 c1 e8 03 <80> 3c 28 00 0f 85 81 03 00 00 48 8d 7b 08 4c 09 23 48 89 f8 48 c1
RSP: 0018:ffffc9000408f870 EFLAGS: 00010246
RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff8250f7ec
RDX: ffff88802a4d8000 RSI: ffffffff8250fcc6 RDI: ffff88802a4d9680
RBP: dffffc0000000000 R08: 0000000000000005 R09: 0000000000000000
R10: 0000000000000000 R11: ffff88802a4d8b30 R12: 0000000000000000
R13: ffffea0000a9e5c0 R14: 0000000000000000 R15: dffffc0000000000
FS: 00007f1ac84a46c0(0000) GS:ffff8880d6af5000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f1ac84a3f98 CR3: 000000002b14f000 CR4: 0000000000352ef0
----------------
Code disassembly (best guess):
0: ec in (%dx),%al
1: 6d insl (%dx),%es:(%rdi)
2: ff 48 89 decl -0x77(%rax)
5: de ba 40 8c 40 00 fidivrs 0x408c40(%rdx)
b: 4c 89 ef mov %r13,%rdi
e: e8 0a f6 ff ff call 0xfffff61d
13: 49 89 c6 mov %rax,%r14
16: 48 89 c3 mov %rax,%rbx
19: eb 03 jmp 0x1e
1b: 48 89 c3 mov %rax,%rbx
1e: e8 ea eb 6d ff call 0xff6dec0d
23: 48 89 d8 mov %rbx,%rax
26: 48 c1 e8 03 shr $0x3,%rax
* 2a: 80 3c 28 00 cmpb $0x0,(%rax,%rbp,1) <-- trapping instruction
2e: 0f 85 81 03 00 00 jne 0x3b5
34: 48 8d 7b 08 lea 0x8(%rbx),%rdi
38: 4c 09 23 or %r12,(%rbx)
3b: 48 89 f8 mov %rdi,%rax
3e: 48 rex.W
3f: c1 .byte 0xc1
---
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 syzkaller@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
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] btrfs: Sync read disk supper and set block size
2026-01-08 13:00 [syzbot] [btrfs?] general protection fault in create_empty_buffers (5) syzbot
@ 2026-01-09 11:37 ` Edward Adam Davis
2026-01-09 12:43 ` Filipe Manana
2026-01-09 12:56 ` [PATCH] " Edward Adam Davis
1 sibling, 1 reply; 7+ messages in thread
From: Edward Adam Davis @ 2026-01-09 11:37 UTC (permalink / raw)
To: syzbot+b4a2af3000eaa84d95d5
Cc: clm, dsterba, josef, linux-btrfs, linux-kernel, syzkaller-bugs
When the user performs a btrfs mount, the block device is not set
correctly. The user sets the block size of the block device to 0x4000
by executing the BLKBSZSET command.
Since the block size change also changes the mapping->flags value, this
further affects the result of the mapping_min_folio_order() calculation.
Let's analyze the following two scenarios:
Scenario 1: Without executing the BLKBSZSET command, the block size is
0x1000, and mapping_min_folio_order() returns 0;
Scenario 2: After executing the BLKBSZSET command, the block size is
0x4000, and mapping_min_folio_order() returns 2.
do_read_cache_folio() allocates a folio before the BLKBSZSET command
is executed. This results in the allocated folio having an order value
of 0. Later, after BLKBSZSET is executed, the block size increases to
0x4000, and the mapping_min_folio_order() calculation result becomes 2.
This leads to two undesirable consequences:
1. filemap_add_folio() triggers a VM_BUG_ON_FOLIO(folio_order(folio) <
mapping_min_folio_order(mapping)) assertion.
2. The syzbot report [1] shows a null pointer dereference in
create_empty_buffers() due to a buffer head allocation failure.
Synchronization should be established based on the inode between the
BLKBSZSET command and read cache page to prevent inconsistencies in
block size or mapping flags before and after folio allocation.
[1]
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
RIP: 0010:create_empty_buffers+0x4d/0x480 fs/buffer.c:1694
Call Trace:
folio_create_buffers+0x109/0x150 fs/buffer.c:1802
block_read_full_folio+0x14c/0x850 fs/buffer.c:2403
filemap_read_folio+0xc8/0x2a0 mm/filemap.c:2496
do_read_cache_folio+0x266/0x5c0 mm/filemap.c:4096
do_read_cache_page mm/filemap.c:4162 [inline]
read_cache_page_gfp+0x29/0x120 mm/filemap.c:4195
btrfs_read_disk_super+0x192/0x500 fs/btrfs/volumes.c:1367
Reported-by: syzbot+b4a2af3000eaa84d95d5@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b4a2af3000eaa84d95d5
Tested-by: syzbot+b4a2af3000eaa84d95d5@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
---
fs/btrfs/volumes.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 13c514684cfb..eee7471a3e03 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1339,6 +1339,7 @@ struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
struct page *page;
u64 bytenr, bytenr_orig;
struct address_space *mapping = bdev->bd_mapping;
+ struct inode *inode = mapping->host;
int ret;
bytenr_orig = btrfs_sb_offset(copy_num);
@@ -1364,7 +1365,9 @@ struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
(bytenr + BTRFS_SUPER_INFO_SIZE) >> PAGE_SHIFT);
}
+ inode_lock(inode);
page = read_cache_page_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS);
+ inode_unlock(inode);
if (IS_ERR(page))
return ERR_CAST(page);
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] btrfs: Sync read disk supper and set block size
2026-01-09 11:37 ` [PATCH] btrfs: Sync read disk supper and set block size Edward Adam Davis
@ 2026-01-09 12:43 ` Filipe Manana
2026-01-09 13:02 ` [PATCH v2] btrfs: Sync read disk super " Edward Adam Davis
0 siblings, 1 reply; 7+ messages in thread
From: Filipe Manana @ 2026-01-09 12:43 UTC (permalink / raw)
To: Edward Adam Davis
Cc: syzbot+b4a2af3000eaa84d95d5, clm, dsterba, josef, linux-btrfs,
linux-kernel, syzkaller-bugs
On Fri, Jan 9, 2026 at 11:42 AM Edward Adam Davis <eadavis@qq.com> wrote:
>
> When the user performs a btrfs mount, the block device is not set
> correctly. The user sets the block size of the block device to 0x4000
> by executing the BLKBSZSET command.
> Since the block size change also changes the mapping->flags value, this
> further affects the result of the mapping_min_folio_order() calculation.
>
> Let's analyze the following two scenarios:
> Scenario 1: Without executing the BLKBSZSET command, the block size is
> 0x1000, and mapping_min_folio_order() returns 0;
>
> Scenario 2: After executing the BLKBSZSET command, the block size is
> 0x4000, and mapping_min_folio_order() returns 2.
>
> do_read_cache_folio() allocates a folio before the BLKBSZSET command
> is executed. This results in the allocated folio having an order value
> of 0. Later, after BLKBSZSET is executed, the block size increases to
> 0x4000, and the mapping_min_folio_order() calculation result becomes 2.
> This leads to two undesirable consequences:
> 1. filemap_add_folio() triggers a VM_BUG_ON_FOLIO(folio_order(folio) <
> mapping_min_folio_order(mapping)) assertion.
> 2. The syzbot report [1] shows a null pointer dereference in
> create_empty_buffers() due to a buffer head allocation failure.
>
> Synchronization should be established based on the inode between the
> BLKBSZSET command and read cache page to prevent inconsistencies in
> block size or mapping flags before and after folio allocation.
While that fixes the problem, I'd rather lock the invalidation lock
instead of the inode:
filemap_invalidate_lock(mapping);
page = read_cache_page_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS);
filemap_invalidate_unlock(mapping);
Because that's what the documentation for read_cache_page_gfp() asks for:
/**
(...)
*
* The function expects mapping->invalidate_lock to be already held.
(...)
*/
struct page *read_cache_page_gfp(struct address_space *mapping,
pgoff_t index,
gfp_t gfp)
{
return do_read_cache_page(mapping, index, NULL, NULL, gfp);
}
That will fix the race with set_blocksize() too.
Thanks.
>
> [1]
> KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
> RIP: 0010:create_empty_buffers+0x4d/0x480 fs/buffer.c:1694
> Call Trace:
> folio_create_buffers+0x109/0x150 fs/buffer.c:1802
> block_read_full_folio+0x14c/0x850 fs/buffer.c:2403
> filemap_read_folio+0xc8/0x2a0 mm/filemap.c:2496
> do_read_cache_folio+0x266/0x5c0 mm/filemap.c:4096
> do_read_cache_page mm/filemap.c:4162 [inline]
> read_cache_page_gfp+0x29/0x120 mm/filemap.c:4195
> btrfs_read_disk_super+0x192/0x500 fs/btrfs/volumes.c:1367
>
> Reported-by: syzbot+b4a2af3000eaa84d95d5@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=b4a2af3000eaa84d95d5
> Tested-by: syzbot+b4a2af3000eaa84d95d5@syzkaller.appspotmail.com
> Signed-off-by: Edward Adam Davis <eadavis@qq.com>
> ---
> fs/btrfs/volumes.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index 13c514684cfb..eee7471a3e03 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -1339,6 +1339,7 @@ struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
> struct page *page;
> u64 bytenr, bytenr_orig;
> struct address_space *mapping = bdev->bd_mapping;
> + struct inode *inode = mapping->host;
> int ret;
>
> bytenr_orig = btrfs_sb_offset(copy_num);
> @@ -1364,7 +1365,9 @@ struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
> (bytenr + BTRFS_SUPER_INFO_SIZE) >> PAGE_SHIFT);
> }
>
> + inode_lock(inode);
> page = read_cache_page_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS);
> + inode_unlock(inode);
> if (IS_ERR(page))
> return ERR_CAST(page);
>
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] btrfs: Sync read disk super and set block size
2026-01-08 13:00 [syzbot] [btrfs?] general protection fault in create_empty_buffers (5) syzbot
2026-01-09 11:37 ` [PATCH] btrfs: Sync read disk supper and set block size Edward Adam Davis
@ 2026-01-09 12:56 ` Edward Adam Davis
1 sibling, 0 replies; 7+ messages in thread
From: Edward Adam Davis @ 2026-01-09 12:56 UTC (permalink / raw)
To: syzbot+b4a2af3000eaa84d95d5
Cc: clm, dsterba, josef, linux-btrfs, linux-kernel, syzkaller-bugs
When the user performs a btrfs mount, the block device is not set
correctly. The user sets the block size of the block device to 0x4000
by executing the BLKBSZSET command.
Since the block size change also changes the mapping->flags value, this
further affects the result of the mapping_min_folio_order() calculation.
Let's analyze the following two scenarios:
Scenario 1: Without executing the BLKBSZSET command, the block size is
0x1000, and mapping_min_folio_order() returns 0;
Scenario 2: After executing the BLKBSZSET command, the block size is
0x4000, and mapping_min_folio_order() returns 2.
do_read_cache_folio() allocates a folio before the BLKBSZSET command
is executed. This results in the allocated folio having an order value
of 0. Later, after BLKBSZSET is executed, the block size increases to
0x4000, and the mapping_min_folio_order() calculation result becomes 2.
This leads to two undesirable consequences:
1. filemap_add_folio() triggers a VM_BUG_ON_FOLIO(folio_order(folio) <
mapping_min_folio_order(mapping)) assertion.
2. The syzbot report [1] shows a null pointer dereference in
create_empty_buffers() due to a buffer head allocation failure.
Synchronization should be established based on the inode between the
BLKBSZSET command and read cache page to prevent inconsistencies in
block size or mapping flags before and after folio allocation.
[1]
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
RIP: 0010:create_empty_buffers+0x4d/0x480 fs/buffer.c:1694
Call Trace:
folio_create_buffers+0x109/0x150 fs/buffer.c:1802
block_read_full_folio+0x14c/0x850 fs/buffer.c:2403
filemap_read_folio+0xc8/0x2a0 mm/filemap.c:2496
do_read_cache_folio+0x266/0x5c0 mm/filemap.c:4096
do_read_cache_page mm/filemap.c:4162 [inline]
read_cache_page_gfp+0x29/0x120 mm/filemap.c:4195
btrfs_read_disk_super+0x192/0x500 fs/btrfs/volumes.c:1367
Reported-by: syzbot+b4a2af3000eaa84d95d5@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b4a2af3000eaa84d95d5
Tested-by: syzbot+b4a2af3000eaa84d95d5@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
---
fs/btrfs/volumes.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 13c514684cfb..eee7471a3e03 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1339,6 +1339,7 @@ struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
struct page *page;
u64 bytenr, bytenr_orig;
struct address_space *mapping = bdev->bd_mapping;
+ struct inode *inode = mapping->host;
int ret;
bytenr_orig = btrfs_sb_offset(copy_num);
@@ -1364,7 +1365,9 @@ struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
(bytenr + BTRFS_SUPER_INFO_SIZE) >> PAGE_SHIFT);
}
+ inode_lock(inode);
page = read_cache_page_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS);
+ inode_unlock(inode);
if (IS_ERR(page))
return ERR_CAST(page);
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2] btrfs: Sync read disk super and set block size
2026-01-09 12:43 ` Filipe Manana
@ 2026-01-09 13:02 ` Edward Adam Davis
2026-01-09 17:21 ` Filipe Manana
2026-01-09 21:04 ` Qu Wenruo
0 siblings, 2 replies; 7+ messages in thread
From: Edward Adam Davis @ 2026-01-09 13:02 UTC (permalink / raw)
To: fdmanana
Cc: clm, dsterba, eadavis, josef, linux-btrfs, linux-kernel,
syzbot+b4a2af3000eaa84d95d5, syzkaller-bugs
When the user performs a btrfs mount, the block device is not set
correctly. The user sets the block size of the block device to 0x4000
by executing the BLKBSZSET command.
Since the block size change also changes the mapping->flags value, this
further affects the result of the mapping_min_folio_order() calculation.
Let's analyze the following two scenarios:
Scenario 1: Without executing the BLKBSZSET command, the block size is
0x1000, and mapping_min_folio_order() returns 0;
Scenario 2: After executing the BLKBSZSET command, the block size is
0x4000, and mapping_min_folio_order() returns 2.
do_read_cache_folio() allocates a folio before the BLKBSZSET command
is executed. This results in the allocated folio having an order value
of 0. Later, after BLKBSZSET is executed, the block size increases to
0x4000, and the mapping_min_folio_order() calculation result becomes 2.
This leads to two undesirable consequences:
1. filemap_add_folio() triggers a VM_BUG_ON_FOLIO(folio_order(folio) <
mapping_min_folio_order(mapping)) assertion.
2. The syzbot report [1] shows a null pointer dereference in
create_empty_buffers() due to a buffer head allocation failure.
Synchronization should be established based on the inode between the
BLKBSZSET command and read cache page to prevent inconsistencies in
block size or mapping flags before and after folio allocation.
[1]
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
RIP: 0010:create_empty_buffers+0x4d/0x480 fs/buffer.c:1694
Call Trace:
folio_create_buffers+0x109/0x150 fs/buffer.c:1802
block_read_full_folio+0x14c/0x850 fs/buffer.c:2403
filemap_read_folio+0xc8/0x2a0 mm/filemap.c:2496
do_read_cache_folio+0x266/0x5c0 mm/filemap.c:4096
do_read_cache_page mm/filemap.c:4162 [inline]
read_cache_page_gfp+0x29/0x120 mm/filemap.c:4195
btrfs_read_disk_super+0x192/0x500 fs/btrfs/volumes.c:1367
Reported-by: syzbot+b4a2af3000eaa84d95d5@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b4a2af3000eaa84d95d5
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
---
v1 -> v2: replace inode lock with invalidate lock
fs/btrfs/volumes.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 13c514684cfb..68ff166fe445 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1364,7 +1364,9 @@ struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
(bytenr + BTRFS_SUPER_INFO_SIZE) >> PAGE_SHIFT);
}
+ filemap_invalidate_lock(mapping);
page = read_cache_page_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS);
+ filemap_invalidate_unlock(mapping);
if (IS_ERR(page))
return ERR_CAST(page);
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2] btrfs: Sync read disk super and set block size
2026-01-09 13:02 ` [PATCH v2] btrfs: Sync read disk super " Edward Adam Davis
@ 2026-01-09 17:21 ` Filipe Manana
2026-01-09 21:04 ` Qu Wenruo
1 sibling, 0 replies; 7+ messages in thread
From: Filipe Manana @ 2026-01-09 17:21 UTC (permalink / raw)
To: Edward Adam Davis
Cc: clm, dsterba, josef, linux-btrfs, linux-kernel,
syzbot+b4a2af3000eaa84d95d5, syzkaller-bugs
On Fri, Jan 9, 2026 at 1:02 PM Edward Adam Davis <eadavis@qq.com> wrote:
>
> When the user performs a btrfs mount, the block device is not set
> correctly. The user sets the block size of the block device to 0x4000
> by executing the BLKBSZSET command.
> Since the block size change also changes the mapping->flags value, this
> further affects the result of the mapping_min_folio_order() calculation.
>
> Let's analyze the following two scenarios:
> Scenario 1: Without executing the BLKBSZSET command, the block size is
> 0x1000, and mapping_min_folio_order() returns 0;
>
> Scenario 2: After executing the BLKBSZSET command, the block size is
> 0x4000, and mapping_min_folio_order() returns 2.
>
> do_read_cache_folio() allocates a folio before the BLKBSZSET command
> is executed. This results in the allocated folio having an order value
> of 0. Later, after BLKBSZSET is executed, the block size increases to
> 0x4000, and the mapping_min_folio_order() calculation result becomes 2.
> This leads to two undesirable consequences:
> 1. filemap_add_folio() triggers a VM_BUG_ON_FOLIO(folio_order(folio) <
> mapping_min_folio_order(mapping)) assertion.
> 2. The syzbot report [1] shows a null pointer dereference in
> create_empty_buffers() due to a buffer head allocation failure.
>
> Synchronization should be established based on the inode between the
> BLKBSZSET command and read cache page to prevent inconsistencies in
> block size or mapping flags before and after folio allocation.
>
> [1]
> KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
> RIP: 0010:create_empty_buffers+0x4d/0x480 fs/buffer.c:1694
> Call Trace:
> folio_create_buffers+0x109/0x150 fs/buffer.c:1802
> block_read_full_folio+0x14c/0x850 fs/buffer.c:2403
> filemap_read_folio+0xc8/0x2a0 mm/filemap.c:2496
> do_read_cache_folio+0x266/0x5c0 mm/filemap.c:4096
> do_read_cache_page mm/filemap.c:4162 [inline]
> read_cache_page_gfp+0x29/0x120 mm/filemap.c:4195
> btrfs_read_disk_super+0x192/0x500 fs/btrfs/volumes.c:1367
>
> Reported-by: syzbot+b4a2af3000eaa84d95d5@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=b4a2af3000eaa84d95d5
> Signed-off-by: Edward Adam Davis <eadavis@qq.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Thanks, I've added it to the for-next branch with minor editing
(uncapitalize the first word in the subject and added some blank lines
for readability):
https://github.com/btrfs/linux/commits/for-next/
> ---
> v1 -> v2: replace inode lock with invalidate lock
>
> fs/btrfs/volumes.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index 13c514684cfb..68ff166fe445 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -1364,7 +1364,9 @@ struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
> (bytenr + BTRFS_SUPER_INFO_SIZE) >> PAGE_SHIFT);
> }
>
> + filemap_invalidate_lock(mapping);
> page = read_cache_page_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS);
> + filemap_invalidate_unlock(mapping);
> if (IS_ERR(page))
> return ERR_CAST(page);
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] btrfs: Sync read disk super and set block size
2026-01-09 13:02 ` [PATCH v2] btrfs: Sync read disk super " Edward Adam Davis
2026-01-09 17:21 ` Filipe Manana
@ 2026-01-09 21:04 ` Qu Wenruo
1 sibling, 0 replies; 7+ messages in thread
From: Qu Wenruo @ 2026-01-09 21:04 UTC (permalink / raw)
To: Edward Adam Davis, fdmanana
Cc: clm, dsterba, josef, linux-btrfs, linux-kernel,
syzbot+b4a2af3000eaa84d95d5, syzkaller-bugs
在 2026/1/9 23:32, Edward Adam Davis 写道:
> When the user performs a btrfs mount, the block device is not set
> correctly.
Explain "the block device is not set correctly", all your later commit
message is showing that it's end user re-setting the device block size.
There is nothing "not set correctly".
> The user sets the block size of the block device to 0x4000
> by executing the BLKBSZSET command.
> Since the block size change also changes the mapping->flags value, this
> further affects the result of the mapping_min_folio_order() calculation.
>
> Let's analyze the following two scenarios:
> Scenario 1: Without executing the BLKBSZSET command, the block size is
> 0x1000, and mapping_min_folio_order() returns 0;
>
> Scenario 2: After executing the BLKBSZSET command, the block size is
> 0x4000, and mapping_min_folio_order() returns 2.
>
> do_read_cache_folio() allocates a folio before the BLKBSZSET command
> is executed. This results in the allocated folio having an order value
> of 0. Later, after BLKBSZSET is executed, the block size increases to
> 0x4000, and the mapping_min_folio_order() calculation result becomes 2.
> This leads to two undesirable consequences:
> 1. filemap_add_folio() triggers a VM_BUG_ON_FOLIO(folio_order(folio) <
> mapping_min_folio_order(mapping)) assertion.
> 2. The syzbot report [1] shows a null pointer dereference in
> create_empty_buffers() due to a buffer head allocation failure.
Although I agree with the analyze so far, I didn't see we should
continue stick to the old read_page_cache_gfp() call.
There is already an old series which will address it pretty well:
https://lore.kernel.org/linux-btrfs/cover.1752097916.git.wqu@suse.com/
Although at that time I'm not aware of the race between blocksize set
and read_page_cache_gfp().
Since btrfs is the last one utilizing this interface, I think it's
better to completely remove it other than bothering the extra locking
requirement.
>
> Synchronization should be established based on the inode between the
> BLKBSZSET command and read cache page to prevent inconsistencies in
> block size or mapping flags before and after folio allocation.
>
> [1]
> KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
> RIP: 0010:create_empty_buffers+0x4d/0x480 fs/buffer.c:1694
> Call Trace:
> folio_create_buffers+0x109/0x150 fs/buffer.c:1802
> block_read_full_folio+0x14c/0x850 fs/buffer.c:2403
> filemap_read_folio+0xc8/0x2a0 mm/filemap.c:2496
> do_read_cache_folio+0x266/0x5c0 mm/filemap.c:4096
> do_read_cache_page mm/filemap.c:4162 [inline]
> read_cache_page_gfp+0x29/0x120 mm/filemap.c:4195
> btrfs_read_disk_super+0x192/0x500 fs/btrfs/volumes.c:1367
>
> Reported-by: syzbot+b4a2af3000eaa84d95d5@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=b4a2af3000eaa84d95d5
> Signed-off-by: Edward Adam Davis <eadavis@qq.com>
Anyway you won't reply to any review/comment, I doubt if you will change
this time.
> ---
> v1 -> v2: replace inode lock with invalidate lock
>
> fs/btrfs/volumes.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index 13c514684cfb..68ff166fe445 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -1364,7 +1364,9 @@ struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
> (bytenr + BTRFS_SUPER_INFO_SIZE) >> PAGE_SHIFT);
> }
>
> + filemap_invalidate_lock(mapping);
> page = read_cache_page_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS);
> + filemap_invalidate_unlock(mapping);
> if (IS_ERR(page))
> return ERR_CAST(page);
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-01-09 21:04 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-08 13:00 [syzbot] [btrfs?] general protection fault in create_empty_buffers (5) syzbot
2026-01-09 11:37 ` [PATCH] btrfs: Sync read disk supper and set block size Edward Adam Davis
2026-01-09 12:43 ` Filipe Manana
2026-01-09 13:02 ` [PATCH v2] btrfs: Sync read disk super " Edward Adam Davis
2026-01-09 17:21 ` Filipe Manana
2026-01-09 21:04 ` Qu Wenruo
2026-01-09 12:56 ` [PATCH] " Edward Adam Davis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox