aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 93e72e5feae6..6b982f2cf524 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>
@@ -42,6 +43,8 @@
42 43
43static struct kmem_cache *sigqueue_cachep; 44static struct kmem_cache *sigqueue_cachep;
44 45
46int print_fatal_signals __read_mostly;
47
45static void __user *sig_handler(struct task_struct *t, int sig) 48static void __user *sig_handler(struct task_struct *t, int sig)
46{ 49{
47 return t->sighand->action[sig - 1].sa.sa_handler; 50 return t->sighand->action[sig - 1].sa.sa_handler;
@@ -160,7 +163,7 @@ int next_signal(struct sigpending *pending, sigset_t *mask)
160{ 163{
161 unsigned long i, *s, *m, x; 164 unsigned long i, *s, *m, x;
162 int sig = 0; 165 int sig = 0;
163 166
164 s = pending->signal.sig; 167 s = pending->signal.sig;
165 m = mask->sig; 168 m = mask->sig;
166 switch (_NSIG_WORDS) { 169 switch (_NSIG_WORDS) {
@@ -185,17 +188,31 @@ int next_signal(struct sigpending *pending, sigset_t *mask)
185 sig = ffz(~x) + 1; 188 sig = ffz(~x) + 1;
186 break; 189 break;
187 } 190 }
188 191
189 return sig; 192 return sig;
190} 193}
191 194
195static inline void print_dropped_signal(int sig)
196{
197 static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10);
198
199 if (!print_fatal_signals)
200 return;
201
202 if (!__ratelimit(&ratelimit_state))
203 return;
204
205 printk(KERN_INFO "%s/%d: reached RLIMIT_SIGPENDING, dropped signal %d\n",
206 current->comm, current->pid, sig);
207}
208
192/* 209/*
193 * allocate a new signal queue record 210 * allocate a new signal queue record
194 * - this may be called without locks if and only if t == current, otherwise an 211 * - this may be called without locks if and only if t == current, otherwise an
195 * appopriate lock must be held to stop the target task from exiting 212 * appopriate lock must be held to stop the target task from exiting
196 */ 213 */
197static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags, 214static struct sigqueue *
198 int override_rlimit) 215__sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimit)
199{ 216{
200 struct sigqueue *q = NULL; 217 struct sigqueue *q = NULL;
201 struct user_struct *user; 218 struct user_struct *user;
@@ -208,10 +225,15 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
208 */ 225 */
209 user = get_uid(__task_cred(t)->user); 226 user = get_uid(__task_cred(t)->user);
210 atomic_inc(&user->sigpending); 227 atomic_inc(&user->sigpending);
228
211 if (override_rlimit || 229 if (override_rlimit ||
212 atomic_read(&user->sigpending) <= 230 atomic_read(&user->sigpending) <=
213 t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur) 231 t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur) {
214 q = kmem_cache_alloc(sigqueue_cachep, flags); 232 q = kmem_cache_alloc(sigqueue_cachep, flags);
233 } else {
234 print_dropped_signal(sig);
235 }
236
215 if (unlikely(q == NULL)) { 237 if (unlikely(q == NULL)) {
216 atomic_dec(&user->sigpending); 238 atomic_dec(&user->sigpending);
217 free_uid(user); 239 free_uid(user);
@@ -870,7 +892,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
870 else 892 else
871 override_rlimit = 0; 893 override_rlimit = 0;
872 894
873 q = __sigqueue_alloc(t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE, 895 q = __sigqueue_alloc(sig, t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE,
874 override_rlimit); 896 override_rlimit);
875 if (q) { 897 if (q) {
876 list_add_tail(&q->list, &pending->list); 898 list_add_tail(&q->list, &pending->list);
@@ -935,8 +957,6 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
935 return __send_signal(sig, info, t, group, from_ancestor_ns); 957 return __send_signal(sig, info, t, group, from_ancestor_ns);
936} 958}
937 959
938int print_fatal_signals;
939
940static void print_fatal_signal(struct pt_regs *regs, int signr) 960static void print_fatal_signal(struct pt_regs *regs, int signr)
941{ 961{
942 printk("%s/%d: potentially unexpected fatal signal %d.\n", 962 printk("%s/%d: potentially unexpected fatal signal %d.\n",
@@ -1303,19 +1323,19 @@ EXPORT_SYMBOL(kill_pid);
1303 * These functions support sending signals using preallocated sigqueue 1323 * These functions support sending signals using preallocated sigqueue
1304 * structures. This is needed "because realtime applications cannot 1324 * structures. This is needed "because realtime applications cannot
1305 * afford to lose notifications of asynchronous events, like timer 1325 * afford to lose notifications of asynchronous events, like timer
1306 * expirations or I/O completions". In the case of Posix Timers 1326 * expirations or I/O completions". In the case of Posix Timers
1307 * we allocate the sigqueue structure from the timer_create. If this 1327 * we allocate the sigqueue structure from the timer_create. If this
1308 * allocation fails we are able to report the failure to the application 1328 * allocation fails we are able to report the failure to the application
1309 * with an EAGAIN error. 1329 * with an EAGAIN error.
1310 */ 1330 */
1311
1312struct sigqueue *sigqueue_alloc(void) 1331struct sigqueue *sigqueue_alloc(void)
1313{ 1332{
1314 struct sigqueue *q; 1333 struct sigqueue *q = __sigqueue_alloc(-1, current, GFP_KERNEL, 0);
1315 1334
1316 if ((q = __sigqueue_alloc(current, GFP_KERNEL, 0))) 1335 if (q)
1317 q->flags |= SIGQUEUE_PREALLOC; 1336 q->flags |= SIGQUEUE_PREALLOC;
1318 return(q); 1337
1338 return q;
1319} 1339}
1320 1340
1321void sigqueue_free(struct sigqueue *q) 1341void sigqueue_free(struct sigqueue *q)