[PATCH] ocfs2: Fix kernel BUG in ocfs2_write_block

Prithvi Tambewagh posted 1 patch 1 week, 5 days ago
fs/ocfs2/slot_map.c | 10 ++++++++++
1 file changed, 10 insertions(+)
[PATCH] ocfs2: Fix kernel BUG in ocfs2_write_block
Posted by Prithvi Tambewagh 1 week, 5 days ago
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>
---
 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..788924fc3663 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",
+				     le16_to_cpu(bh->b_blocknr),
+				     le16_to_cpu((int)OCFS2_SUPER_BLOCK_BLKNO));
+		if (!status)
+			return -EIO;
+		return status;
+	}
 
 	status = ocfs2_write_block(osb, bh, INODE_CACHE(si->si_inode));
 	if (status < 0)

base-commit: 24172e0d79900908cf5ebf366600616d29c9b417
-- 
2.43.0
Re: [PATCH] ocfs2: Fix kernel BUG in ocfs2_write_block
Posted by kernel test robot 1 week, 3 days ago
Hi Prithvi,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 24172e0d79900908cf5ebf366600616d29c9b417]

url:    https://github.com/intel-lab-lkp/linux/commits/Prithvi-Tambewagh/ocfs2-Fix-kernel-BUG-in-ocfs2_write_block/20251206-235042
base:   24172e0d79900908cf5ebf366600616d29c9b417
patch link:    https://lore.kernel.org/r/20251206154819.175479-1-activprithvi%40gmail.com
patch subject: [PATCH] ocfs2: Fix kernel BUG in ocfs2_write_block
config: loongarch-randconfig-r112-20251207 (https://download.01.org/0day-ci/archive/20251209/202512090210.evJEJv5b-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 12.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251209/202512090210.evJEJv5b-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512090210.evJEJv5b-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> fs/ocfs2/slot_map.c:197:26: sparse: sparse: cast to restricted __le16
>> fs/ocfs2/slot_map.c:197:26: sparse: sparse: cast to restricted __le16

vim +197 fs/ocfs2/slot_map.c

   182	
   183	static int ocfs2_update_disk_slot(struct ocfs2_super *osb,
   184					  struct ocfs2_slot_info *si,
   185					  int slot_num)
   186	{
   187		int status;
   188		struct buffer_head *bh;
   189	
   190		spin_lock(&osb->osb_lock);
   191		if (si->si_extended)
   192			ocfs2_update_disk_slot_extended(si, slot_num, &bh);
   193		else
   194			ocfs2_update_disk_slot_old(si, slot_num, &bh);
   195		spin_unlock(&osb->osb_lock);
   196		if (bh->b_blocknr < OCFS2_SUPER_BLOCK_BLKNO) {
 > 197			status = ocfs2_error(osb->sb,
   198					     "Invalid Slot Map Buffer Head "
   199					     "Block Number : %llu, Should be >= %d",
   200					     le16_to_cpu(bh->b_blocknr),
   201					     le16_to_cpu((int)OCFS2_SUPER_BLOCK_BLKNO));
   202			if (!status)
   203				return -EIO;
   204			return status;
   205		}
   206	
   207		status = ocfs2_write_block(osb, bh, INODE_CACHE(si->si_inode));
   208		if (status < 0)
   209			mlog_errno(status);
   210	
   211		return status;
   212	}
   213	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki