diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 142 |
1 files changed, 87 insertions, 55 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 5d30ff561847..2c1f08defac2 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1018,7 +1018,7 @@ int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) | |||
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | /* | 1020 | /* |
1021 | * kill_pgrp_info() sends a signal to a process group: this is what the tty | 1021 | * __kill_pgrp_info() sends a signal to a process group: this is what the tty |
1022 | * control characters do (^C, ^Z etc) | 1022 | * control characters do (^C, ^Z etc) |
1023 | */ | 1023 | */ |
1024 | 1024 | ||
@@ -1037,30 +1037,28 @@ int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp) | |||
1037 | return success ? 0 : retval; | 1037 | return success ? 0 : retval; |
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp) | ||
1041 | { | ||
1042 | int retval; | ||
1043 | |||
1044 | read_lock(&tasklist_lock); | ||
1045 | retval = __kill_pgrp_info(sig, info, pgrp); | ||
1046 | read_unlock(&tasklist_lock); | ||
1047 | |||
1048 | return retval; | ||
1049 | } | ||
1050 | |||
1051 | int kill_pid_info(int sig, struct siginfo *info, struct pid *pid) | 1040 | int kill_pid_info(int sig, struct siginfo *info, struct pid *pid) |
1052 | { | 1041 | { |
1053 | int error; | 1042 | int error = -ESRCH; |
1054 | struct task_struct *p; | 1043 | struct task_struct *p; |
1055 | 1044 | ||
1056 | rcu_read_lock(); | 1045 | rcu_read_lock(); |
1057 | if (unlikely(sig_needs_tasklist(sig))) | 1046 | if (unlikely(sig_needs_tasklist(sig))) |
1058 | read_lock(&tasklist_lock); | 1047 | read_lock(&tasklist_lock); |
1059 | 1048 | ||
1049 | retry: | ||
1060 | p = pid_task(pid, PIDTYPE_PID); | 1050 | p = pid_task(pid, PIDTYPE_PID); |
1061 | error = -ESRCH; | 1051 | if (p) { |
1062 | if (p) | ||
1063 | error = group_send_sig_info(sig, info, p); | 1052 | error = group_send_sig_info(sig, info, p); |
1053 | if (unlikely(error == -ESRCH)) | ||
1054 | /* | ||
1055 | * The task was unhashed in between, try again. | ||
1056 | * If it is dead, pid_task() will return NULL, | ||
1057 | * if we race with de_thread() it will find the | ||
1058 | * new leader. | ||
1059 | */ | ||
1060 | goto retry; | ||
1061 | } | ||
1064 | 1062 | ||
1065 | if (unlikely(sig_needs_tasklist(sig))) | 1063 | if (unlikely(sig_needs_tasklist(sig))) |
1066 | read_unlock(&tasklist_lock); | 1064 | read_unlock(&tasklist_lock); |
@@ -1125,14 +1123,22 @@ EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); | |||
1125 | static int kill_something_info(int sig, struct siginfo *info, int pid) | 1123 | static int kill_something_info(int sig, struct siginfo *info, int pid) |
1126 | { | 1124 | { |
1127 | int ret; | 1125 | int ret; |
1128 | rcu_read_lock(); | 1126 | |
1129 | if (!pid) { | 1127 | if (pid > 0) { |
1130 | ret = kill_pgrp_info(sig, info, task_pgrp(current)); | 1128 | rcu_read_lock(); |
1131 | } else if (pid == -1) { | 1129 | ret = kill_pid_info(sig, info, find_vpid(pid)); |
1130 | rcu_read_unlock(); | ||
1131 | return ret; | ||
1132 | } | ||
1133 | |||
1134 | read_lock(&tasklist_lock); | ||
1135 | if (pid != -1) { | ||
1136 | ret = __kill_pgrp_info(sig, info, | ||
1137 | pid ? find_vpid(-pid) : task_pgrp(current)); | ||
1138 | } else { | ||
1132 | int retval = 0, count = 0; | 1139 | int retval = 0, count = 0; |
1133 | struct task_struct * p; | 1140 | struct task_struct * p; |
1134 | 1141 | ||
1135 | read_lock(&tasklist_lock); | ||
1136 | for_each_process(p) { | 1142 | for_each_process(p) { |
1137 | if (p->pid > 1 && !same_thread_group(p, current)) { | 1143 | if (p->pid > 1 && !same_thread_group(p, current)) { |
1138 | int err = group_send_sig_info(sig, info, p); | 1144 | int err = group_send_sig_info(sig, info, p); |
@@ -1141,14 +1147,10 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) | |||
1141 | retval = err; | 1147 | retval = err; |
1142 | } | 1148 | } |
1143 | } | 1149 | } |
1144 | read_unlock(&tasklist_lock); | ||
1145 | ret = count ? retval : -ESRCH; | 1150 | ret = count ? retval : -ESRCH; |
1146 | } else if (pid < 0) { | ||
1147 | ret = kill_pgrp_info(sig, info, find_vpid(-pid)); | ||
1148 | } else { | ||
1149 | ret = kill_pid_info(sig, info, find_vpid(pid)); | ||
1150 | } | 1151 | } |
1151 | rcu_read_unlock(); | 1152 | read_unlock(&tasklist_lock); |
1153 | |||
1152 | return ret; | 1154 | return ret; |
1153 | } | 1155 | } |
1154 | 1156 | ||
@@ -1196,20 +1198,6 @@ send_sig(int sig, struct task_struct *p, int priv) | |||
1196 | return send_sig_info(sig, __si_special(priv), p); | 1198 | return send_sig_info(sig, __si_special(priv), p); |
1197 | } | 1199 | } |
1198 | 1200 | ||
1199 | /* | ||
1200 | * This is the entry point for "process-wide" signals. | ||
1201 | * They will go to an appropriate thread in the thread group. | ||
1202 | */ | ||
1203 | int | ||
1204 | send_group_sig_info(int sig, struct siginfo *info, struct task_struct *p) | ||
1205 | { | ||
1206 | int ret; | ||
1207 | read_lock(&tasklist_lock); | ||
1208 | ret = group_send_sig_info(sig, info, p); | ||
1209 | read_unlock(&tasklist_lock); | ||
1210 | return ret; | ||
1211 | } | ||
1212 | |||
1213 | void | 1201 | void |
1214 | force_sig(int sig, struct task_struct *p) | 1202 | force_sig(int sig, struct task_struct *p) |
1215 | { | 1203 | { |
@@ -1237,7 +1225,13 @@ force_sigsegv(int sig, struct task_struct *p) | |||
1237 | 1225 | ||
1238 | int kill_pgrp(struct pid *pid, int sig, int priv) | 1226 | int kill_pgrp(struct pid *pid, int sig, int priv) |
1239 | { | 1227 | { |
1240 | return kill_pgrp_info(sig, __si_special(priv), pid); | 1228 | int ret; |
1229 | |||
1230 | read_lock(&tasklist_lock); | ||
1231 | ret = __kill_pgrp_info(sig, __si_special(priv), pid); | ||
1232 | read_unlock(&tasklist_lock); | ||
1233 | |||
1234 | return ret; | ||
1241 | } | 1235 | } |
1242 | EXPORT_SYMBOL(kill_pgrp); | 1236 | EXPORT_SYMBOL(kill_pgrp); |
1243 | 1237 | ||
@@ -1556,11 +1550,6 @@ static inline int may_ptrace_stop(void) | |||
1556 | { | 1550 | { |
1557 | if (!likely(current->ptrace & PT_PTRACED)) | 1551 | if (!likely(current->ptrace & PT_PTRACED)) |
1558 | return 0; | 1552 | return 0; |
1559 | |||
1560 | if (unlikely(current->parent == current->real_parent && | ||
1561 | (current->ptrace & PT_ATTACHED))) | ||
1562 | return 0; | ||
1563 | |||
1564 | /* | 1553 | /* |
1565 | * Are we in the middle of do_coredump? | 1554 | * Are we in the middle of do_coredump? |
1566 | * If so and our tracer is also part of the coredump stopping | 1555 | * If so and our tracer is also part of the coredump stopping |
@@ -1596,10 +1585,10 @@ static int sigkill_pending(struct task_struct *tsk) | |||
1596 | * That makes it a way to test a stopped process for | 1585 | * That makes it a way to test a stopped process for |
1597 | * being ptrace-stopped vs being job-control-stopped. | 1586 | * being ptrace-stopped vs being job-control-stopped. |
1598 | * | 1587 | * |
1599 | * If we actually decide not to stop at all because the tracer is gone, | 1588 | * If we actually decide not to stop at all because the tracer |
1600 | * we leave nostop_code in current->exit_code. | 1589 | * is gone, we keep current->exit_code unless clear_code. |
1601 | */ | 1590 | */ |
1602 | static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info) | 1591 | static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) |
1603 | { | 1592 | { |
1604 | int killed = 0; | 1593 | int killed = 0; |
1605 | 1594 | ||
@@ -1643,11 +1632,12 @@ static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info) | |||
1643 | } else { | 1632 | } else { |
1644 | /* | 1633 | /* |
1645 | * By the time we got the lock, our tracer went away. | 1634 | * By the time we got the lock, our tracer went away. |
1646 | * Don't stop here. | 1635 | * Don't drop the lock yet, another tracer may come. |
1647 | */ | 1636 | */ |
1637 | __set_current_state(TASK_RUNNING); | ||
1638 | if (clear_code) | ||
1639 | current->exit_code = 0; | ||
1648 | read_unlock(&tasklist_lock); | 1640 | read_unlock(&tasklist_lock); |
1649 | set_current_state(TASK_RUNNING); | ||
1650 | current->exit_code = nostop_code; | ||
1651 | } | 1641 | } |
1652 | 1642 | ||
1653 | /* | 1643 | /* |
@@ -1680,7 +1670,7 @@ void ptrace_notify(int exit_code) | |||
1680 | 1670 | ||
1681 | /* Let the debugger run. */ | 1671 | /* Let the debugger run. */ |
1682 | spin_lock_irq(¤t->sighand->siglock); | 1672 | spin_lock_irq(¤t->sighand->siglock); |
1683 | ptrace_stop(exit_code, 0, &info); | 1673 | ptrace_stop(exit_code, 1, &info); |
1684 | spin_unlock_irq(¤t->sighand->siglock); | 1674 | spin_unlock_irq(¤t->sighand->siglock); |
1685 | } | 1675 | } |
1686 | 1676 | ||
@@ -1743,7 +1733,7 @@ static int do_signal_stop(int signr) | |||
1743 | * stop is always done with the siglock held, | 1733 | * stop is always done with the siglock held, |
1744 | * so this check has no races. | 1734 | * so this check has no races. |
1745 | */ | 1735 | */ |
1746 | if (!t->exit_state && | 1736 | if (!(t->flags & PF_EXITING) && |
1747 | !task_is_stopped_or_traced(t)) { | 1737 | !task_is_stopped_or_traced(t)) { |
1748 | stop_count++; | 1738 | stop_count++; |
1749 | signal_wake_up(t, 0); | 1739 | signal_wake_up(t, 0); |
@@ -1787,7 +1777,7 @@ relock: | |||
1787 | ptrace_signal_deliver(regs, cookie); | 1777 | ptrace_signal_deliver(regs, cookie); |
1788 | 1778 | ||
1789 | /* Let the debugger run. */ | 1779 | /* Let the debugger run. */ |
1790 | ptrace_stop(signr, signr, info); | 1780 | ptrace_stop(signr, 0, info); |
1791 | 1781 | ||
1792 | /* We're back. Did the debugger cancel the sig? */ | 1782 | /* We're back. Did the debugger cancel the sig? */ |
1793 | signr = current->exit_code; | 1783 | signr = current->exit_code; |
@@ -1904,6 +1894,48 @@ relock: | |||
1904 | return signr; | 1894 | return signr; |
1905 | } | 1895 | } |
1906 | 1896 | ||
1897 | void exit_signals(struct task_struct *tsk) | ||
1898 | { | ||
1899 | int group_stop = 0; | ||
1900 | struct task_struct *t; | ||
1901 | |||
1902 | if (thread_group_empty(tsk) || signal_group_exit(tsk->signal)) { | ||
1903 | tsk->flags |= PF_EXITING; | ||
1904 | return; | ||
1905 | } | ||
1906 | |||
1907 | spin_lock_irq(&tsk->sighand->siglock); | ||
1908 | /* | ||
1909 | * From now this task is not visible for group-wide signals, | ||
1910 | * see wants_signal(), do_signal_stop(). | ||
1911 | */ | ||
1912 | tsk->flags |= PF_EXITING; | ||
1913 | if (!signal_pending(tsk)) | ||
1914 | goto out; | ||
1915 | |||
1916 | /* It could be that __group_complete_signal() choose us to | ||
1917 | * notify about group-wide signal. Another thread should be | ||
1918 | * woken now to take the signal since we will not. | ||
1919 | */ | ||
1920 | for (t = tsk; (t = next_thread(t)) != tsk; ) | ||
1921 | if (!signal_pending(t) && !(t->flags & PF_EXITING)) | ||
1922 | recalc_sigpending_and_wake(t); | ||
1923 | |||
1924 | if (unlikely(tsk->signal->group_stop_count) && | ||
1925 | !--tsk->signal->group_stop_count) { | ||
1926 | tsk->signal->flags = SIGNAL_STOP_STOPPED; | ||
1927 | group_stop = 1; | ||
1928 | } | ||
1929 | out: | ||
1930 | spin_unlock_irq(&tsk->sighand->siglock); | ||
1931 | |||
1932 | if (unlikely(group_stop)) { | ||
1933 | read_lock(&tasklist_lock); | ||
1934 | do_notify_parent_cldstop(tsk, CLD_STOPPED); | ||
1935 | read_unlock(&tasklist_lock); | ||
1936 | } | ||
1937 | } | ||
1938 | |||
1907 | EXPORT_SYMBOL(recalc_sigpending); | 1939 | EXPORT_SYMBOL(recalc_sigpending); |
1908 | EXPORT_SYMBOL_GPL(dequeue_signal); | 1940 | EXPORT_SYMBOL_GPL(dequeue_signal); |
1909 | EXPORT_SYMBOL(flush_signals); | 1941 | EXPORT_SYMBOL(flush_signals); |