Commit f2729827 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull nilfs2 updates from Viacheslav Dubeyko:
 "This contains fixes of syzbot reported issues in NILFS2 functionality:

   - The DAT inode's btree node cache (i_assoc_inode) is initialized
     lazily during btree operations.

     However, nilfs_mdt_save_to_shadow_map() assumes i_assoc_inode is
     already initialized when copying dirty pages to the shadow map
     during GC. If NILFS_IOCTL_CLEAN_SEGMENTS is called immediately
     after mount before any btree operation has occurred on the DAT
     inode, i_assoc_inode is NULL leading to a general protection fault.

     Fix this by calling nilfs_attach_btree_node_cache() on the DAT
     inode in nilfs_dat_read() at mount time, ensuring i_assoc_inode is
     always initialized before any GC operation can use it (Deepanshu
     Kartikey)

   - nilfs_ioctl_mark_blocks_dirty() uses bd_oblocknr to detect dead
     blocks by comparing it with the current block number bd_blocknr. If
     they differ, the block is considered dead and skipped.

     A corrupted ioctl request with bd_oblocknr set to 0 causes the
     comparison to incorrectly match when the lookup returns -ENOENT and
     sets bd_blocknr to 0, bypassing the dead block check and calling
     nilfs_bmap_mark() on a non- existent block. This causes
     nilfs_btree_do_lookup() to return -ENOENT, triggering the
     WARN_ON(ret == -ENOENT).

     Fix this by rejecting ioctl requests with bd_oblocknr set to 0 at
     the beginning of each iteration (Deepanshu Kartikey)"

* tag 'nilfs2-v7.1-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/nilfs2:
  nilfs2: reject zero bd_oblocknr in nilfs_ioctl_mark_blocks_dirty()
  nilfs2: fix NULL i_assoc_inode dereference in nilfs_mdt_save_to_shadow_map
parents 4d998142 be3e5d10
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -524,6 +524,9 @@ int nilfs_dat_read(struct super_block *sb, size_t entry_size,
	if (err)
		goto failed;

	err = nilfs_attach_btree_node_cache(dat);
	if (err)
		goto failed;
	err = nilfs_read_inode_common(dat, raw_inode);
	if (err)
		goto failed;
+6 −0
Original line number Diff line number Diff line
@@ -736,6 +736,12 @@ static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
	int ret, i;

	for (i = 0; i < nmembs; i++) {
		/*
		 * bd_oblocknr must never be 0 as block 0
		 * is never a valid GC target block
		 */
		if (unlikely(!bdescs[i].bd_oblocknr))
			return -EINVAL;
		/* XXX: use macro or inline func to check liveness */
		ret = nilfs_bmap_lookup_at_level(bmap,
						 bdescs[i].bd_offset,