Re: [PATCH] btrfs: do not check support for an invalid sectorsize
From: Qu Wenruo
Date: Mon Nov 02 2026 - 18:43:05 EST
在 2026/11/3 10:00, Siddharth Mishra 写道:
From: Siddharth Mishra <brightprogrammer@xxxxxxx>
[BUG]
Mounting an image whose super block has an invalid sectorsize (for
example 4097) on a kernel with CONFIG_BTRFS_ASSERT=y triggers a BUG:
BTRFS error (device loop0): invalid sectorsize 4097
assertion failed: is_power_of_2(blocksize) &&
blocksize >= BTRFS_MIN_BLOCKSIZE && blocksize <= BTRFS_MAX_BLOCKSIZE,
in fs/btrfs/fs.c:137
kernel BUG at fs/btrfs/fs.c:137!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
RIP: 0010:btrfs_supported_blocksize.cold (fs/btrfs/fs.c:137)
Call Trace:
btrfs_validate_super (fs/btrfs/disk-io.c:2525)
open_ctree (fs/btrfs/disk-io.c:3507)
btrfs_get_tree.cold (fs/btrfs/super.c:2133)
vfs_get_tree (fs/super.c:1943)
fc_mount (fs/namespace.c:1282)
path_mount (fs/namespace.c:4337)
__x64_sys_mount (fs/namespace.c:4542)
[CAUSE]
btrfs_validate_super() rejects the sectorsize because it is not a power
of 2, but it does not stop there: it goes on to report all invalid
fields. The next check passes the same sectorsize to
btrfs_supported_blocksize(), which requires a validated value and
asserts it since commit d728f2e5f8a0 ("btrfs: simplify support block
size check").
[FIX]
Only check whether a sectorsize is supported after it passed the
validity check. An invalid sectorsize is still rejected with -EINVAL,
and the misleading second message "sectorsize 4097 not yet supported"
is no longer printed.
This bug was found by fuzzing. The cause was analysed and the fix was
written with the help of an AI tool. Tested on btrfs for-next
(d6f76ca0a70d) and on v7.4-rc1, with KASAN and CONFIG_BTRFS_ASSERT=y:
without the fix, mounting the image hits the BUG above; with the fix,
the mount fails with -EINVAL and only "invalid sectorsize 4097" is
printed.
A crafted image (22 KiB, xz) and a C reproducer are available on request.
Fixes: d728f2e5f8a0 ("btrfs: simplify support block size check")
Cc: stable@xxxxxxxxxxxxxxx # 6.18+
Signed-off-by: Siddharth Mishra <brightprogrammer@xxxxxxx>
---
fs/btrfs/disk-io.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 8e8fb942d..b348591f8 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2520,9 +2520,7 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
sectorsize > BTRFS_MAX_METADATA_BLOCKSIZE)) {
btrfs_err(fs_info, "invalid sectorsize %u", sectorsize);
ret = -EINVAL;
- }
-
- if (unlikely(!btrfs_supported_blocksize(sectorsize))) {
+ } else if (unlikely(!btrfs_supported_blocksize(sectorsize))) {
If you want to change this, you should touch all callsites.
Not only this one, but every unlikely() branch to return immediately.
I do not like the ad-hoc fix just be cause you can trigger an ASSERT().
btrfs_err(fs_info,
"sectorsize %u not yet supported for page size %lu",
sectorsize, PAGE_SIZE);
base-commit: d6f76ca0a70d0c814731394a625ff0dc1feb390e