aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/signal.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index e46971560fcb..5d30ff561847 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1578,6 +1578,17 @@ static inline int may_ptrace_stop(void)
1578} 1578}
1579 1579
1580/* 1580/*
1581 * Return nonzero if there is a SIGKILL that should be waking us up.
1582 * Called with the siglock held.
1583 */
1584static int sigkill_pending(struct task_struct *tsk)
1585{
1586 return ((sigismember(&tsk->pending.signal, SIGKILL) ||
1587 sigismember(&tsk->signal->shared_pending.signal, SIGKILL)) &&
1588 !unlikely(sigismember(&tsk->blocked, SIGKILL)));
1589}
1590
1591/*
1581 * This must be called with current->sighand->siglock held. 1592 * This must be called with current->sighand->siglock held.
1582 * 1593 *
1583 * This should be the path for all ptrace stops. 1594 * This should be the path for all ptrace stops.
@@ -1590,6 +1601,26 @@ static inline int may_ptrace_stop(void)
1590 */ 1601 */
1591static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info) 1602static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info)
1592{ 1603{
1604 int killed = 0;
1605
1606 if (arch_ptrace_stop_needed(exit_code, info)) {
1607 /*
1608 * The arch code has something special to do before a
1609 * ptrace stop. This is allowed to block, e.g. for faults
1610 * on user stack pages. We can't keep the siglock while
1611 * calling arch_ptrace_stop, so we must release it now.
1612 * To preserve proper semantics, we must do this before
1613 * any signal bookkeeping like checking group_stop_count.
1614 * Meanwhile, a SIGKILL could come in before we retake the
1615 * siglock. That must prevent us from sleeping in TASK_TRACED.
1616 * So after regaining the lock, we must check for SIGKILL.
1617 */
1618 spin_unlock_irq(&current->sighand->siglock);
1619 arch_ptrace_stop(exit_code, info);
1620 spin_lock_irq(&current->sighand->siglock);
1621 killed = sigkill_pending(current);
1622 }
1623
1593 /* 1624 /*
1594 * If there is a group stop in progress, 1625 * If there is a group stop in progress,
1595 * we must participate in the bookkeeping. 1626 * we must participate in the bookkeeping.
@@ -1605,7 +1636,7 @@ static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info)
1605 spin_unlock_irq(&current->sighand->siglock); 1636 spin_unlock_irq(&current->sighand->siglock);
1606 try_to_freeze(); 1637 try_to_freeze();
1607 read_lock(&tasklist_lock); 1638 read_lock(&tasklist_lock);
1608 if (may_ptrace_stop()) { 1639 if (!unlikely(killed) && may_ptrace_stop()) {
1609 do_notify_parent_cldstop(current, CLD_TRAPPED); 1640 do_notify_parent_cldstop(current, CLD_TRAPPED);
1610 read_unlock(&tasklist_lock); 1641 read_unlock(&tasklist_lock);
1611 schedule(); 1642 schedule();