[PATCH 2/3] ocfs2: handle invalid dinode in claim_suballoc_bits
From: ZhengYuan Huang
Date: Fri Apr 03 2026 - 02:31:36 EST
[BUG]
A crafted filesystem can feed an invalid dinode into
ocfs2_claim_suballoc_bits() and trip:
kernel BUG at fs/ocfs2/suballoc.c:1966
[CAUSE]
ocfs2_claim_suballoc_bits() trusts ac->ac_bh, but that buffer is not
limited to the reserve_suballoc_bits() path: local allocation can also
hand in osb->local_alloc_bh directly. JBD-managed buffers can bypass
inode validation, so invalid dinode data can still reach this function.
[FIX]
Report an invalid dinode as filesystem corruption and unwind through the
existing bail path instead of BUG()ing. This keeps the allocation logic
unchanged while removing the fatal failure mode.
Fixes: 10995aa2451a ("ocfs2: Morph the haphazard OCFS2_IS_VALID_DINODE() checks.")
Signed-off-by: ZhengYuan Huang <gality369@xxxxxxxxx>
---
fs/ocfs2/suballoc.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 12ac2bb3f10b..b99870aeaf88 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -1965,9 +1965,13 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac,
fe = (struct ocfs2_dinode *) ac->ac_bh->b_data;
- /* The bh was validated by the inode read during
- * ocfs2_reserve_suballoc_bits(). Any corruption is a code bug. */
- BUG_ON(!OCFS2_IS_VALID_DINODE(fe));
+ /* JBD-managed buffers can bypass inode validation. */
+ if (!OCFS2_IS_VALID_DINODE(fe)) {
+ status = ocfs2_error(ac->ac_inode->i_sb,
+ "Invalid dinode #%llu\n",
+ (unsigned long long)OCFS2_I(ac->ac_inode)->ip_blkno);
+ goto bail;
+ }
if (le32_to_cpu(fe->id1.bitmap1.i_used) >=
le32_to_cpu(fe->id1.bitmap1.i_total)) {
--
2.43.0