Commit 64e0253d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'sched-urgent-2023-02-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull scheduler fixes from Ingo Molnar:

 - Fix user-after-free bug in call_usermodehelper_exec()

 - Fix missing user_cpus_ptr update in __set_cpus_allowed_ptr_locked()

 - Fix PSI use-after-free bug in ep_remove_wait_queue()

* tag 'sched-urgent-2023-02-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  sched/psi: Fix use-after-free in ep_remove_wait_queue()
  sched/core: Fix a missed update of user_cpus_ptr
  freezer,umh: Fix call_usermode_helper_exec() vs SIGKILL
parents ec35307e c2dbe32d
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -2951,8 +2951,11 @@ static int __set_cpus_allowed_ptr_locked(struct task_struct *p,
	}

	if (!(ctx->flags & SCA_MIGRATE_ENABLE)) {
		if (cpumask_equal(&p->cpus_mask, ctx->new_mask))
		if (cpumask_equal(&p->cpus_mask, ctx->new_mask)) {
			if (ctx->flags & SCA_USER)
				swap(p->user_cpus_ptr, ctx->user_mask);
			goto out;
		}

		if (WARN_ON_ONCE(p == current &&
				 is_migration_disabled(p) &&
+4 −3
Original line number Diff line number Diff line
@@ -1343,10 +1343,11 @@ void psi_trigger_destroy(struct psi_trigger *t)

	group = t->group;
	/*
	 * Wakeup waiters to stop polling. Can happen if cgroup is deleted
	 * from under a polling process.
	 * Wakeup waiters to stop polling and clear the queue to prevent it from
	 * being accessed later. Can happen if cgroup is deleted from under a
	 * polling process.
	 */
	wake_up_interruptible(&t->event_wait);
	wake_up_pollfree(&t->event_wait);

	mutex_lock(&group->trigger_lock);

+13 −7
Original line number Diff line number Diff line
@@ -438,21 +438,27 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
	if (wait == UMH_NO_WAIT)	/* task has freed sub_info */
		goto unlock;

	if (wait & UMH_KILLABLE)
		state |= TASK_KILLABLE;

	if (wait & UMH_FREEZABLE)
		state |= TASK_FREEZABLE;

	retval = wait_for_completion_state(&done, state);
	if (wait & UMH_KILLABLE) {
		retval = wait_for_completion_state(&done, state | TASK_KILLABLE);
		if (!retval)
			goto wait_done;

	if (wait & UMH_KILLABLE) {
		/* umh_complete() will see NULL and free sub_info */
		if (xchg(&sub_info->complete, NULL))
			goto unlock;

		/*
		 * fallthrough; in case of -ERESTARTSYS now do uninterruptible
		 * wait_for_completion_state(). Since umh_complete() shall call
		 * complete() in a moment if xchg() above returned NULL, this
		 * uninterruptible wait_for_completion_state() will not block
		 * SIGKILL'ed processes for long.
		 */
	}
	wait_for_completion_state(&done, state);

wait_done:
	retval = sub_info->retval;