[PATCH RFC] hfs/hfsplus: remove WARN_ON() and fix error handling in hfs_bnode_create

"syzbot" <[email protected]>
Newsgroups dev.linux.lists.syzbot
Message-ID <[email protected]>
When a new btree node needs to be allocated, the filesystem scans the
allocation bitmap to find a free bit. If the filesystem image is corrupted,
the bitmap might incorrectly indicate that an already-used node is free.
This causes hfs_bnode_create() to find that the node is already present in
the in-memory hash table. When this happens, it prints a critical message
and hits a WARN_ON(1).

A corrupted filesystem should fail gracefully with an error code. WARN_ON()
must not be used for conditions that can legitimately happen due to
corrupted images, and pr_err() should be used instead.

Recently, commit d8a73cc46c84 ("hfsplus: return error when node already
exists in hfs_bnode_create") changed hfs_bnode_create() in
fs/hfsplus/bnode.c to return ERR_PTR(-EEXIST) instead of returning the
existing node, but left the WARN_ON(1) in place. Furthermore, the exact
same bug exists in the older hfs filesystem (fs/hfs/bnode.c), which was not
fixed by that commit. In fs/hfs/bnode.c, hfs_bnode_create() still triggers
the WARN_ON(1) and returns the existing node without incrementing its
refcount, which leads to a BUG_ON(!atomic_read(&node->refcnt)) in
hfs_bnode_put() and corrupts the btree in memory.

Fix this by removing the WARN_ON(1) in both fs/hfs/bnode.c and
fs/hfsplus/bnode.c, downgrading the log message from pr_crit() to pr_err(),
and changing the return value in fs/hfs/bnode.c to ERR_PTR(-EEXIST) to
align with the hfsplus implementation.

hfsplus: new node 0 already hashed?
WARNING: fs/hfsplus/bnode.c:634 at hfsplus_bnode_create+0x45d/0x4f0
fs/hfsplus/bnode.c:634
...
Call Trace:
 <TASK>
 hfs_bnode_split+0xd2/0x1090 fs/hfsplus/brec.c:248
 hfsplus_brec_insert+0x3bc/0xd70 fs/hfsplus/brec.c:100
 hfsplus_create_cat+0xa64/0x11f0 fs/hfsplus/catalog.c:308
 hfsplus_mknod+0x186/0x3f0 fs/hfsplus/dir.c:538
 hfsplus_mkdir+0x2c/0x40 fs/hfsplus/dir.c:579
 vfs_mkdir+0x40b/0x630 fs/namei.c:5271
 filename_mkdirat+0x289/0x520 fs/namei.c:5304
 __do_sys_mkdirat fs/namei.c:5325 [inline]
 __se_sys_mkdirat+0x35/0x150 fs/namei.c:5322
 </TASK>

Fixes: d8a73cc46c84 ("hfsplus: return error when node already exists in hfs_bnode_create")
Assisted-by: Gemini:gemini-3.1-pro-preview syzbot
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=2bf21610eea63cb2ce93
Link: https://syzkaller.appspot.com/ai_job?id=7b105f12-f88e-46a6-9fc6-e0df3a1532e4
To: "Yangtao Li" <[email protected]>
To: "John Paul Adrian Glaubitz" <[email protected]>
To: <[email protected]>
To: "Viacheslav Dubeyko" <[email protected]>
Cc: <[email protected]>

---
diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c
index 13d58c51f..3c49f6c64 100644
--- a/fs/hfs/bnode.c
+++ b/fs/hfs/bnode.c
@@ -516,9 +516,8 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num)
 	node = hfs_bnode_findhash(tree, num);
 	spin_unlock(&tree->hash_lock);
 	if (node) {
-		pr_crit("new node %u already hashed?\n", num);
-		WARN_ON(1);
-		return node;
+		pr_err("new node %u already hashed?\n", num);
+		return ERR_PTR(-EEXIST);
 	}
 	node = __hfs_bnode_create(tree, num);
 	if (!node)
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
index f8b5a8ae5..2375b8f21 100644
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -630,8 +630,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num)
 	node = hfs_bnode_findhash(tree, num);
 	spin_unlock(&tree->hash_lock);
 	if (node) {
-		pr_crit("new node %u already hashed?\n", num);
-		WARN_ON(1);
+		pr_err("new node %u already hashed?\n", num);
 		return ERR_PTR(-EEXIST);
 	}
 	node = __hfs_bnode_create(tree, num);


base-commit: 4549871118cf616eecdd2d939f78e3b9e1dddc48
-- 
This is an AI-generated patch subject to moderation.
Reply with '#syz upstream' to Sign-off the patch as a human author
and send it to the upstream kernel mailing lists.
Reply with '#syz reject' to reject it ('#syz unreject' to undo).

See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
You can comment on the patch as usual, syzbot will try to address
the comments and send a new version of the patch if necessary.
syzbot engineers can be reached at [email protected].
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.