Misc scheduler fixes:

- 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()
 
 Signed-off-by: Ingo Molnar <mingo@kernel.org>
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmPvL2ARHG1pbmdvQGtl
 cm5lbC5vcmcACgkQEnMQ0APhK1jDTA/+IgUjTKxxvXk+vWblhJcJXnFJaN0v37gE
 I4zk0Z4cndpZhK4ayCKyb9sqMAnNHN/aWtJCfqwcctdp35B6A8PcXlFLEE1Fd54g
 ZO1P3b+sXg8yV+xrh6mJTu29oLCMMfYjmZiMw/1FM0tWCStOP7ECOdp0Afgsknpi
 gAoN/pgzDPcnVrLZMIRzX8Z4REPOGqnmR/ILNkKk0SD5dfwE0lw0aO0cDndpkD8j
 P24w4WRwDb6dL0AEHkNgFgufoYXB2p82cXVg94vGuonQ2siS+8ebo7YPMx+JB35o
 IGrto4MoCN/hQvSY7b0kkUccG7JA0eXzFBSdqpDAsXZbkGTtMlDfn6c8XWLz4WOs
 ZIoeJ9hvntLJgFNb7+KekYYdQZyLd/fGWoFlk93Sy+Ex7OQHeCotKrcXYStJN/2j
 FdpDoTzsnAkfQDWtwu6tguzoXfV9v91e4o6xxHG+PYrbARHwGanAAXE8EZ9XwVp+
 18oPp2GDUmlvZyJo/u/X9T5qu2usMgxqxIm15P31sYfzWjb9d/DvP7QjaEyuhdaV
 nB71Saa8RZQviZtnf++FfgzoCMPKWn2sYYO4IUU9f6OB3Zq1t+jiGraPuMP6bApA
 tjardQVE0L70C2YPy1p8FzWRpiBF6YwFXP3Q99+6WDcWBM5s8WkrwDYSRUc8ontj
 JNqfHCsiycY=
 =FVI9
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2023-02-17 13:45:09 -08:00
commit 64e0253df6
3 changed files with 21 additions and 11 deletions

View File

@ -2951,8 +2951,11 @@ static int __set_cpus_allowed_ptr_locked(struct task_struct *p,
} }
if (!(ctx->flags & SCA_MIGRATE_ENABLE)) { 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; goto out;
}
if (WARN_ON_ONCE(p == current && if (WARN_ON_ONCE(p == current &&
is_migration_disabled(p) && is_migration_disabled(p) &&

View File

@ -1343,10 +1343,11 @@ void psi_trigger_destroy(struct psi_trigger *t)
group = t->group; group = t->group;
/* /*
* Wakeup waiters to stop polling. Can happen if cgroup is deleted * Wakeup waiters to stop polling and clear the queue to prevent it from
* from under a polling process. * 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); mutex_lock(&group->trigger_lock);

View File

@ -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 */ if (wait == UMH_NO_WAIT) /* task has freed sub_info */
goto unlock; goto unlock;
if (wait & UMH_KILLABLE)
state |= TASK_KILLABLE;
if (wait & UMH_FREEZABLE) if (wait & UMH_FREEZABLE)
state |= TASK_FREEZABLE; state |= TASK_FREEZABLE;
retval = wait_for_completion_state(&done, state);
if (!retval)
goto wait_done;
if (wait & UMH_KILLABLE) { if (wait & UMH_KILLABLE) {
retval = wait_for_completion_state(&done, state | TASK_KILLABLE);
if (!retval)
goto wait_done;
/* umh_complete() will see NULL and free sub_info */ /* umh_complete() will see NULL and free sub_info */
if (xchg(&sub_info->complete, NULL)) if (xchg(&sub_info->complete, NULL))
goto unlock; 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: wait_done:
retval = sub_info->retval; retval = sub_info->retval;