From nobody Fri Apr 3 01:28:28 2026 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F41003A6F03 for ; Wed, 25 Mar 2026 10:04:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774433065; cv=none; b=hxLS45KqjNJjBXPVSeJD24ZK2clmaHUZc/45anRdnNX1GyHYQ50+nUdk1B6yfp1FBgO3DtwAGaOaiqhVNt628mZEE1F69Oj8nHChc1qrnVo8vbD6P7Bp1f+VkMZ+j59mT0P4IMEVOADi+YXJtDQgc5giDuMeRcB4QUPmYAJFJv4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774433065; c=relaxed/simple; bh=cx6cZUtWXnbgDAYqH526B/SLiBF37AGCrp7peFlOGM4=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=tZpdzx/hg42AtNygV7TCTOiqEj3pNAWEEVmPQVi/Uaf/Ybz1z3ED8sUOLXjFtpGTS6K24GNsJsQxAbKjubk3k3L/R9a07I7wFCle1DHpLDLF8AZysMT866kyZkokUN4Xsl1H0xCXHpDmIUtyTqZyVEYlCv51Sd66+qIXD/UDCRI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=WE5LSPNl; arc=none smtp.client-ip=209.85.216.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WE5LSPNl" Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-35c05d7e0e9so1444050a91.1 for ; Wed, 25 Mar 2026 03:04:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774433062; x=1775037862; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=3Anl9pp+ZGMXwC7XIc0DqbvO58qkRpPIzKB25+EU45M=; b=WE5LSPNlijQ9V9GdFrPQWtfVlBIzpN2/cdEGTbrsBdzE/HzSNX2H3idvqrOZAn45eY JlyHP8LTsgTADfhB2ca/5YZFFFVWR/8C0ZDdjBT7w4tT+8MAtK85jYuLk/smKh9j+uOp aevef8WdOwksgH/uFraG17sCBQLd0cfSUNaOY2WlQQb1rw+m1yLHIDNhB6YNiG+z/Rrk BweGeux3j2YoqDoBEHzv9apUQkDEaATuWRl2km/M3cq/TW6vM9C/56w8bAEz9C/db+nA kDPsEyCGPcCn5NnwTHP0Y3nbPt1svtkdWnwfkcKyqr29f7Pyyua195E2nHk7trtcBBF7 ZCLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774433062; x=1775037862; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=3Anl9pp+ZGMXwC7XIc0DqbvO58qkRpPIzKB25+EU45M=; b=XAT6nlEciPSqv0vdU7aiFchI52MuBujNwdPupGmGXCVY8usdaT2CHR6cyZ5o4XaaB5 oibi7rvkNQ3iuu4BTyXle/g32pDw0JKc9tYykG+jyM5Ae21X18qyeYFgxe+oTGv8DehM fG+GOou/JrgZPhD1l4UG0JBVD7+sW+7ln9sgHdR4RIbqxUAUC0tVTaAlPX8PlK+LZAqB 5w3nevpFmFmpRuZ7+vmUawD0GGGZNYf6siDxAYa7zlRWXX/3R7HmXp+Ctxmpx9E7jyoh pAI9Aohq1rlDXSWGASmOZMCkZ2cfCCK1LjYQR/WIcmZlbMmf1wYrBn3f/ldWQB29h0p5 izxA== X-Forwarded-Encrypted: i=1; AJvYcCVp8/8Z1N9SQ/8QQvJp8TGjSb/mCk0z0Nk2bp657xzsrGOTwBX5dMBgZtF2+QXn7kW9R7Qc9rgczGJzJ2E=@vger.kernel.org X-Gm-Message-State: AOJu0Yw/nud3mFk28gAE27LbIgXoR1xYYA6UoYJ0FZBKUAJYH3aRhQov ltS1YxnN5lx8YC6/MHsgkip7f/bZymaCBgQ6CkxZMHSlKdvXKq/0dkQ2 X-Gm-Gg: ATEYQzxmORcdHIYdUENpo0FwCA0H/EiPpooDtOAReKkRemeu4Buft9I7cDO5IRsfEOl wD4zgVgjSZPKtv2YITS78TsVhSNEELyVYxrsmxPb0mfppMWIOSd5F0LzlR7MhWfcbqFiFJ6psJE lMZW0irJ574EucZm5Ll9894KOaZl8XwUZ/RBB5ztn9lC+VdyP4dphtpkb6U0a4Ms1l024Gorxv7 ScDALVnjG2CEkhNwp4WXV189cEcTynovsaBrOLJsvmrGZbdrF+nRnQ8mBp9hstr8dPt3jVtAbiZ A99ZCjaIudPymY/GNwH2OG2AwnS15R3Tfj0SiV/+DRdZYyyQBd5yiW18kvmDRWigInRy6xlCvqO m9c22EN6kFt93gJHcEuN3kb7GWqkJ89H/kDHtg1LeD5udAo6GAblfCX0bMuHwdLyqvk67lAiDlo fE18ahwA43LgfZocyNZ2j7PT1bqXm+H3xJrSmC6VfnDAsBpijHsjvvTHE30v+TSdXxurq1ox8= X-Received: by 2002:a17:90b:518e:b0:34c:904a:d92 with SMTP id 98e67ed59e1d1-35c0dd7a69cmr2484525a91.26.1774433061926; Wed, 25 Mar 2026 03:04:21 -0700 (PDT) Received: from kernel-fuzz.. ([103.172.182.26]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-35c11deb26esm1398670a91.12.2026.03.25.03.04.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Mar 2026 03:04:21 -0700 (PDT) From: ZhengYuan Huang To: dsterba@suse.com, clm@fb.com, anand.jain@oracle.com, wqu@suse.com Cc: linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org, baijiaju1990@gmail.com, r33s3n6@gmail.com, zzzccc427@gmail.com, ZhengYuan Huang Subject: [PATCH] btrfs: disk-io: reject misaligned tree blocks in btree_csum_one_bio Date: Wed, 25 Mar 2026 18:04:11 +0800 Message-ID: <20260325100411.2483356-1-gality369@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" [BUG] Running btrfs balance on a corrupt image can trigger a GPF, with KASAN reporting a wild memory access: BTRFS warning: tree block not nodesize aligned, start 6179131392 nodesize= 16384, can be resolved by a full metadata balance Oops: general protection fault, probably for non-canonical address 0xe000= 9d1000000052: 0000 [#1] SMP KASAN NOPTI KASAN: maybe wild-memory-access in range [0x0005088000000290-0x0005088000= 000297] Hardware name: QEMU Ubuntu 24.04 PC v2, BIOS 1.16.3-debian-1.16.3-2 RIP: 0010:get_unaligned_le64 include/linux/unaligned.h:28 [inline] RIP: 0010:btrfs_header_bytenr fs/btrfs/accessors.h:647 [inline] RIP: 0010:btree_csum_one_bio+0x175/0xfe0 fs/btrfs/disk-io.c:263 Call Trace: btrfs_bio_csum fs/btrfs/bio.c:511 [inline] btrfs_submit_chunk+0x138d/0x1750 fs/btrfs/bio.c:744 btrfs_submit_bbio+0x20/0x40 fs/btrfs/bio.c:814 write_one_eb+0x9ea/0xd30 fs/btrfs/extent_io.c:2239 btree_write_cache_pages+0x836/0xdc0 fs/btrfs/extent_io.c:2342 btree_writepages+0x163/0x1c0 fs/btrfs/disk-io.c:512 do_writepages+0x255/0x5c0 mm/page-writeback.c:2604 filemap_fdatawrite_wbc mm/filemap.c:389 [inline] filemap_fdatawrite_wbc+0xf2/0x150 mm/filemap.c:379 __filemap_fdatawrite_range+0xd2/0x120 mm/filemap.c:422 filemap_fdatawrite_range+0x2f/0x50 mm/filemap.c:440 btrfs_write_marked_extents+0x13c/0x2d0 fs/btrfs/transaction.c:1157 btrfs_write_and_wait_transaction+0xe5/0x250 fs/btrfs/transaction.c:1264 btrfs_commit_transaction+0x28af/0x3d90 fs/btrfs/transaction.c:2533 insert_balance_item.isra.0+0x392/0x3f0 fs/btrfs/volumes.c:3712 btrfs_balance+0x1021/0x42b0 fs/btrfs/volumes.c:4582 btrfs_ioctl_balance fs/btrfs/ioctl.c:3577 [inline] btrfs_ioctl+0x25cf/0x5b90 fs/btrfs/ioctl.c:5313 ... [CAUSE] The corrupt image contains a tree block whose start address (6179131392) is page-aligned (4 KiB) but NOT nodesize-aligned (16 KiB): 6179131392 % 16384 =3D=3D 4096 When alloc_extent_buffer() is called for such a block, check_eb_alignment() detects the nodesize misalignment, but only emits a one-time btrfs_warn() and returns false without failing the allocation. This allows the extent buffer to be created with a misaligned start. Later, during transaction commit triggered by balance, write_one_eb() submits the dirty extent buffer for writeback, and btree_csum_one_bio() is called to checksum it before I/O submission. That path calls btrfs_header_bytenr(eb), which expands via BTRFS_SETGET_HEADER_FUNCS to: folio_address(eb->folios[0]) + offset_in_page(eb->start) With a nodesize-misaligned start, eb->folios[0] does not correspond to a valid direct-mapped kernel address. folio_address() returns the garbage value 0x0005088000000260, and dereferencing +0x30 (the bytenr field offset in struct btrfs_header) triggers the GPF. [FIX] Add a WARN_ON_ONCE() nodesize alignment check at the beginning of btree_csum_one_bio() and return -EIO for misaligned tree blocks. btree_csum_one_bio() already guards against corrupted extent buffer state on the checksum path, and it also revalidates metadata on the write path. The alignment check follows that pattern and must happen before the first access to eb->folios[] via btrfs_header_bytenr(). Fixes: 6d3a61945b00 ("btrfs: warn on tree blocks which are not nodesize ali= gned") Signed-off-by: ZhengYuan Huang --- An alternative fix of promoting check_eb_alignment() from warn to error would prevent the misaligned eb from being created at all, but would break mount and repair workflows: users need to be able to read and inspect a filesystem containing legacy misaligned tree blocks in order to run "btrfs balance -m" and correct the alignment. --- fs/btrfs/disk-io.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 0aa7e5d1b05f..5ca9e63e51d6 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -260,6 +260,11 @@ int btree_csum_one_bio(struct btrfs_bio *bbio) { struct extent_buffer *eb =3D bbio->private; struct btrfs_fs_info *fs_info =3D eb->fs_info; + + /* A nodesize-misaligned eb has corrupted folio mapping. */ + if (WARN_ON_ONCE(!IS_ALIGNED(eb->start, fs_info->nodesize))) + return -EIO; + u64 found_start =3D btrfs_header_bytenr(eb); u64 last_trans; u8 result[BTRFS_CSUM_SIZE]; --=20 2.43.0