Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751862AbdHGRld (ORCPT ); Mon, 7 Aug 2017 13:41:33 -0400 Received: from mx0a-00010702.pphosted.com ([148.163.156.75]:48713 "EHLO mx0b-00010702.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752193AbdHGRlZ (ORCPT ); Mon, 7 Aug 2017 13:41:25 -0400 From: Julia Cartwright To: , CC: Thomas Gleixner , Steven Rostedt , Carsten Emde , Sebastian Andrzej Siewior , John Kacur , Paul Gortmaker , Subject: [PATCH RT 3/6] sched: Prevent task state corruption by spurious lock wakeup Date: Mon, 7 Aug 2017 12:40:59 -0500 Message-ID: <20170807174102.5448-4-julia@ni.com> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20170807174102.5448-1-julia@ni.com> References: <20170807174102.5448-1-julia@ni.com> MIME-Version: 1.0 Content-Type: text/plain X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-08-07_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_policy_notspam policy=outbound_policy score=30 priorityscore=1501 malwarescore=0 suspectscore=2 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=30 reason=mlx scancount=1 engine=8.0.1-1706020000 definitions=main-1708070291 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2836 Lines: 85 4.1.42-rt50-rc1 stable review patch. If you have any objection to the inclusion of this patch, let me know. --- 8< --- 8< --- 8< --- From: Thomas Gleixner Mathias and others reported GDB failures on RT. The following scenario leads to task state corruption: CPU0 CPU1 T1->state = TASK_XXX; spin_lock(&lock) rt_spin_lock_slowlock(&lock->rtmutex) raw_spin_lock(&rtm->wait_lock); T1->saved_state = current->state; T1->state = TASK_UNINTERRUPTIBLE; spin_unlock(&lock) task_blocks_on_rt_mutex(rtm) rt_spin_lock_slowunlock(&lock->rtmutex) queue_waiter(rtm) raw_spin_lock(&rtm->wait_lock); pi_chain_walk(rtm) raw_spin_unlock(&rtm->wait_lock); wake_top_waiter(T1) raw_spin_lock(&rtm->wait_lock); for (;;) { if (__try_to_take_rt_mutex()) <- Succeeds break; ... } T1->state = T1->saved_state; try_to_wake_up(T1) ttwu_do_wakeup(T1) T1->state = TASK_RUNNING; In most cases this is harmless because waiting for some event, which is the usual reason for TASK_[UN]INTERRUPTIBLE has to be safe against other forms of spurious wakeups anyway. But in case of TASK_TRACED this is actually fatal, because the task loses the TASK_TRACED state. In consequence it fails to consume SIGSTOP which was sent from the debugger and actually delivers SIGSTOP to the task which breaks the ptrace mechanics and brings the debugger into an unexpected state. The TASK_TRACED state should prevent getting there due to the state matching logic in try_to_wake_up(). But that's not true because wake_up_lock_sleeper() uses TASK_ALL as state mask. That's bogus because lock sleepers always use TASK_UNINTERRUPTIBLE, so the wakeup should use that as well. The cure is way simpler as figuring it out: Change the mask used in wake_up_lock_sleeper() from TASK_ALL to TASK_UNINTERRUPTIBLE. Cc: stable-rt@vger.kernel.org Reported-by: Mathias Koehrer Reported-by: David Hauck Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior (cherry picked from commit 2f9f24e15088d2ef3244d088a9604d7e98c9c625) Signed-off-by: Julia Cartwright --- kernel/sched/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 0d3a40b24304..ee11a59e53ff 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1876,7 +1876,7 @@ EXPORT_SYMBOL(wake_up_process); */ int wake_up_lock_sleeper(struct task_struct *p) { - return try_to_wake_up(p, TASK_ALL, WF_LOCK_SLEEPER); + return try_to_wake_up(p, TASK_UNINTERRUPTIBLE, WF_LOCK_SLEEPER); } int wake_up_state(struct task_struct *p, unsigned int state) -- 2.13.1