diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 11 | ||||
-rw-r--r-- | include/linux/sched.h | 13 | ||||
-rw-r--r-- | kernel/signal.c | 46 |
3 files changed, 52 insertions, 18 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 332fe3b47e0c..1d28812260cd 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2031,8 +2031,15 @@ and is between 256 and 4096 characters. It is defined in the file | |||
2031 | 2031 | ||
2032 | print-fatal-signals= | 2032 | print-fatal-signals= |
2033 | [KNL] debug: print fatal signals | 2033 | [KNL] debug: print fatal signals |
2034 | print-fatal-signals=1: print segfault info to | 2034 | |
2035 | the kernel console. | 2035 | If enabled, warn about various signal handling |
2036 | related application anomalies: too many signals, | ||
2037 | too many POSIX.1 timers, fatal signals causing a | ||
2038 | coredump - etc. | ||
2039 | |||
2040 | If you hit the warning due to signal overflow, | ||
2041 | you might want to try "ulimit -i unlimited". | ||
2042 | |||
2036 | default: off. | 2043 | default: off. |
2037 | 2044 | ||
2038 | printk.time= Show timing data prefixed to each printk message line | 2045 | printk.time= Show timing data prefixed to each printk message line |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 49be8f7c05f6..882dc48163b4 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -2086,11 +2086,18 @@ static inline int is_si_special(const struct siginfo *info) | |||
2086 | return info <= SEND_SIG_FORCED; | 2086 | return info <= SEND_SIG_FORCED; |
2087 | } | 2087 | } |
2088 | 2088 | ||
2089 | /* True if we are on the alternate signal stack. */ | 2089 | /* |
2090 | 2090 | * True if we are on the alternate signal stack. | |
2091 | */ | ||
2091 | static inline int on_sig_stack(unsigned long sp) | 2092 | static inline int on_sig_stack(unsigned long sp) |
2092 | { | 2093 | { |
2093 | return (sp - current->sas_ss_sp < current->sas_ss_size); | 2094 | #ifdef CONFIG_STACK_GROWSUP |
2095 | return sp >= current->sas_ss_sp && | ||
2096 | sp - current->sas_ss_sp < current->sas_ss_size; | ||
2097 | #else | ||
2098 | return sp > current->sas_ss_sp && | ||
2099 | sp - current->sas_ss_sp <= current->sas_ss_size; | ||
2100 | #endif | ||
2094 | } | 2101 | } |
2095 | 2102 | ||
2096 | static inline int sas_ss_flags(unsigned long sp) | 2103 | static inline int sas_ss_flags(unsigned long sp) |
diff --git a/kernel/signal.c b/kernel/signal.c index 6705320784fd..fe08008133da 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/ratelimit.h> | ||
25 | #include <linux/tracehook.h> | 26 | #include <linux/tracehook.h> |
26 | #include <linux/capability.h> | 27 | #include <linux/capability.h> |
27 | #include <linux/freezer.h> | 28 | #include <linux/freezer.h> |
@@ -41,6 +42,8 @@ | |||
41 | 42 | ||
42 | static struct kmem_cache *sigqueue_cachep; | 43 | static struct kmem_cache *sigqueue_cachep; |
43 | 44 | ||
45 | int print_fatal_signals __read_mostly; | ||
46 | |||
44 | static void __user *sig_handler(struct task_struct *t, int sig) | 47 | static void __user *sig_handler(struct task_struct *t, int sig) |
45 | { | 48 | { |
46 | return t->sighand->action[sig - 1].sa.sa_handler; | 49 | return t->sighand->action[sig - 1].sa.sa_handler; |
@@ -159,7 +162,7 @@ int next_signal(struct sigpending *pending, sigset_t *mask) | |||
159 | { | 162 | { |
160 | unsigned long i, *s, *m, x; | 163 | unsigned long i, *s, *m, x; |
161 | int sig = 0; | 164 | int sig = 0; |
162 | 165 | ||
163 | s = pending->signal.sig; | 166 | s = pending->signal.sig; |
164 | m = mask->sig; | 167 | m = mask->sig; |
165 | switch (_NSIG_WORDS) { | 168 | switch (_NSIG_WORDS) { |
@@ -184,17 +187,31 @@ int next_signal(struct sigpending *pending, sigset_t *mask) | |||
184 | sig = ffz(~x) + 1; | 187 | sig = ffz(~x) + 1; |
185 | break; | 188 | break; |
186 | } | 189 | } |
187 | 190 | ||
188 | return sig; | 191 | return sig; |
189 | } | 192 | } |
190 | 193 | ||
194 | static inline void print_dropped_signal(int sig) | ||
195 | { | ||
196 | static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10); | ||
197 | |||
198 | if (!print_fatal_signals) | ||
199 | return; | ||
200 | |||
201 | if (!__ratelimit(&ratelimit_state)) | ||
202 | return; | ||
203 | |||
204 | printk(KERN_INFO "%s/%d: reached RLIMIT_SIGPENDING, dropped signal %d\n", | ||
205 | current->comm, current->pid, sig); | ||
206 | } | ||
207 | |||
191 | /* | 208 | /* |
192 | * allocate a new signal queue record | 209 | * allocate a new signal queue record |
193 | * - this may be called without locks if and only if t == current, otherwise an | 210 | * - this may be called without locks if and only if t == current, otherwise an |
194 | * appopriate lock must be held to stop the target task from exiting | 211 | * appopriate lock must be held to stop the target task from exiting |
195 | */ | 212 | */ |
196 | static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags, | 213 | static struct sigqueue * |
197 | int override_rlimit) | 214 | __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimit) |
198 | { | 215 | { |
199 | struct sigqueue *q = NULL; | 216 | struct sigqueue *q = NULL; |
200 | struct user_struct *user; | 217 | struct user_struct *user; |
@@ -207,10 +224,15 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags, | |||
207 | */ | 224 | */ |
208 | user = get_uid(__task_cred(t)->user); | 225 | user = get_uid(__task_cred(t)->user); |
209 | atomic_inc(&user->sigpending); | 226 | atomic_inc(&user->sigpending); |
227 | |||
210 | if (override_rlimit || | 228 | if (override_rlimit || |
211 | atomic_read(&user->sigpending) <= | 229 | atomic_read(&user->sigpending) <= |
212 | t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur) | 230 | t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur) { |
213 | q = kmem_cache_alloc(sigqueue_cachep, flags); | 231 | q = kmem_cache_alloc(sigqueue_cachep, flags); |
232 | } else { | ||
233 | print_dropped_signal(sig); | ||
234 | } | ||
235 | |||
214 | if (unlikely(q == NULL)) { | 236 | if (unlikely(q == NULL)) { |
215 | atomic_dec(&user->sigpending); | 237 | atomic_dec(&user->sigpending); |
216 | free_uid(user); | 238 | free_uid(user); |
@@ -869,7 +891,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
869 | else | 891 | else |
870 | override_rlimit = 0; | 892 | override_rlimit = 0; |
871 | 893 | ||
872 | q = __sigqueue_alloc(t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE, | 894 | q = __sigqueue_alloc(sig, t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE, |
873 | override_rlimit); | 895 | override_rlimit); |
874 | if (q) { | 896 | if (q) { |
875 | list_add_tail(&q->list, &pending->list); | 897 | list_add_tail(&q->list, &pending->list); |
@@ -925,8 +947,6 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
925 | return __send_signal(sig, info, t, group, from_ancestor_ns); | 947 | return __send_signal(sig, info, t, group, from_ancestor_ns); |
926 | } | 948 | } |
927 | 949 | ||
928 | int print_fatal_signals; | ||
929 | |||
930 | static void print_fatal_signal(struct pt_regs *regs, int signr) | 950 | static void print_fatal_signal(struct pt_regs *regs, int signr) |
931 | { | 951 | { |
932 | printk("%s/%d: potentially unexpected fatal signal %d.\n", | 952 | printk("%s/%d: potentially unexpected fatal signal %d.\n", |
@@ -1293,19 +1313,19 @@ EXPORT_SYMBOL(kill_pid); | |||
1293 | * These functions support sending signals using preallocated sigqueue | 1313 | * These functions support sending signals using preallocated sigqueue |
1294 | * structures. This is needed "because realtime applications cannot | 1314 | * structures. This is needed "because realtime applications cannot |
1295 | * afford to lose notifications of asynchronous events, like timer | 1315 | * afford to lose notifications of asynchronous events, like timer |
1296 | * expirations or I/O completions". In the case of Posix Timers | 1316 | * expirations or I/O completions". In the case of Posix Timers |
1297 | * we allocate the sigqueue structure from the timer_create. If this | 1317 | * we allocate the sigqueue structure from the timer_create. If this |
1298 | * allocation fails we are able to report the failure to the application | 1318 | * allocation fails we are able to report the failure to the application |
1299 | * with an EAGAIN error. | 1319 | * with an EAGAIN error. |
1300 | */ | 1320 | */ |
1301 | |||
1302 | struct sigqueue *sigqueue_alloc(void) | 1321 | struct sigqueue *sigqueue_alloc(void) |
1303 | { | 1322 | { |
1304 | struct sigqueue *q; | 1323 | struct sigqueue *q = __sigqueue_alloc(-1, current, GFP_KERNEL, 0); |
1305 | 1324 | ||
1306 | if ((q = __sigqueue_alloc(current, GFP_KERNEL, 0))) | 1325 | if (q) |
1307 | q->flags |= SIGQUEUE_PREALLOC; | 1326 | q->flags |= SIGQUEUE_PREALLOC; |
1308 | return(q); | 1327 | |
1328 | return q; | ||
1309 | } | 1329 | } |
1310 | 1330 | ||
1311 | void sigqueue_free(struct sigqueue *q) | 1331 | void sigqueue_free(struct sigqueue *q) |