Commit 82d712f6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-5.14-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq

Pull workqueue fix from Tejun Heo:
 "Fix a use-after-free in allocation failure handling path"

* 'for-5.14-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq:
  workqueue: fix UAF in pwq_unbound_release_workfn()
parents ff117646 b42b0bdd
Loading
Loading
Loading
Loading
+13 −7
Original line number Original line Diff line number Diff line
@@ -3676,8 +3676,13 @@ static void pwq_unbound_release_workfn(struct work_struct *work)
						  unbound_release_work);
						  unbound_release_work);
	struct workqueue_struct *wq = pwq->wq;
	struct workqueue_struct *wq = pwq->wq;
	struct worker_pool *pool = pwq->pool;
	struct worker_pool *pool = pwq->pool;
	bool is_last;
	bool is_last = false;


	/*
	 * when @pwq is not linked, it doesn't hold any reference to the
	 * @wq, and @wq is invalid to access.
	 */
	if (!list_empty(&pwq->pwqs_node)) {
		if (WARN_ON_ONCE(!(wq->flags & WQ_UNBOUND)))
		if (WARN_ON_ONCE(!(wq->flags & WQ_UNBOUND)))
			return;
			return;


@@ -3685,6 +3690,7 @@ static void pwq_unbound_release_workfn(struct work_struct *work)
		list_del_rcu(&pwq->pwqs_node);
		list_del_rcu(&pwq->pwqs_node);
		is_last = list_empty(&wq->pwqs);
		is_last = list_empty(&wq->pwqs);
		mutex_unlock(&wq->mutex);
		mutex_unlock(&wq->mutex);
	}


	mutex_lock(&wq_pool_mutex);
	mutex_lock(&wq_pool_mutex);
	put_unbound_pool(pool);
	put_unbound_pool(pool);