Unverified Commit 0e54c3f3 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11827 CVE-2024-46781

Merge Pull Request from: @ci-robot 
 
PR sync from: Zeng Heng <zengheng4@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/VM4MKLDMRR33QUJMHVXUUX7LAH5LVBNK/ 
Ryusuke Konishi (2):
  nilfs2: fix use-after-free of nilfs_root in dirtying inodes via iput
  nilfs2: fix missing cleanup on rollforward recovery error


--
2.25.1
 
https://gitee.com/src-openeuler/kernel/issues/IARYB6 
 
Link:https://gitee.com/openeuler/kernel/pulls/11827

 

Reviewed-by: default avatarXie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parents 4a3dd177 5fbea955
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1085,9 +1085,17 @@ int nilfs_set_file_dirty(struct inode *inode, unsigned int nr_dirty)

int __nilfs_mark_inode_dirty(struct inode *inode, int flags)
{
	struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
	struct buffer_head *ibh;
	int err;

	/*
	 * Do not dirty inodes after the log writer has been detached
	 * and its nilfs_root struct has been freed.
	 */
	if (unlikely(nilfs_purging(nilfs)))
		return 0;

	err = nilfs_load_inode_block(inode, &ibh);
	if (unlikely(err)) {
		nilfs_warn(inode->i_sb,
+33 −2
Original line number Diff line number Diff line
@@ -708,6 +708,33 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs,
	brelse(bh);
}

/**
 * nilfs_abort_roll_forward - cleaning up after a failed rollforward recovery
 * @nilfs: nilfs object
 */
static void nilfs_abort_roll_forward(struct the_nilfs *nilfs)
{
	struct nilfs_inode_info *ii, *n;
	LIST_HEAD(head);

	/* Abandon inodes that have read recovery data */
	spin_lock(&nilfs->ns_inode_lock);
	list_splice_init(&nilfs->ns_dirty_files, &head);
	spin_unlock(&nilfs->ns_inode_lock);
	if (list_empty(&head))
		return;

	set_nilfs_purging(nilfs);
	list_for_each_entry_safe(ii, n, &head, i_dirty) {
		spin_lock(&nilfs->ns_inode_lock);
		list_del_init(&ii->i_dirty);
		spin_unlock(&nilfs->ns_inode_lock);

		iput(&ii->vfs_inode);
	}
	clear_nilfs_purging(nilfs);
}

/**
 * nilfs_salvage_orphan_logs - salvage logs written after the latest checkpoint
 * @nilfs: nilfs object
@@ -766,15 +793,19 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs,
		if (unlikely(err)) {
			nilfs_err(sb, "error %d writing segment for recovery",
				  err);
			goto failed;
			goto put_root;
		}

		nilfs_finish_roll_forward(nilfs, ri);
	}

 failed:
put_root:
	nilfs_put_root(root);
	return err;

failed:
	nilfs_abort_roll_forward(nilfs);
	goto put_root;
}

/**
+2 −0
Original line number Diff line number Diff line
@@ -2862,6 +2862,7 @@ void nilfs_detach_log_writer(struct super_block *sb)
		nilfs_segctor_destroy(nilfs->ns_writer);
		nilfs->ns_writer = NULL;
	}
	set_nilfs_purging(nilfs);

	/* Force to free the list of dirty files */
	spin_lock(&nilfs->ns_inode_lock);
@@ -2874,4 +2875,5 @@ void nilfs_detach_log_writer(struct super_block *sb)
	up_write(&nilfs->ns_segctor_sem);

	nilfs_dispose_list(nilfs, &garbage_list, 1);
	clear_nilfs_purging(nilfs);
}
+2 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ enum {
	THE_NILFS_DISCONTINUED,	/* 'next' pointer chain has broken */
	THE_NILFS_GC_RUNNING,	/* gc process is running */
	THE_NILFS_SB_DIRTY,	/* super block is dirty */
	THE_NILFS_PURGING,	/* disposing dirty files for cleanup */
};

/**
@@ -208,6 +209,7 @@ THE_NILFS_FNS(INIT, init)
THE_NILFS_FNS(DISCONTINUED, discontinued)
THE_NILFS_FNS(GC_RUNNING, gc_running)
THE_NILFS_FNS(SB_DIRTY, sb_dirty)
THE_NILFS_FNS(PURGING, purging)

/*
 * Mount option operations