ANDROID: sched: Fix wake_q length tracking
The current approach to carry the wake_q length is exposed to an intertask stack access. For example, if A sets the wake_q_head for B but is preempted before it is able to set it back to NULL, then B continues to point to an address corresponding to A's stack. If B is then woken up by another task, it ends up accessing the address pointing to A's stack. This causes a memory fault. Replace this with a simple parameter which indicates the number of tasks that are being woken up as part of the same event. This avoids saving and accessing on stack pointers. Bug: 173981591 Change-Id: I0031747d79a27673e680f7b1121eb4896ac7c699 Signed-off-by: Shaleen Agrawal <shalagra@codeaurora.org> (cherry picked from commit 1e674650ffcd43de38d8a68549b345683a0a5f1d) Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
parent
3b77e032e0
commit
abe2e577c3
@ -1034,7 +1034,7 @@ struct task_struct {
|
|||||||
raw_spinlock_t pi_lock;
|
raw_spinlock_t pi_lock;
|
||||||
|
|
||||||
struct wake_q_node wake_q;
|
struct wake_q_node wake_q;
|
||||||
struct wake_q_head *wake_q_head;
|
int wake_q_count;
|
||||||
|
|
||||||
#ifdef CONFIG_RT_MUTEXES
|
#ifdef CONFIG_RT_MUTEXES
|
||||||
/* PI waiters blocked on a rt_mutex held by this task: */
|
/* PI waiters blocked on a rt_mutex held by this task: */
|
||||||
|
@ -597,14 +597,14 @@ void wake_up_q(struct wake_q_head *head)
|
|||||||
/* Task can safely be re-inserted now: */
|
/* Task can safely be re-inserted now: */
|
||||||
node = node->next;
|
node = node->next;
|
||||||
task->wake_q.next = NULL;
|
task->wake_q.next = NULL;
|
||||||
task->wake_q_head = head;
|
task->wake_q_count = head->count;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wake_up_process() executes a full barrier, which pairs with
|
* wake_up_process() executes a full barrier, which pairs with
|
||||||
* the queueing in wake_q_add() so as not to miss wakeups.
|
* the queueing in wake_q_add() so as not to miss wakeups.
|
||||||
*/
|
*/
|
||||||
wake_up_process(task);
|
wake_up_process(task);
|
||||||
task->wake_q_head = NULL;
|
task->wake_q_count = 0;
|
||||||
put_task_struct(task);
|
put_task_struct(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user