From 1e674650ffcd43de38d8a68549b345683a0a5f1d Mon Sep 17 00:00:00 2001 From: Shaleen Agrawal Date: Mon, 8 Feb 2021 21:41:48 -0800 Subject: [PATCH] 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 --- include/linux/sched.h | 2 +- kernel/sched/core.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 0a750bac352d..f40e26b230e0 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1008,7 +1008,7 @@ struct task_struct { raw_spinlock_t pi_lock; struct wake_q_node wake_q; - struct wake_q_head *wake_q_head; + int wake_q_count; #ifdef CONFIG_RT_MUTEXES /* PI waiters blocked on a rt_mutex held by this task: */ diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 1e4651d531c9..9671f3f08ba3 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -601,14 +601,14 @@ void wake_up_q(struct wake_q_head *head) /* Task can safely be re-inserted now: */ node = node->next; 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 * the queueing in wake_q_add() so as not to miss wakeups. */ wake_up_process(task); - task->wake_q_head = NULL; + task->wake_q_count = 0; put_task_struct(task); } }