Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf6b9316 authored by Guoqing Jiang's avatar Guoqing Jiang Committed by Greg Kroah-Hartman
Browse files

md: protect md_unregister_thread from reentrancy



[ Upstream commit 1e267742283a4b5a8ca65755c44166be27e9aa0f ]

Generally, the md_unregister_thread is called with reconfig_mutex, but
raid_message in dm-raid doesn't hold reconfig_mutex to unregister thread,
so md_unregister_thread can be called simulitaneously from two call sites
in theory.

Then after previous commit which remove the protection of reconfig_mutex
for md_unregister_thread completely, the potential issue could be worse
than before.

Let's take pers_lock at the beginning of function to ensure reentrancy.

Reported-by: default avatarDonald Buczek <buczek@molgen.mpg.de>
Signed-off-by: default avatarGuoqing Jiang <guoqing.jiang@linux.dev>
Signed-off-by: default avatarSong Liu <song@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 99e4c67a
Loading
Loading
Loading
Loading
+10 −5
Original line number Original line Diff line number Diff line
@@ -7777,17 +7777,22 @@ EXPORT_SYMBOL(md_register_thread);


void md_unregister_thread(struct md_thread **threadp)
void md_unregister_thread(struct md_thread **threadp)
{
{
	struct md_thread *thread = *threadp;
	struct md_thread *thread;
	if (!thread)

		return;
	/*
	pr_debug("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
	 * Locking ensures that mddev_unlock does not wake_up a
	/* Locking ensures that mddev_unlock does not wake_up a
	 * non-existent thread
	 * non-existent thread
	 */
	 */
	spin_lock(&pers_lock);
	spin_lock(&pers_lock);
	thread = *threadp;
	if (!thread) {
		spin_unlock(&pers_lock);
		return;
	}
	*threadp = NULL;
	*threadp = NULL;
	spin_unlock(&pers_lock);
	spin_unlock(&pers_lock);


	pr_debug("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
	kthread_stop(thread->tsk);
	kthread_stop(thread->tsk);
	kfree(thread);
	kfree(thread);
}
}