diff options
Diffstat (limited to 'kernel/signal.c')
| -rw-r--r-- | kernel/signal.c | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 1c8814481a11..d8034737db4c 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -55,10 +55,22 @@ static int sig_handler_ignored(void __user *handler, int sig) | |||
| 55 | (handler == SIG_DFL && sig_kernel_ignore(sig)); | 55 | (handler == SIG_DFL && sig_kernel_ignore(sig)); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | static int sig_ignored(struct task_struct *t, int sig) | 58 | static int sig_task_ignored(struct task_struct *t, int sig, |
| 59 | int from_ancestor_ns) | ||
| 59 | { | 60 | { |
| 60 | void __user *handler; | 61 | void __user *handler; |
| 61 | 62 | ||
| 63 | handler = sig_handler(t, sig); | ||
| 64 | |||
| 65 | if (unlikely(t->signal->flags & SIGNAL_UNKILLABLE) && | ||
| 66 | handler == SIG_DFL && !from_ancestor_ns) | ||
| 67 | return 1; | ||
| 68 | |||
| 69 | return sig_handler_ignored(handler, sig); | ||
| 70 | } | ||
| 71 | |||
| 72 | static int sig_ignored(struct task_struct *t, int sig, int from_ancestor_ns) | ||
| 73 | { | ||
| 62 | /* | 74 | /* |
| 63 | * Blocked signals are never ignored, since the | 75 | * Blocked signals are never ignored, since the |
| 64 | * signal handler may change by the time it is | 76 | * signal handler may change by the time it is |
| @@ -67,14 +79,13 @@ static int sig_ignored(struct task_struct *t, int sig) | |||
| 67 | if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) | 79 | if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) |
| 68 | return 0; | 80 | return 0; |
| 69 | 81 | ||
| 70 | handler = sig_handler(t, sig); | 82 | if (!sig_task_ignored(t, sig, from_ancestor_ns)) |
| 71 | if (!sig_handler_ignored(handler, sig)) | ||
| 72 | return 0; | 83 | return 0; |
| 73 | 84 | ||
| 74 | /* | 85 | /* |
| 75 | * Tracers may want to know about even ignored signals. | 86 | * Tracers may want to know about even ignored signals. |
| 76 | */ | 87 | */ |
| 77 | return !tracehook_consider_ignored_signal(t, sig, handler); | 88 | return !tracehook_consider_ignored_signal(t, sig); |
| 78 | } | 89 | } |
| 79 | 90 | ||
| 80 | /* | 91 | /* |
| @@ -318,7 +329,7 @@ int unhandled_signal(struct task_struct *tsk, int sig) | |||
| 318 | return 1; | 329 | return 1; |
| 319 | if (handler != SIG_IGN && handler != SIG_DFL) | 330 | if (handler != SIG_IGN && handler != SIG_DFL) |
| 320 | return 0; | 331 | return 0; |
| 321 | return !tracehook_consider_fatal_signal(tsk, sig, handler); | 332 | return !tracehook_consider_fatal_signal(tsk, sig); |
| 322 | } | 333 | } |
| 323 | 334 | ||
| 324 | 335 | ||
| @@ -624,7 +635,7 @@ static int check_kill_permission(int sig, struct siginfo *info, | |||
| 624 | * Returns true if the signal should be actually delivered, otherwise | 635 | * Returns true if the signal should be actually delivered, otherwise |
| 625 | * it should be dropped. | 636 | * it should be dropped. |
| 626 | */ | 637 | */ |
| 627 | static int prepare_signal(int sig, struct task_struct *p) | 638 | static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns) |
| 628 | { | 639 | { |
| 629 | struct signal_struct *signal = p->signal; | 640 | struct signal_struct *signal = p->signal; |
| 630 | struct task_struct *t; | 641 | struct task_struct *t; |
| @@ -708,7 +719,7 @@ static int prepare_signal(int sig, struct task_struct *p) | |||
| 708 | } | 719 | } |
| 709 | } | 720 | } |
| 710 | 721 | ||
| 711 | return !sig_ignored(p, sig); | 722 | return !sig_ignored(p, sig, from_ancestor_ns); |
| 712 | } | 723 | } |
| 713 | 724 | ||
| 714 | /* | 725 | /* |
| @@ -777,7 +788,7 @@ static void complete_signal(int sig, struct task_struct *p, int group) | |||
| 777 | !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) && | 788 | !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) && |
| 778 | !sigismember(&t->real_blocked, sig) && | 789 | !sigismember(&t->real_blocked, sig) && |
| 779 | (sig == SIGKILL || | 790 | (sig == SIGKILL || |
| 780 | !tracehook_consider_fatal_signal(t, sig, SIG_DFL))) { | 791 | !tracehook_consider_fatal_signal(t, sig))) { |
| 781 | /* | 792 | /* |
| 782 | * This signal will be fatal to the whole group. | 793 | * This signal will be fatal to the whole group. |
| 783 | */ | 794 | */ |
| @@ -813,8 +824,8 @@ static inline int legacy_queue(struct sigpending *signals, int sig) | |||
| 813 | return (sig < SIGRTMIN) && sigismember(&signals->signal, sig); | 824 | return (sig < SIGRTMIN) && sigismember(&signals->signal, sig); |
| 814 | } | 825 | } |
| 815 | 826 | ||
| 816 | static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | 827 | static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, |
| 817 | int group) | 828 | int group, int from_ancestor_ns) |
| 818 | { | 829 | { |
| 819 | struct sigpending *pending; | 830 | struct sigpending *pending; |
| 820 | struct sigqueue *q; | 831 | struct sigqueue *q; |
| @@ -822,7 +833,8 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
| 822 | trace_sched_signal_send(sig, t); | 833 | trace_sched_signal_send(sig, t); |
| 823 | 834 | ||
| 824 | assert_spin_locked(&t->sighand->siglock); | 835 | assert_spin_locked(&t->sighand->siglock); |
| 825 | if (!prepare_signal(sig, t)) | 836 | |
| 837 | if (!prepare_signal(sig, t, from_ancestor_ns)) | ||
| 826 | return 0; | 838 | return 0; |
| 827 | 839 | ||
| 828 | pending = group ? &t->signal->shared_pending : &t->pending; | 840 | pending = group ? &t->signal->shared_pending : &t->pending; |
| @@ -871,6 +883,8 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
| 871 | break; | 883 | break; |
| 872 | default: | 884 | default: |
| 873 | copy_siginfo(&q->info, info); | 885 | copy_siginfo(&q->info, info); |
| 886 | if (from_ancestor_ns) | ||
| 887 | q->info.si_pid = 0; | ||
| 874 | break; | 888 | break; |
| 875 | } | 889 | } |
| 876 | } else if (!is_si_special(info)) { | 890 | } else if (!is_si_special(info)) { |
| @@ -889,6 +903,20 @@ out_set: | |||
| 889 | return 0; | 903 | return 0; |
| 890 | } | 904 | } |
| 891 | 905 | ||
| 906 | static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | ||
| 907 | int group) | ||
| 908 | { | ||
| 909 | int from_ancestor_ns = 0; | ||
| 910 | |||
| 911 | #ifdef CONFIG_PID_NS | ||
| 912 | if (!is_si_special(info) && SI_FROMUSER(info) && | ||
| 913 | task_pid_nr_ns(current, task_active_pid_ns(t)) <= 0) | ||
| 914 | from_ancestor_ns = 1; | ||
| 915 | #endif | ||
| 916 | |||
| 917 | return __send_signal(sig, info, t, group, from_ancestor_ns); | ||
| 918 | } | ||
| 919 | |||
| 892 | int print_fatal_signals; | 920 | int print_fatal_signals; |
| 893 | 921 | ||
| 894 | static void print_fatal_signal(struct pt_regs *regs, int signr) | 922 | static void print_fatal_signal(struct pt_regs *regs, int signr) |
| @@ -1133,7 +1161,7 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid, | |||
| 1133 | if (sig && p->sighand) { | 1161 | if (sig && p->sighand) { |
| 1134 | unsigned long flags; | 1162 | unsigned long flags; |
| 1135 | spin_lock_irqsave(&p->sighand->siglock, flags); | 1163 | spin_lock_irqsave(&p->sighand->siglock, flags); |
| 1136 | ret = __group_send_sig_info(sig, info, p); | 1164 | ret = __send_signal(sig, info, p, 1, 0); |
| 1137 | spin_unlock_irqrestore(&p->sighand->siglock, flags); | 1165 | spin_unlock_irqrestore(&p->sighand->siglock, flags); |
| 1138 | } | 1166 | } |
| 1139 | out_unlock: | 1167 | out_unlock: |
| @@ -1320,7 +1348,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) | |||
| 1320 | goto ret; | 1348 | goto ret; |
| 1321 | 1349 | ||
| 1322 | ret = 1; /* the signal is ignored */ | 1350 | ret = 1; /* the signal is ignored */ |
| 1323 | if (!prepare_signal(sig, t)) | 1351 | if (!prepare_signal(sig, t, 0)) |
| 1324 | goto out; | 1352 | goto out; |
| 1325 | 1353 | ||
| 1326 | ret = 0; | 1354 | ret = 0; |
| @@ -1844,9 +1872,16 @@ relock: | |||
| 1844 | 1872 | ||
| 1845 | /* | 1873 | /* |
| 1846 | * Global init gets no signals it doesn't want. | 1874 | * Global init gets no signals it doesn't want. |
| 1875 | * Container-init gets no signals it doesn't want from same | ||
| 1876 | * container. | ||
| 1877 | * | ||
| 1878 | * Note that if global/container-init sees a sig_kernel_only() | ||
| 1879 | * signal here, the signal must have been generated internally | ||
| 1880 | * or must have come from an ancestor namespace. In either | ||
| 1881 | * case, the signal cannot be dropped. | ||
| 1847 | */ | 1882 | */ |
| 1848 | if (unlikely(signal->flags & SIGNAL_UNKILLABLE) && | 1883 | if (unlikely(signal->flags & SIGNAL_UNKILLABLE) && |
| 1849 | !signal_group_exit(signal)) | 1884 | !sig_kernel_only(signr)) |
| 1850 | continue; | 1885 | continue; |
| 1851 | 1886 | ||
| 1852 | if (sig_kernel_stop(signr)) { | 1887 | if (sig_kernel_stop(signr)) { |
