diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 108 |
1 files changed, 84 insertions, 24 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 934ae5e687b9..906ae5a1779c 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -159,6 +159,10 @@ void recalc_sigpending(void) | |||
159 | 159 | ||
160 | /* Given the mask, find the first available signal that should be serviced. */ | 160 | /* Given the mask, find the first available signal that should be serviced. */ |
161 | 161 | ||
162 | #define SYNCHRONOUS_MASK \ | ||
163 | (sigmask(SIGSEGV) | sigmask(SIGBUS) | sigmask(SIGILL) | \ | ||
164 | sigmask(SIGTRAP) | sigmask(SIGFPE)) | ||
165 | |||
162 | int next_signal(struct sigpending *pending, sigset_t *mask) | 166 | int next_signal(struct sigpending *pending, sigset_t *mask) |
163 | { | 167 | { |
164 | unsigned long i, *s, *m, x; | 168 | unsigned long i, *s, *m, x; |
@@ -166,26 +170,39 @@ int next_signal(struct sigpending *pending, sigset_t *mask) | |||
166 | 170 | ||
167 | s = pending->signal.sig; | 171 | s = pending->signal.sig; |
168 | m = mask->sig; | 172 | m = mask->sig; |
173 | |||
174 | /* | ||
175 | * Handle the first word specially: it contains the | ||
176 | * synchronous signals that need to be dequeued first. | ||
177 | */ | ||
178 | x = *s &~ *m; | ||
179 | if (x) { | ||
180 | if (x & SYNCHRONOUS_MASK) | ||
181 | x &= SYNCHRONOUS_MASK; | ||
182 | sig = ffz(~x) + 1; | ||
183 | return sig; | ||
184 | } | ||
185 | |||
169 | switch (_NSIG_WORDS) { | 186 | switch (_NSIG_WORDS) { |
170 | default: | 187 | default: |
171 | for (i = 0; i < _NSIG_WORDS; ++i, ++s, ++m) | 188 | for (i = 1; i < _NSIG_WORDS; ++i) { |
172 | if ((x = *s &~ *m) != 0) { | 189 | x = *++s &~ *++m; |
173 | sig = ffz(~x) + i*_NSIG_BPW + 1; | 190 | if (!x) |
174 | break; | 191 | continue; |
175 | } | 192 | sig = ffz(~x) + i*_NSIG_BPW + 1; |
193 | break; | ||
194 | } | ||
176 | break; | 195 | break; |
177 | 196 | ||
178 | case 2: if ((x = s[0] &~ m[0]) != 0) | 197 | case 2: |
179 | sig = 1; | 198 | x = s[1] &~ m[1]; |
180 | else if ((x = s[1] &~ m[1]) != 0) | 199 | if (!x) |
181 | sig = _NSIG_BPW + 1; | ||
182 | else | ||
183 | break; | 200 | break; |
184 | sig += ffz(~x); | 201 | sig = ffz(~x) + _NSIG_BPW + 1; |
185 | break; | 202 | break; |
186 | 203 | ||
187 | case 1: if ((x = *s &~ *m) != 0) | 204 | case 1: |
188 | sig = ffz(~x) + 1; | 205 | /* Nothing to do */ |
189 | break; | 206 | break; |
190 | } | 207 | } |
191 | 208 | ||
@@ -228,7 +245,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi | |||
228 | 245 | ||
229 | if (override_rlimit || | 246 | if (override_rlimit || |
230 | atomic_read(&user->sigpending) <= | 247 | atomic_read(&user->sigpending) <= |
231 | t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur) { | 248 | task_rlimit(t, RLIMIT_SIGPENDING)) { |
232 | q = kmem_cache_alloc(sigqueue_cachep, flags); | 249 | q = kmem_cache_alloc(sigqueue_cachep, flags); |
233 | } else { | 250 | } else { |
234 | print_dropped_signal(sig); | 251 | print_dropped_signal(sig); |
@@ -625,7 +642,7 @@ static inline bool si_fromuser(const struct siginfo *info) | |||
625 | static int check_kill_permission(int sig, struct siginfo *info, | 642 | static int check_kill_permission(int sig, struct siginfo *info, |
626 | struct task_struct *t) | 643 | struct task_struct *t) |
627 | { | 644 | { |
628 | const struct cred *cred = current_cred(), *tcred; | 645 | const struct cred *cred, *tcred; |
629 | struct pid *sid; | 646 | struct pid *sid; |
630 | int error; | 647 | int error; |
631 | 648 | ||
@@ -639,8 +656,10 @@ static int check_kill_permission(int sig, struct siginfo *info, | |||
639 | if (error) | 656 | if (error) |
640 | return error; | 657 | return error; |
641 | 658 | ||
659 | cred = current_cred(); | ||
642 | tcred = __task_cred(t); | 660 | tcred = __task_cred(t); |
643 | if ((cred->euid ^ tcred->suid) && | 661 | if (!same_thread_group(current, t) && |
662 | (cred->euid ^ tcred->suid) && | ||
644 | (cred->euid ^ tcred->uid) && | 663 | (cred->euid ^ tcred->uid) && |
645 | (cred->uid ^ tcred->suid) && | 664 | (cred->uid ^ tcred->suid) && |
646 | (cred->uid ^ tcred->uid) && | 665 | (cred->uid ^ tcred->uid) && |
@@ -1066,23 +1085,24 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t) | |||
1066 | /* | 1085 | /* |
1067 | * Nuke all other threads in the group. | 1086 | * Nuke all other threads in the group. |
1068 | */ | 1087 | */ |
1069 | void zap_other_threads(struct task_struct *p) | 1088 | int zap_other_threads(struct task_struct *p) |
1070 | { | 1089 | { |
1071 | struct task_struct *t; | 1090 | struct task_struct *t = p; |
1091 | int count = 0; | ||
1072 | 1092 | ||
1073 | p->signal->group_stop_count = 0; | 1093 | p->signal->group_stop_count = 0; |
1074 | 1094 | ||
1075 | for (t = next_thread(p); t != p; t = next_thread(t)) { | 1095 | while_each_thread(p, t) { |
1076 | /* | 1096 | count++; |
1077 | * Don't bother with already dead threads | 1097 | |
1078 | */ | 1098 | /* Don't bother with already dead threads */ |
1079 | if (t->exit_state) | 1099 | if (t->exit_state) |
1080 | continue; | 1100 | continue; |
1081 | |||
1082 | /* SIGKILL will be handled before any pending SIGSTOP */ | ||
1083 | sigaddset(&t->pending.signal, SIGKILL); | 1101 | sigaddset(&t->pending.signal, SIGKILL); |
1084 | signal_wake_up(t, 1); | 1102 | signal_wake_up(t, 1); |
1085 | } | 1103 | } |
1104 | |||
1105 | return count; | ||
1086 | } | 1106 | } |
1087 | 1107 | ||
1088 | struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long *flags) | 1108 | struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long *flags) |
@@ -2718,3 +2738,43 @@ void __init signals_init(void) | |||
2718 | { | 2738 | { |
2719 | sigqueue_cachep = KMEM_CACHE(sigqueue, SLAB_PANIC); | 2739 | sigqueue_cachep = KMEM_CACHE(sigqueue, SLAB_PANIC); |
2720 | } | 2740 | } |
2741 | |||
2742 | #ifdef CONFIG_KGDB_KDB | ||
2743 | #include <linux/kdb.h> | ||
2744 | /* | ||
2745 | * kdb_send_sig_info - Allows kdb to send signals without exposing | ||
2746 | * signal internals. This function checks if the required locks are | ||
2747 | * available before calling the main signal code, to avoid kdb | ||
2748 | * deadlocks. | ||
2749 | */ | ||
2750 | void | ||
2751 | kdb_send_sig_info(struct task_struct *t, struct siginfo *info) | ||
2752 | { | ||
2753 | static struct task_struct *kdb_prev_t; | ||
2754 | int sig, new_t; | ||
2755 | if (!spin_trylock(&t->sighand->siglock)) { | ||
2756 | kdb_printf("Can't do kill command now.\n" | ||
2757 | "The sigmask lock is held somewhere else in " | ||
2758 | "kernel, try again later\n"); | ||
2759 | return; | ||
2760 | } | ||
2761 | spin_unlock(&t->sighand->siglock); | ||
2762 | new_t = kdb_prev_t != t; | ||
2763 | kdb_prev_t = t; | ||
2764 | if (t->state != TASK_RUNNING && new_t) { | ||
2765 | kdb_printf("Process is not RUNNING, sending a signal from " | ||
2766 | "kdb risks deadlock\n" | ||
2767 | "on the run queue locks. " | ||
2768 | "The signal has _not_ been sent.\n" | ||
2769 | "Reissue the kill command if you want to risk " | ||
2770 | "the deadlock.\n"); | ||
2771 | return; | ||
2772 | } | ||
2773 | sig = info->si_signo; | ||
2774 | if (send_sig_info(sig, info, t)) | ||
2775 | kdb_printf("Fail to deliver Signal %d to process %d.\n", | ||
2776 | sig, t->pid); | ||
2777 | else | ||
2778 | kdb_printf("Signal %d is sent to process %d.\n", sig, t->pid); | ||
2779 | } | ||
2780 | #endif /* CONFIG_KGDB_KDB */ | ||