diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 99 |
1 files changed, 63 insertions, 36 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 82c3545596c5..954f77d7e3bc 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/ptrace.h> | 22 | #include <linux/ptrace.h> |
23 | #include <linux/signal.h> | 23 | #include <linux/signal.h> |
24 | #include <linux/signalfd.h> | 24 | #include <linux/signalfd.h> |
25 | #include <linux/tracehook.h> | ||
25 | #include <linux/capability.h> | 26 | #include <linux/capability.h> |
26 | #include <linux/freezer.h> | 27 | #include <linux/freezer.h> |
27 | #include <linux/pid_namespace.h> | 28 | #include <linux/pid_namespace.h> |
@@ -39,24 +40,21 @@ | |||
39 | 40 | ||
40 | static struct kmem_cache *sigqueue_cachep; | 41 | static struct kmem_cache *sigqueue_cachep; |
41 | 42 | ||
42 | static int __sig_ignored(struct task_struct *t, int sig) | 43 | static void __user *sig_handler(struct task_struct *t, int sig) |
43 | { | 44 | { |
44 | void __user *handler; | 45 | return t->sighand->action[sig - 1].sa.sa_handler; |
46 | } | ||
45 | 47 | ||
48 | static int sig_handler_ignored(void __user *handler, int sig) | ||
49 | { | ||
46 | /* Is it explicitly or implicitly ignored? */ | 50 | /* Is it explicitly or implicitly ignored? */ |
47 | |||
48 | handler = t->sighand->action[sig - 1].sa.sa_handler; | ||
49 | return handler == SIG_IGN || | 51 | return handler == SIG_IGN || |
50 | (handler == SIG_DFL && sig_kernel_ignore(sig)); | 52 | (handler == SIG_DFL && sig_kernel_ignore(sig)); |
51 | } | 53 | } |
52 | 54 | ||
53 | static int sig_ignored(struct task_struct *t, int sig) | 55 | static int sig_ignored(struct task_struct *t, int sig) |
54 | { | 56 | { |
55 | /* | 57 | void __user *handler; |
56 | * Tracers always want to know about signals.. | ||
57 | */ | ||
58 | if (t->ptrace & PT_PTRACED) | ||
59 | return 0; | ||
60 | 58 | ||
61 | /* | 59 | /* |
62 | * Blocked signals are never ignored, since the | 60 | * Blocked signals are never ignored, since the |
@@ -66,7 +64,14 @@ static int sig_ignored(struct task_struct *t, int sig) | |||
66 | if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) | 64 | if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) |
67 | return 0; | 65 | return 0; |
68 | 66 | ||
69 | return __sig_ignored(t, sig); | 67 | handler = sig_handler(t, sig); |
68 | if (!sig_handler_ignored(handler, sig)) | ||
69 | return 0; | ||
70 | |||
71 | /* | ||
72 | * Tracers may want to know about even ignored signals. | ||
73 | */ | ||
74 | return !tracehook_consider_ignored_signal(t, sig, handler); | ||
70 | } | 75 | } |
71 | 76 | ||
72 | /* | 77 | /* |
@@ -129,7 +134,9 @@ void recalc_sigpending_and_wake(struct task_struct *t) | |||
129 | 134 | ||
130 | void recalc_sigpending(void) | 135 | void recalc_sigpending(void) |
131 | { | 136 | { |
132 | if (!recalc_sigpending_tsk(current) && !freezing(current)) | 137 | if (unlikely(tracehook_force_sigpending())) |
138 | set_thread_flag(TIF_SIGPENDING); | ||
139 | else if (!recalc_sigpending_tsk(current) && !freezing(current)) | ||
133 | clear_thread_flag(TIF_SIGPENDING); | 140 | clear_thread_flag(TIF_SIGPENDING); |
134 | 141 | ||
135 | } | 142 | } |
@@ -295,12 +302,12 @@ flush_signal_handlers(struct task_struct *t, int force_default) | |||
295 | 302 | ||
296 | int unhandled_signal(struct task_struct *tsk, int sig) | 303 | int unhandled_signal(struct task_struct *tsk, int sig) |
297 | { | 304 | { |
305 | void __user *handler = tsk->sighand->action[sig-1].sa.sa_handler; | ||
298 | if (is_global_init(tsk)) | 306 | if (is_global_init(tsk)) |
299 | return 1; | 307 | return 1; |
300 | if (tsk->ptrace & PT_PTRACED) | 308 | if (handler != SIG_IGN && handler != SIG_DFL) |
301 | return 0; | 309 | return 0; |
302 | return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) || | 310 | return !tracehook_consider_fatal_signal(tsk, sig, handler); |
303 | (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL); | ||
304 | } | 311 | } |
305 | 312 | ||
306 | 313 | ||
@@ -591,9 +598,6 @@ static int check_kill_permission(int sig, struct siginfo *info, | |||
591 | return security_task_kill(t, info, sig, 0); | 598 | return security_task_kill(t, info, sig, 0); |
592 | } | 599 | } |
593 | 600 | ||
594 | /* forward decl */ | ||
595 | static void do_notify_parent_cldstop(struct task_struct *tsk, int why); | ||
596 | |||
597 | /* | 601 | /* |
598 | * Handle magic process-wide effects of stop/continue signals. Unlike | 602 | * Handle magic process-wide effects of stop/continue signals. Unlike |
599 | * the signal actions, these happen immediately at signal-generation | 603 | * the signal actions, these happen immediately at signal-generation |
@@ -756,7 +760,8 @@ static void complete_signal(int sig, struct task_struct *p, int group) | |||
756 | if (sig_fatal(p, sig) && | 760 | if (sig_fatal(p, sig) && |
757 | !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) && | 761 | !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) && |
758 | !sigismember(&t->real_blocked, sig) && | 762 | !sigismember(&t->real_blocked, sig) && |
759 | (sig == SIGKILL || !(t->ptrace & PT_PTRACED))) { | 763 | (sig == SIGKILL || |
764 | !tracehook_consider_fatal_signal(t, sig, SIG_DFL))) { | ||
760 | /* | 765 | /* |
761 | * This signal will be fatal to the whole group. | 766 | * This signal will be fatal to the whole group. |
762 | */ | 767 | */ |
@@ -1323,9 +1328,11 @@ static inline void __wake_up_parent(struct task_struct *p, | |||
1323 | /* | 1328 | /* |
1324 | * Let a parent know about the death of a child. | 1329 | * Let a parent know about the death of a child. |
1325 | * For a stopped/continued status change, use do_notify_parent_cldstop instead. | 1330 | * For a stopped/continued status change, use do_notify_parent_cldstop instead. |
1331 | * | ||
1332 | * Returns -1 if our parent ignored us and so we've switched to | ||
1333 | * self-reaping, or else @sig. | ||
1326 | */ | 1334 | */ |
1327 | 1335 | int do_notify_parent(struct task_struct *tsk, int sig) | |
1328 | void do_notify_parent(struct task_struct *tsk, int sig) | ||
1329 | { | 1336 | { |
1330 | struct siginfo info; | 1337 | struct siginfo info; |
1331 | unsigned long flags; | 1338 | unsigned long flags; |
@@ -1396,12 +1403,14 @@ void do_notify_parent(struct task_struct *tsk, int sig) | |||
1396 | */ | 1403 | */ |
1397 | tsk->exit_signal = -1; | 1404 | tsk->exit_signal = -1; |
1398 | if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) | 1405 | if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) |
1399 | sig = 0; | 1406 | sig = -1; |
1400 | } | 1407 | } |
1401 | if (valid_signal(sig) && sig > 0) | 1408 | if (valid_signal(sig) && sig > 0) |
1402 | __group_send_sig_info(sig, &info, tsk->parent); | 1409 | __group_send_sig_info(sig, &info, tsk->parent); |
1403 | __wake_up_parent(tsk, tsk->parent); | 1410 | __wake_up_parent(tsk, tsk->parent); |
1404 | spin_unlock_irqrestore(&psig->siglock, flags); | 1411 | spin_unlock_irqrestore(&psig->siglock, flags); |
1412 | |||
1413 | return sig; | ||
1405 | } | 1414 | } |
1406 | 1415 | ||
1407 | static void do_notify_parent_cldstop(struct task_struct *tsk, int why) | 1416 | static void do_notify_parent_cldstop(struct task_struct *tsk, int why) |
@@ -1599,7 +1608,7 @@ finish_stop(int stop_count) | |||
1599 | * a group stop in progress and we are the last to stop, | 1608 | * a group stop in progress and we are the last to stop, |
1600 | * report to the parent. When ptraced, every thread reports itself. | 1609 | * report to the parent. When ptraced, every thread reports itself. |
1601 | */ | 1610 | */ |
1602 | if (stop_count == 0 || (current->ptrace & PT_PTRACED)) { | 1611 | if (tracehook_notify_jctl(stop_count == 0, CLD_STOPPED)) { |
1603 | read_lock(&tasklist_lock); | 1612 | read_lock(&tasklist_lock); |
1604 | do_notify_parent_cldstop(current, CLD_STOPPED); | 1613 | do_notify_parent_cldstop(current, CLD_STOPPED); |
1605 | read_unlock(&tasklist_lock); | 1614 | read_unlock(&tasklist_lock); |
@@ -1735,6 +1744,9 @@ relock: | |||
1735 | signal->flags &= ~SIGNAL_CLD_MASK; | 1744 | signal->flags &= ~SIGNAL_CLD_MASK; |
1736 | spin_unlock_irq(&sighand->siglock); | 1745 | spin_unlock_irq(&sighand->siglock); |
1737 | 1746 | ||
1747 | if (unlikely(!tracehook_notify_jctl(1, why))) | ||
1748 | goto relock; | ||
1749 | |||
1738 | read_lock(&tasklist_lock); | 1750 | read_lock(&tasklist_lock); |
1739 | do_notify_parent_cldstop(current->group_leader, why); | 1751 | do_notify_parent_cldstop(current->group_leader, why); |
1740 | read_unlock(&tasklist_lock); | 1752 | read_unlock(&tasklist_lock); |
@@ -1748,17 +1760,33 @@ relock: | |||
1748 | do_signal_stop(0)) | 1760 | do_signal_stop(0)) |
1749 | goto relock; | 1761 | goto relock; |
1750 | 1762 | ||
1751 | signr = dequeue_signal(current, ¤t->blocked, info); | 1763 | /* |
1752 | if (!signr) | 1764 | * Tracing can induce an artifical signal and choose sigaction. |
1753 | break; /* will return 0 */ | 1765 | * The return value in @signr determines the default action, |
1766 | * but @info->si_signo is the signal number we will report. | ||
1767 | */ | ||
1768 | signr = tracehook_get_signal(current, regs, info, return_ka); | ||
1769 | if (unlikely(signr < 0)) | ||
1770 | goto relock; | ||
1771 | if (unlikely(signr != 0)) | ||
1772 | ka = return_ka; | ||
1773 | else { | ||
1774 | signr = dequeue_signal(current, ¤t->blocked, | ||
1775 | info); | ||
1754 | 1776 | ||
1755 | if (signr != SIGKILL) { | ||
1756 | signr = ptrace_signal(signr, info, regs, cookie); | ||
1757 | if (!signr) | 1777 | if (!signr) |
1758 | continue; | 1778 | break; /* will return 0 */ |
1779 | |||
1780 | if (signr != SIGKILL) { | ||
1781 | signr = ptrace_signal(signr, info, | ||
1782 | regs, cookie); | ||
1783 | if (!signr) | ||
1784 | continue; | ||
1785 | } | ||
1786 | |||
1787 | ka = &sighand->action[signr-1]; | ||
1759 | } | 1788 | } |
1760 | 1789 | ||
1761 | ka = &sighand->action[signr-1]; | ||
1762 | if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */ | 1790 | if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */ |
1763 | continue; | 1791 | continue; |
1764 | if (ka->sa.sa_handler != SIG_DFL) { | 1792 | if (ka->sa.sa_handler != SIG_DFL) { |
@@ -1806,7 +1834,7 @@ relock: | |||
1806 | spin_lock_irq(&sighand->siglock); | 1834 | spin_lock_irq(&sighand->siglock); |
1807 | } | 1835 | } |
1808 | 1836 | ||
1809 | if (likely(do_signal_stop(signr))) { | 1837 | if (likely(do_signal_stop(info->si_signo))) { |
1810 | /* It released the siglock. */ | 1838 | /* It released the siglock. */ |
1811 | goto relock; | 1839 | goto relock; |
1812 | } | 1840 | } |
@@ -1827,7 +1855,7 @@ relock: | |||
1827 | 1855 | ||
1828 | if (sig_kernel_coredump(signr)) { | 1856 | if (sig_kernel_coredump(signr)) { |
1829 | if (print_fatal_signals) | 1857 | if (print_fatal_signals) |
1830 | print_fatal_signal(regs, signr); | 1858 | print_fatal_signal(regs, info->si_signo); |
1831 | /* | 1859 | /* |
1832 | * If it was able to dump core, this kills all | 1860 | * If it was able to dump core, this kills all |
1833 | * other threads in the group and synchronizes with | 1861 | * other threads in the group and synchronizes with |
@@ -1836,13 +1864,13 @@ relock: | |||
1836 | * first and our do_group_exit call below will use | 1864 | * first and our do_group_exit call below will use |
1837 | * that value and ignore the one we pass it. | 1865 | * that value and ignore the one we pass it. |
1838 | */ | 1866 | */ |
1839 | do_coredump((long)signr, signr, regs); | 1867 | do_coredump(info->si_signo, info->si_signo, regs); |
1840 | } | 1868 | } |
1841 | 1869 | ||
1842 | /* | 1870 | /* |
1843 | * Death signals, no core dump. | 1871 | * Death signals, no core dump. |
1844 | */ | 1872 | */ |
1845 | do_group_exit(signr); | 1873 | do_group_exit(info->si_signo); |
1846 | /* NOTREACHED */ | 1874 | /* NOTREACHED */ |
1847 | } | 1875 | } |
1848 | spin_unlock_irq(&sighand->siglock); | 1876 | spin_unlock_irq(&sighand->siglock); |
@@ -1884,7 +1912,7 @@ void exit_signals(struct task_struct *tsk) | |||
1884 | out: | 1912 | out: |
1885 | spin_unlock_irq(&tsk->sighand->siglock); | 1913 | spin_unlock_irq(&tsk->sighand->siglock); |
1886 | 1914 | ||
1887 | if (unlikely(group_stop)) { | 1915 | if (unlikely(group_stop) && tracehook_notify_jctl(1, CLD_STOPPED)) { |
1888 | read_lock(&tasklist_lock); | 1916 | read_lock(&tasklist_lock); |
1889 | do_notify_parent_cldstop(tsk, CLD_STOPPED); | 1917 | do_notify_parent_cldstop(tsk, CLD_STOPPED); |
1890 | read_unlock(&tasklist_lock); | 1918 | read_unlock(&tasklist_lock); |
@@ -1895,7 +1923,6 @@ EXPORT_SYMBOL(recalc_sigpending); | |||
1895 | EXPORT_SYMBOL_GPL(dequeue_signal); | 1923 | EXPORT_SYMBOL_GPL(dequeue_signal); |
1896 | EXPORT_SYMBOL(flush_signals); | 1924 | EXPORT_SYMBOL(flush_signals); |
1897 | EXPORT_SYMBOL(force_sig); | 1925 | EXPORT_SYMBOL(force_sig); |
1898 | EXPORT_SYMBOL(ptrace_notify); | ||
1899 | EXPORT_SYMBOL(send_sig); | 1926 | EXPORT_SYMBOL(send_sig); |
1900 | EXPORT_SYMBOL(send_sig_info); | 1927 | EXPORT_SYMBOL(send_sig_info); |
1901 | EXPORT_SYMBOL(sigprocmask); | 1928 | EXPORT_SYMBOL(sigprocmask); |
@@ -2299,7 +2326,7 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) | |||
2299 | * (for example, SIGCHLD), shall cause the pending signal to | 2326 | * (for example, SIGCHLD), shall cause the pending signal to |
2300 | * be discarded, whether or not it is blocked" | 2327 | * be discarded, whether or not it is blocked" |
2301 | */ | 2328 | */ |
2302 | if (__sig_ignored(t, sig)) { | 2329 | if (sig_handler_ignored(sig_handler(t, sig), sig)) { |
2303 | sigemptyset(&mask); | 2330 | sigemptyset(&mask); |
2304 | sigaddset(&mask, sig); | 2331 | sigaddset(&mask, sig); |
2305 | rm_from_queue_full(&mask, &t->signal->shared_pending); | 2332 | rm_from_queue_full(&mask, &t->signal->shared_pending); |