Node 0 is the header node in HFS+ B-trees and should always be allocated. However, if a filesystem image has node 0's bitmap bit unset (e.g., due to corruption or a buggy image generator), hfs_bmap_alloc() will find node 0 as free and attempt to allocate it. This causes a conflict because node 0 already exists as the header node, leading to a WARN_ON(1) in hfs_bnode_create() when the node is found already hashed.
This issue can occur with syzkaller-generated HFS+ images or corrupted real-world filesystems. Add a guard in hfs_bmap_alloc() to skip node 0 during allocation, providing defense-in-depth against such corruption.
Reported-by: syzbot+1c8ff72d0cd8a50dfeaa@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=1c8ff72d0cd8a50dfeaa Signed-off-by: Shardul Bankar shardul.b@mpiricsoftware.com --- v2: - Keep the node-0 allocation guard as targeted hardening for corrupted images. fs/hfsplus/btree.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c index 229f25dc7c49..60985f449450 100644 --- a/fs/hfsplus/btree.c +++ b/fs/hfsplus/btree.c @@ -411,6 +411,9 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) if (byte != 0xff) { for (m = 0x80, i = 0; i < 8; m >>= 1, i++) { if (!(byte & m)) { + /* Skip node 0 (header node, always allocated) */ + if (idx == 0 && i == 0) + continue; idx += i; data[off] |= m; set_page_dirty(*pagep);