On 2025/12/11 03:32, Prithvi Tambewagh wrote:
When the filesystem is being mounted, the kernel panics while the data regarding slot map allocation to the local node, is being written to the disk. This occurs because the value of slot map buffer head block number, which should have been greater than or equal to `OCFS2_SUPER_BLOCK_BLKNO` (evaluating to 2) is less than it, indicative of disk metadata corruption. This triggers BUG_ON(bh->b_blocknr < OCFS2_SUPER_BLOCK_BLKNO) in ocfs2_write_block(), causing the kernel to panic.
This is fixed by introducing an if condition block in ocfs2_update_disk_slot(), right before calling ocfs2_write_block(), which checks if `bh->b_blocknr` is lesser than `OCFS2_SUPER_BLOCK_BLKNO`; if yes, then ocfs2_error is called, which prints the error log, for debugging purposes, and the return value of ocfs2_error() is returned back to caller of ocfs2_update_disk_slot() i.e. ocfs2_find_slot(). If the return value is zero. then error code EIO is returned.
Reported-by: syzbot+c818e5c4559444f88aa0@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=c818e5c4559444f88aa0 Tested-by: syzbot+c818e5c4559444f88aa0@syzkaller.appspotmail.com Cc: stable@vger.kernel.org Signed-off-by: Prithvi Tambewagh activprithvi@gmail.com
v1->v2:
- Remove usage of le16_to_cpu() from ocfs2_error()
- Cast bh->b_blocknr to unsigned long long
- Remove type casting for OCFS2_SUPER_BLOCK_BLKNO
- Fix Sparse warnings reported in v1 by kernel test robot
- Update title from 'ocfs2: Fix kernel BUG in ocfs2_write_block' to 'ocfs2: fix kernel BUG in ocfs2_write_block'
v1 link: https://lore.kernel.org/all/20251206154819.175479-1-activprithvi@gmail.com/T...
fs/ocfs2/slot_map.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c index e544c704b583..e916a2e8f92d 100644 --- a/fs/ocfs2/slot_map.c +++ b/fs/ocfs2/slot_map.c @@ -193,6 +193,16 @@ static int ocfs2_update_disk_slot(struct ocfs2_super *osb, else ocfs2_update_disk_slot_old(si, slot_num, &bh); spin_unlock(&osb->osb_lock);
- if (bh->b_blocknr < OCFS2_SUPER_BLOCK_BLKNO) {
status = ocfs2_error(osb->sb,"Invalid Slot Map Buffer Head ""Block Number : %llu, Should be >= %d",(unsigned long long)bh->b_blocknr,OCFS2_SUPER_BLOCK_BLKNO);if (!status)return -EIO;return status;- }
status = ocfs2_write_block(osb, bh, INODE_CACHE(si->si_inode)); if (status < 0)
Ummm... The 'bh' is from ocfs2_slot_info, which is load from crafted image during mount. So IIUC, the root cause is we read slot info without validating, see ocfs2_refresh_slot_info(). So I'd prefer to implement a validate func and pass it into ocfs2_read_blocks() to do this job.
Thanks, Joseph