Re: [PATCH 2/2] hfs/hfsplus: stop btree allocators from reusing node 0
Viacheslav Dubeyko <[email protected]>
| Newsgroups | org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On Fri, 2026-08-14 at 10:31 +0800, Tao Yu wrote: > The btree header node is permanently reserved as node 0. If the on- > disk > bitmap ever presents node 0 as free, the filesystem is already > corrupted and the allocator must not try to instantiate it again. > > Both HFS and HFS+ currently keep scanning the bitmap, set the bit, > and > hand node 0 to hfs_bnode_create()/hfsplus_bnode_create(). HFS+ then > hits the "new node 0 already hashed?" warning reported by syzbot, > while > HFS risks continuing after the same corruption pattern. > > Teach both allocators to treat attempts to allocate node 0 as btree > map > corruption. Force the filesystem read-only, emit the existing repair > hint, and abort the allocation before the code reaches the hashed- > node > warning. > > Reported-by: [email protected] > Closes: https://syzkaller.appspot.com/bug?extid=2bf21610eea63cb2ce93 > Signed-off-by: Tao Yu <[email protected]> > --- > fs/hfs/btree.c | 11 +++++++++++ > fs/hfsplus/btree.c | 11 +++++++++++ > 2 files changed, 22 insertions(+) > > diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c > index 14114318ec724..9b0b7418ddbd5 100644 > --- a/fs/hfs/btree.c > +++ b/fs/hfs/btree.c > @@ -376,6 +376,17 @@ 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)) { > + if (unlikely(!(idx + > i))) { > + pr_warn("(%s > ): %s (cnid 0x%x) map record invalid or bitmap corruption detected, > forcing read-only.\n", > + tree > ->sb->s_id, > + hfs_ > btree_name(tree->cnid), > + tree > ->cnid); > + pr_warn("Run > fsck.hfs to repair.\n"); > + tree->sb- > >s_flags |= SB_RDONLY; > + kunmap_local > (data); > + hfs_bnode_pu > t(node); > + return > ERR_PTR(-EIO); > + } > idx += i; > data[off] |= m; > set_page_dirty(*page > p); > diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c > index 394542a47e600..3ee92248b2409 100644 > --- a/fs/hfsplus/btree.c > +++ b/fs/hfsplus/btree.c > @@ -561,6 +561,17 @@ 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)) { > + if (unlikely(!(idx + > i))) { > + pr_warn("(%s > ): %s (cnid 0x%x) map record invalid or bitmap corruption detected, > forcing read-only.\n", > + tree > ->sb->s_id, > + hfs_ > btree_name(tree->cnid), > + tree > ->cnid); > + pr_warn("Run > fsck.hfsplus to repair.\n"); > + tree->sb- > >s_flags |= SB_RDONLY; > + kunmap_local > (data); > + hfs_bnode_pu > t(node); > + return > ERR_PTR(-EIO); > + } > idx += i; > data[ctx.off] |= m; > set_page_dirty(page) > ; We already have check [1] in hfs_btree_open(): if (!hfs_bmap_test_bit(node, 0)) { pr_warn("(%s): %s (cnid 0x%x) map record invalid or bitmap corruption detected, forcing read-only.\n", sb->s_id, hfs_btree_name(id), id); pr_warn("Run fsck.hfsplus to repair.\n"); sb->s_flags |= SB_RDONLY; } The likewise check has been implemented by patch [2] for HFS. Thanks, Slava. [1] https://elixir.bootlin.com/linux/v7.2-rc6/source/fs/hfsplus/btree.c#L388 [2] https://lore.kernel.org/r/[email protected]