Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ocfs2: add validate function for slot map blocks

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 function ocfs2_validate_slot_map_block() to
validate slot map blocks. It first checks if the buffer head passed to it
is up to date and valid, else it panics the kernel at that point itself.
Further, it contains an if condition 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. If the if condition is
false, value 0 is returned by ocfs2_validate_slot_map_block().

This function is used as validate function in calls to ocfs2_read_blocks()
in ocfs2_refresh_slot_info() and ocfs2_map_slot_buffers().

Link: https://lkml.kernel.org/r/20251215184600.13147-1-activprithvi@gmail.com
Signed-off-by: Prithvi Tambewagh <activprithvi@gmail.com>
Reported-by: syzbot+c818e5c4559444f88aa0@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=c818e5c4559444f88aa0
Tested-by: <syzbot+c818e5c4559444f88aa0@syzkaller.appspotmail.com>
Reviewed-by: Heming Zhao <heming.zhao@suse.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Prithvi Tambewagh and committed by
Andrew Morton
4e9f69c0 d3cd8de2

+25 -2
+25 -2
fs/ocfs2/slot_map.c
··· 44 44 static int __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 45 45 unsigned int node_num); 46 46 47 + static int ocfs2_validate_slot_map_block(struct super_block *sb, 48 + struct buffer_head *bh); 49 + 47 50 static void ocfs2_invalidate_slot(struct ocfs2_slot_info *si, 48 51 int slot_num) 49 52 { ··· 135 132 * this is not true, the read of -1 (UINT64_MAX) will fail. 136 133 */ 137 134 ret = ocfs2_read_blocks(INODE_CACHE(si->si_inode), -1, si->si_blocks, 138 - si->si_bh, OCFS2_BH_IGNORE_CACHE, NULL); 135 + si->si_bh, OCFS2_BH_IGNORE_CACHE, 136 + ocfs2_validate_slot_map_block); 139 137 if (ret == 0) { 140 138 spin_lock(&osb->osb_lock); 141 139 ocfs2_update_slot_info(si); ··· 336 332 return ocfs2_update_disk_slot(osb, osb->slot_info, slot_num); 337 333 } 338 334 335 + static int ocfs2_validate_slot_map_block(struct super_block *sb, 336 + struct buffer_head *bh) 337 + { 338 + int rc; 339 + 340 + BUG_ON(!buffer_uptodate(bh)); 341 + 342 + if (bh->b_blocknr < OCFS2_SUPER_BLOCK_BLKNO) { 343 + rc = ocfs2_error(sb, 344 + "Invalid Slot Map Buffer Head " 345 + "Block Number : %llu, Should be >= %d", 346 + (unsigned long long)bh->b_blocknr, 347 + OCFS2_SUPER_BLOCK_BLKNO); 348 + return rc; 349 + } 350 + return 0; 351 + } 352 + 339 353 static int ocfs2_map_slot_buffers(struct ocfs2_super *osb, 340 354 struct ocfs2_slot_info *si) 341 355 { ··· 405 383 406 384 bh = NULL; /* Acquire a fresh bh */ 407 385 status = ocfs2_read_blocks(INODE_CACHE(si->si_inode), blkno, 408 - 1, &bh, OCFS2_BH_IGNORE_CACHE, NULL); 386 + 1, &bh, OCFS2_BH_IGNORE_CACHE, 387 + ocfs2_validate_slot_map_block); 409 388 if (status < 0) { 410 389 mlog_errno(status); 411 390 goto bail;