diff options
author | James Morris <jmorris@namei.org> | 2009-05-08 03:56:47 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2009-05-08 03:56:47 -0400 |
commit | d254117099d711f215e62427f55dfb8ebd5ad011 (patch) | |
tree | 0848ff8dd74314fec14a86497f8d288c86ba7c65 /kernel/signal.c | |
parent | 07ff7a0b187f3951788f64ae1f30e8109bc8e9eb (diff) | |
parent | 8c9ed899b44c19e81859fbb0e9d659fe2f8630fc (diff) |
Merge branch 'master' into next
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 f93efec14ff5..d2dd9cf5dcc6 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 | /* |
@@ -323,7 +334,7 @@ int unhandled_signal(struct task_struct *tsk, int sig) | |||
323 | return 1; | 334 | return 1; |
324 | if (handler != SIG_IGN && handler != SIG_DFL) | 335 | if (handler != SIG_IGN && handler != SIG_DFL) |
325 | return 0; | 336 | return 0; |
326 | return !tracehook_consider_fatal_signal(tsk, sig, handler); | 337 | return !tracehook_consider_fatal_signal(tsk, sig); |
327 | } | 338 | } |
328 | 339 | ||
329 | 340 | ||
@@ -629,7 +640,7 @@ static int check_kill_permission(int sig, struct siginfo *info, | |||
629 | * Returns true if the signal should be actually delivered, otherwise | 640 | * Returns true if the signal should be actually delivered, otherwise |
630 | * it should be dropped. | 641 | * it should be dropped. |
631 | */ | 642 | */ |
632 | static int prepare_signal(int sig, struct task_struct *p) | 643 | static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns) |
633 | { | 644 | { |
634 | struct signal_struct *signal = p->signal; | 645 | struct signal_struct *signal = p->signal; |
635 | struct task_struct *t; | 646 | struct task_struct *t; |
@@ -713,7 +724,7 @@ static int prepare_signal(int sig, struct task_struct *p) | |||
713 | } | 724 | } |
714 | } | 725 | } |
715 | 726 | ||
716 | return !sig_ignored(p, sig); | 727 | return !sig_ignored(p, sig, from_ancestor_ns); |
717 | } | 728 | } |
718 | 729 | ||
719 | /* | 730 | /* |
@@ -782,7 +793,7 @@ static void complete_signal(int sig, struct task_struct *p, int group) | |||
782 | !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) && | 793 | !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) && |
783 | !sigismember(&t->real_blocked, sig) && | 794 | !sigismember(&t->real_blocked, sig) && |
784 | (sig == SIGKILL || | 795 | (sig == SIGKILL || |
785 | !tracehook_consider_fatal_signal(t, sig, SIG_DFL))) { | 796 | !tracehook_consider_fatal_signal(t, sig))) { |
786 | /* | 797 | /* |
787 | * This signal will be fatal to the whole group. | 798 | * This signal will be fatal to the whole group. |
788 | */ | 799 | */ |
@@ -818,8 +829,8 @@ static inline int legacy_queue(struct sigpending *signals, int sig) | |||
818 | return (sig < SIGRTMIN) && sigismember(&signals->signal, sig); | 829 | return (sig < SIGRTMIN) && sigismember(&signals->signal, sig); |
819 | } | 830 | } |
820 | 831 | ||
821 | static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | 832 | static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, |
822 | int group) | 833 | int group, int from_ancestor_ns) |
823 | { | 834 | { |
824 | struct sigpending *pending; | 835 | struct sigpending *pending; |
825 | struct sigqueue *q; | 836 | struct sigqueue *q; |
@@ -827,7 +838,8 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
827 | trace_sched_signal_send(sig, t); | 838 | trace_sched_signal_send(sig, t); |
828 | 839 | ||
829 | assert_spin_locked(&t->sighand->siglock); | 840 | assert_spin_locked(&t->sighand->siglock); |
830 | if (!prepare_signal(sig, t)) | 841 | |
842 | if (!prepare_signal(sig, t, from_ancestor_ns)) | ||
831 | return 0; | 843 | return 0; |
832 | 844 | ||
833 | pending = group ? &t->signal->shared_pending : &t->pending; | 845 | pending = group ? &t->signal->shared_pending : &t->pending; |
@@ -876,6 +888,8 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
876 | break; | 888 | break; |
877 | default: | 889 | default: |
878 | copy_siginfo(&q->info, info); | 890 | copy_siginfo(&q->info, info); |
891 | if (from_ancestor_ns) | ||
892 | q->info.si_pid = 0; | ||
879 | break; | 893 | break; |
880 | } | 894 | } |
881 | } else if (!is_si_special(info)) { | 895 | } else if (!is_si_special(info)) { |
@@ -894,6 +908,20 @@ out_set: | |||
894 | return 0; | 908 | return 0; |
895 | } | 909 | } |
896 | 910 | ||
911 | static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | ||
912 | int group) | ||
913 | { | ||
914 | int from_ancestor_ns = 0; | ||
915 | |||
916 | #ifdef CONFIG_PID_NS | ||
917 | if (!is_si_special(info) && SI_FROMUSER(info) && | ||
918 | task_pid_nr_ns(current, task_active_pid_ns(t)) <= 0) | ||
919 | from_ancestor_ns = 1; | ||
920 | #endif | ||
921 | |||
922 | return __send_signal(sig, info, t, group, from_ancestor_ns); | ||
923 | } | ||
924 | |||
897 | int print_fatal_signals; | 925 | int print_fatal_signals; |
898 | 926 | ||
899 | static void print_fatal_signal(struct pt_regs *regs, int signr) | 927 | static void print_fatal_signal(struct pt_regs *regs, int signr) |
@@ -1138,7 +1166,7 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid, | |||
1138 | if (sig && p->sighand) { | 1166 | if (sig && p->sighand) { |
1139 | unsigned long flags; | 1167 | unsigned long flags; |
1140 | spin_lock_irqsave(&p->sighand->siglock, flags); | 1168 | spin_lock_irqsave(&p->sighand->siglock, flags); |
1141 | ret = __group_send_sig_info(sig, info, p); | 1169 | ret = __send_signal(sig, info, p, 1, 0); |
1142 | spin_unlock_irqrestore(&p->sighand->siglock, flags); | 1170 | spin_unlock_irqrestore(&p->sighand->siglock, flags); |
1143 | } | 1171 | } |
1144 | out_unlock: | 1172 | out_unlock: |
@@ -1325,7 +1353,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) | |||
1325 | goto ret; | 1353 | goto ret; |
1326 | 1354 | ||
1327 | ret = 1; /* the signal is ignored */ | 1355 | ret = 1; /* the signal is ignored */ |
1328 | if (!prepare_signal(sig, t)) | 1356 | if (!prepare_signal(sig, t, 0)) |
1329 | goto out; | 1357 | goto out; |
1330 | 1358 | ||
1331 | ret = 0; | 1359 | ret = 0; |
@@ -1849,9 +1877,16 @@ relock: | |||
1849 | 1877 | ||
1850 | /* | 1878 | /* |
1851 | * Global init gets no signals it doesn't want. | 1879 | * Global init gets no signals it doesn't want. |
1880 | * Container-init gets no signals it doesn't want from same | ||
1881 | * container. | ||
1882 | * | ||
1883 | * Note that if global/container-init sees a sig_kernel_only() | ||
1884 | * signal here, the signal must have been generated internally | ||
1885 | * or must have come from an ancestor namespace. In either | ||
1886 | * case, the signal cannot be dropped. | ||
1852 | */ | 1887 | */ |
1853 | if (unlikely(signal->flags & SIGNAL_UNKILLABLE) && | 1888 | if (unlikely(signal->flags & SIGNAL_UNKILLABLE) && |
1854 | !signal_group_exit(signal)) | 1889 | !sig_kernel_only(signr)) |
1855 | continue; | 1890 | continue; |
1856 | 1891 | ||
1857 | if (sig_kernel_stop(signr)) { | 1892 | if (sig_kernel_stop(signr)) { |