From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f181.google.com (mail-pl1-f181.google.com [209.85.214.181]) (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 1E30738736A for ; Thu, 9 Apr 2026 08:11:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.181 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775722318; cv=none; b=JKB8u6v3wr/Uroyrv+G+E6IoU/NBjzRCkIHv9lrg6nfWcA2ggxrqCfD1AoivDuKY/Pd63S4TX63E8+NE1aW9Eh7RZgVz8XwS81MXMQa/KfF690JkQinoMrzdh4Op9PXaHJBpNw8ttqb+dbntmjiJzdDBZciATYYljzpUz8VDB14= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775722318; c=relaxed/simple; bh=4FmYzVSLwZ4TOjkqmnh54MQ8cMq8i1uy4Ite11pD2oU=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=ogCkBeIS06hbyMh8wmiwkVuuZvUw0suU5YUv7zJm2UGrYAVA1Ktra4zc097sleUArdztpUqEvO2WVS5ynuX8GHSi2BYXs1WhiVL/YQdu5wFGVvocLjuUal1dDCTYvCZhTGxfkprGLyXq0DkL3jjjcihnqvHAEetO3ZxiVf+6Ajk= 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=HfEOEJ0L; arc=none smtp.client-ip=209.85.214.181 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="HfEOEJ0L" Received: by mail-pl1-f181.google.com with SMTP id d9443c01a7336-2b258576d8cso4080475ad.0 for ; Thu, 09 Apr 2026 01:11:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775722316; x=1776327116; 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=4nsehLI9jIB2pvtAUMLCIGtoJBjqHEt2917WeRtwqXk=; b=HfEOEJ0L5kpWcGo/ia96LqjbvwlwVEfUjvP1k4gBLNUCmT0tpV00CzEIvnf+SiKhMe 3bkTWDF3bQYPCefcOAm511jaEu4Zj/731W76M0/8Lf/F9vH3eekTLbQkGduAlF10gfBy swyyE3AQVzlsCi3SpbRBVhj7KaCDwQ+dmiS0Dy1KKIXwxAkgbzQFV+01ydT3k3Erh0AQ 8aNGF2fvRXV3WsebAKg8BitR7FMmxbBUbpcRJ7otvhbf4N6GjRuZynNNjBUCQf/Wfnf6 sN97cKtGptS7ms/4H9JEmCVrsMztobo1H5KOTWa0oDeWNcpas4pzYk6igJiKi8k+9hgp oArg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775722316; x=1776327116; 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=4nsehLI9jIB2pvtAUMLCIGtoJBjqHEt2917WeRtwqXk=; b=hbWEuprsBs7tbH+3aCbBFv5raVPNeVO0LZ9punHF2h7YsZa9I5y/ZnMn+256FJvm+E ug4EKngh9zyEf/HyEsmtjqkjWSske1PocEWvBJoXnzdH5+u3f8awKDBjZRs7OG9itGgN yj21irQ3uUe+yy1lehpiC4g1nlTidaoyKVDjw7Iuc0LOyUzWtQSszo+T/C8EquLVUErg hnlsbtX9ErlcOKYze/qYKLWNWXnLZXzfX7xZbm5kxZuwbpRiK0jdWBTh+0DFBOv5Gcd4 GwufXNOwm1TINHvLGS2XJGgC8U+zd4kn3/Up3wSX9RxrEVNQmEXoK689D0s5rWrC6dQ6 Z3wA== X-Forwarded-Encrypted: i=1; AJvYcCXb9J/pcIrCnkzlCxdfxh13MqsZOgdiLDh1Ry8o3YOHEOe3N2idtDfUT5mGOAWj6nzMsm+ejr1g8o0NuSM=@vger.kernel.org X-Gm-Message-State: AOJu0YzHRl84v2/S0A1GWLGpNVhJAOXjENE/iMegyzy6SzFMuCE1cqi2 Z46eKJhHMvCTkXIWbx+qrS8s+wGX67pDqbDIg8FCZQEFEaQMr8UcQNGr/cSJTtoPdAU= X-Gm-Gg: AeBDiesnlqWB993vwj+5SfVeS20sP+3z98yCJpyu9o+R5ik5qbubfLHCERvIVYdpreF 02qukaK15IYal8BShOr/7+uEUYGdRtQxqbyG8L/hpxN0Og/fc3JuGYI/59CBiNE5nxlcyGirPyh XnFYPGuCWuhXeDcKjUPdHOQMolHS4cTapj+mB5j3I6LhG0kdYkMJJ2m+IcH2LTNQlLDiV9ju5p8 BhIr7m3mEMusVf63DFzvAtaWp+rlA/ksW8vz9kARsW10YifzNNQQNzeb81TcnRkO/yUO771s0BS 1cjFWXtdPlu5Dc8JXNnHGKKJUK/lttcz4WSUcY9TUCGjOKYmTAmQ/dawdcPh4dCXizAVXMHCsIQ dQg0Eynvj4MNPGcj5NQYaSvDpbZAKaM+Z7Ah7fglHZTXBjQ+CLNj68bA7O5to4TWClDr81J5W3w e0ZqbzUYantAiR6Lo/CDSJQi8nLfZ+SSNLGi6DOv8a0T7rDVOIWpVhE6nEG8L0KdvumJj8Rj+T3 aWiCNwQ X-Received: by 2002:a17:903:38cf:b0:2b2:ccfb:8387 with SMTP id d9443c01a7336-2b2ccfb8623mr10523125ad.28.1775722316202; Thu, 09 Apr 2026 01:11:56 -0700 (PDT) Received: from kernel-fuzz.. ([138.199.21.245]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2b27478bc96sm239544935ad.33.2026.04.09.01.11.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Apr 2026 01:11:55 -0700 (PDT) From: ZhengYuan Huang To: dsterba@suse.com, clm@fb.com, zheng.yan@oracle.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 v2] btrfs: reject empty non-root tree blocks at read time Date: Thu, 9 Apr 2026 16:11:40 +0800 Message-ID: <20260409081140.3400650-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: 8bit [BUG] A corrupted tree can contain an empty non-root tree block linked from its parent. If that block is later used by normal tree balancing, btrfs can hit: kernel BUG at fs/btrfs/ctree.c:3388! Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI RIP: 0010:__push_leaf_left+0x11f8/0x1610 fs/btrfs/ctree.c:3388 Code: ff48c1ea 03803c02 000f85bd 00000048 Call Trace: push_leaf_left+0x3b3/0x540 fs/btrfs/ctree.c:3511 btrfs_del_items+0x74d/0xf10 fs/btrfs/ctree.c:4541 btrfs_del_csums+0x44d/0xa50 fs/btrfs/file-item.c:969 do_free_extent_accounting fs/btrfs/extent-tree.c:2984 [inline] __btrfs_free_extent.isra.0+0xded/0x41d0 fs/btrfs/extent-tree.c:3372 run_delayed_data_ref fs/btrfs/extent-tree.c:1599 [inline] run_one_delayed_ref fs/btrfs/extent-tree.c:1779 [inline] btrfs_run_delayed_refs_for_head fs/btrfs/extent-tree.c:1972 [inline] __btrfs_run_delayed_refs+0x86e/0x39a0 fs/btrfs/extent-tree.c:2047 btrfs_run_delayed_refs+0x181/0x420 fs/btrfs/extent-tree.c:2159 btrfs_commit_transaction+0xc9b/0x3d90 fs/btrfs/transaction.c:2211 btrfs_sync_fs+0xf0/0x630 fs/btrfs/super.c:1057 sync_fs_one_sb fs/sync.c:84 [inline] sync_fs_one_sb+0xf4/0x140 fs/sync.c:80 __iterate_supers+0x1be/0x290 fs/super.c:923 iterate_supers+0x24/0x40 fs/super.c:938 ksys_sync+0xb4/0x160 fs/sync.c:104 __do_sys_sync+0x13/0x20 fs/sync.c:113 ... [CAUSE] The old btrfs_verify_level_key() path rejected tree blocks with nritems == 0 whenever the parent check provided a first key. Commit 947a629988f1 ("btrfs: move tree block parentness check into validate_extent_buffer()") moved the parentness checks into the read-time validation path, but it dropped that guard. This lets an empty non-root tree block pass read-time validation even though slot 0 must exist if the parent provides a first key. [FIX] Restore the nritems == 0 rejection in btrfs_validate_extent_buffer() when check->has_first_key is set. This rejects empty non-root tree blocks as soon as they are read from disk, before later btree operations can hit BUG_ONs while trying to use them. Fixes: 947a629988f1 ("btrfs: move tree block parentness check into validate_extent_buffer()") Signed-off-by: ZhengYuan Huang --- v2: - Move the corruption check from push_leaf_left() to read-time validation - Restore the old nritems == 0 guard before reading slot 0 fs/btrfs/disk-io.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 0aa7e5d1b05f..ab2044d83155 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -430,6 +430,15 @@ int btrfs_validate_extent_buffer(struct extent_buffer *eb, const struct btrfs_key *expect_key = &check->first_key; struct btrfs_key found_key; + /* We have @first_key, so this @eb must have at least one item. */ + if (unlikely(btrfs_header_nritems(eb) == 0)) { + btrfs_err(fs_info, + "invalid tree nritems, bytenr=%llu nritems=0 expect >0", + eb->start); + ret = -EUCLEAN; + goto out; + } + if (found_level) btrfs_node_key_to_cpu(eb, &found_key, 0); else -- 2.43.0