aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c53
1 files changed, 50 insertions, 3 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 9f10b246fd46..f65403da4101 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1694,6 +1694,15 @@ static int sigkill_pending(struct task_struct *tsk)
1694} 1694}
1695 1695
1696/* 1696/*
1697 * Test whether the target task of the usual cldstop notification - the
1698 * real_parent of @child - is in the same group as the ptracer.
1699 */
1700static bool real_parent_is_ptracer(struct task_struct *child)
1701{
1702 return same_thread_group(child->parent, child->real_parent);
1703}
1704
1705/*
1697 * This must be called with current->sighand->siglock held. 1706 * This must be called with current->sighand->siglock held.
1698 * 1707 *
1699 * This should be the path for all ptrace stops. 1708 * This should be the path for all ptrace stops.
@@ -1708,6 +1717,8 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
1708 __releases(&current->sighand->siglock) 1717 __releases(&current->sighand->siglock)
1709 __acquires(&current->sighand->siglock) 1718 __acquires(&current->sighand->siglock)
1710{ 1719{
1720 bool gstop_done = false;
1721
1711 if (arch_ptrace_stop_needed(exit_code, info)) { 1722 if (arch_ptrace_stop_needed(exit_code, info)) {
1712 /* 1723 /*
1713 * The arch code has something special to do before a 1724 * The arch code has something special to do before a
@@ -1735,7 +1746,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
1735 * is entered - ignore it. 1746 * is entered - ignore it.
1736 */ 1747 */
1737 if (why == CLD_STOPPED && (current->group_stop & GROUP_STOP_PENDING)) 1748 if (why == CLD_STOPPED && (current->group_stop & GROUP_STOP_PENDING))
1738 task_participate_group_stop(current); 1749 gstop_done = task_participate_group_stop(current);
1739 1750
1740 current->last_siginfo = info; 1751 current->last_siginfo = info;
1741 current->exit_code = exit_code; 1752 current->exit_code = exit_code;
@@ -1757,7 +1768,20 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
1757 spin_unlock_irq(&current->sighand->siglock); 1768 spin_unlock_irq(&current->sighand->siglock);
1758 read_lock(&tasklist_lock); 1769 read_lock(&tasklist_lock);
1759 if (may_ptrace_stop()) { 1770 if (may_ptrace_stop()) {
1760 do_notify_parent_cldstop(current, task_ptrace(current), why); 1771 /*
1772 * Notify parents of the stop.
1773 *
1774 * While ptraced, there are two parents - the ptracer and
1775 * the real_parent of the group_leader. The ptracer should
1776 * know about every stop while the real parent is only
1777 * interested in the completion of group stop. The states
1778 * for the two don't interact with each other. Notify
1779 * separately unless they're gonna be duplicates.
1780 */
1781 do_notify_parent_cldstop(current, true, why);
1782 if (gstop_done && !real_parent_is_ptracer(current))
1783 do_notify_parent_cldstop(current, false, why);
1784
1761 /* 1785 /*
1762 * Don't want to allow preemption here, because 1786 * Don't want to allow preemption here, because
1763 * sys_ptrace() needs this task to be inactive. 1787 * sys_ptrace() needs this task to be inactive.
@@ -1772,7 +1796,16 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
1772 /* 1796 /*
1773 * By the time we got the lock, our tracer went away. 1797 * By the time we got the lock, our tracer went away.
1774 * Don't drop the lock yet, another tracer may come. 1798 * Don't drop the lock yet, another tracer may come.
1799 *
1800 * If @gstop_done, the ptracer went away between group stop
1801 * completion and here. During detach, it would have set
1802 * GROUP_STOP_PENDING on us and we'll re-enter TASK_STOPPED
1803 * in do_signal_stop() on return, so notifying the real
1804 * parent of the group stop completion is enough.
1775 */ 1805 */
1806 if (gstop_done)
1807 do_notify_parent_cldstop(current, false, why);
1808
1776 __set_current_state(TASK_RUNNING); 1809 __set_current_state(TASK_RUNNING);
1777 if (clear_code) 1810 if (clear_code)
1778 current->exit_code = 0; 1811 current->exit_code = 0;
@@ -2017,10 +2050,24 @@ relock:
2017 2050
2018 spin_unlock_irq(&sighand->siglock); 2051 spin_unlock_irq(&sighand->siglock);
2019 2052
2053 /*
2054 * Notify the parent that we're continuing. This event is
2055 * always per-process and doesn't make whole lot of sense
2056 * for ptracers, who shouldn't consume the state via
2057 * wait(2) either, but, for backward compatibility, notify
2058 * the ptracer of the group leader too unless it's gonna be
2059 * a duplicate.
2060 */
2020 read_lock(&tasklist_lock); 2061 read_lock(&tasklist_lock);
2062
2063 do_notify_parent_cldstop(current, false, why);
2064
2021 leader = current->group_leader; 2065 leader = current->group_leader;
2022 do_notify_parent_cldstop(leader, task_ptrace(leader), why); 2066 if (task_ptrace(leader) && !real_parent_is_ptracer(leader))
2067 do_notify_parent_cldstop(leader, true, why);
2068
2023 read_unlock(&tasklist_lock); 2069 read_unlock(&tasklist_lock);
2070
2024 goto relock; 2071 goto relock;
2025 } 2072 }
2026 2073