Commit dae51f56204d33444f61d9e7af3ee70aef55daa4
Committed by
Ingo Molnar
1 parent
9778385db3
Exists in
master
and in
7 other branches
sched: fix SCHED_FIFO tasks & FAIR_GROUP_SCHED
Suppose that the SCHED_FIFO task does switch_uid(new_user); Now, p->se.cfs_rq and p->se.parent both point into the old user_struct->tg because sched_move_task() doesn't call set_task_cfs_rq() for !fair_sched_class case. Suppose that old user_struct/task_group is freed/reused, and the task does sched_setscheduler(SCHED_NORMAL); __setscheduler() sets fair_sched_class, but doesn't update ->se.cfs_rq/parent which point to the freed memory. This means that check_preempt_wakeup() doing while (!is_same_group(se, pse)) { se = parent_entity(se); pse = parent_entity(pse); } may OOPS in a similar way if rq->curr or p did something like above. Perhaps we need something like the patch below, note that __setscheduler() can't do set_task_cfs_rq(). Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Showing 1 changed file with 3 additions and 1 deletions Side-by-side Diff
kernel/sched.c
... | ... | @@ -7087,8 +7087,10 @@ |
7087 | 7087 | |
7088 | 7088 | rq = task_rq_lock(tsk, &flags); |
7089 | 7089 | |
7090 | - if (tsk->sched_class != &fair_sched_class) | |
7090 | + if (tsk->sched_class != &fair_sched_class) { | |
7091 | + set_task_cfs_rq(tsk); | |
7091 | 7092 | goto done; |
7093 | + } | |
7092 | 7094 | |
7093 | 7095 | update_rq_clock(rq); |
7094 | 7096 |