diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 94 |
1 files changed, 67 insertions, 27 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index d8034737db4c..ccf1ceedaebe 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/freezer.h> | 27 | #include <linux/freezer.h> |
28 | #include <linux/pid_namespace.h> | 28 | #include <linux/pid_namespace.h> |
29 | #include <linux/nsproxy.h> | 29 | #include <linux/nsproxy.h> |
30 | #include <trace/sched.h> | 30 | #include <trace/events/sched.h> |
31 | 31 | ||
32 | #include <asm/param.h> | 32 | #include <asm/param.h> |
33 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
@@ -41,8 +41,6 @@ | |||
41 | 41 | ||
42 | static struct kmem_cache *sigqueue_cachep; | 42 | static struct kmem_cache *sigqueue_cachep; |
43 | 43 | ||
44 | DEFINE_TRACE(sched_signal_send); | ||
45 | |||
46 | static void __user *sig_handler(struct task_struct *t, int sig) | 44 | static void __user *sig_handler(struct task_struct *t, int sig) |
47 | { | 45 | { |
48 | return t->sighand->action[sig - 1].sa.sa_handler; | 46 | return t->sighand->action[sig - 1].sa.sa_handler; |
@@ -249,14 +247,19 @@ void flush_sigqueue(struct sigpending *queue) | |||
249 | /* | 247 | /* |
250 | * Flush all pending signals for a task. | 248 | * Flush all pending signals for a task. |
251 | */ | 249 | */ |
250 | void __flush_signals(struct task_struct *t) | ||
251 | { | ||
252 | clear_tsk_thread_flag(t, TIF_SIGPENDING); | ||
253 | flush_sigqueue(&t->pending); | ||
254 | flush_sigqueue(&t->signal->shared_pending); | ||
255 | } | ||
256 | |||
252 | void flush_signals(struct task_struct *t) | 257 | void flush_signals(struct task_struct *t) |
253 | { | 258 | { |
254 | unsigned long flags; | 259 | unsigned long flags; |
255 | 260 | ||
256 | spin_lock_irqsave(&t->sighand->siglock, flags); | 261 | spin_lock_irqsave(&t->sighand->siglock, flags); |
257 | clear_tsk_thread_flag(t, TIF_SIGPENDING); | 262 | __flush_signals(t); |
258 | flush_sigqueue(&t->pending); | ||
259 | flush_sigqueue(&t->signal->shared_pending); | ||
260 | spin_unlock_irqrestore(&t->sighand->siglock, flags); | 263 | spin_unlock_irqrestore(&t->sighand->siglock, flags); |
261 | } | 264 | } |
262 | 265 | ||
@@ -829,6 +832,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
829 | { | 832 | { |
830 | struct sigpending *pending; | 833 | struct sigpending *pending; |
831 | struct sigqueue *q; | 834 | struct sigqueue *q; |
835 | int override_rlimit; | ||
832 | 836 | ||
833 | trace_sched_signal_send(sig, t); | 837 | trace_sched_signal_send(sig, t); |
834 | 838 | ||
@@ -860,9 +864,13 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
860 | make sure at least one signal gets delivered and don't | 864 | make sure at least one signal gets delivered and don't |
861 | pass on the info struct. */ | 865 | pass on the info struct. */ |
862 | 866 | ||
863 | q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN && | 867 | if (sig < SIGRTMIN) |
864 | (is_si_special(info) || | 868 | override_rlimit = (is_si_special(info) || info->si_code >= 0); |
865 | info->si_code >= 0))); | 869 | else |
870 | override_rlimit = 0; | ||
871 | |||
872 | q = __sigqueue_alloc(t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE, | ||
873 | override_rlimit); | ||
866 | if (q) { | 874 | if (q) { |
867 | list_add_tail(&q->list, &pending->list); | 875 | list_add_tail(&q->list, &pending->list); |
868 | switch ((unsigned long) info) { | 876 | switch ((unsigned long) info) { |
@@ -1402,7 +1410,7 @@ int do_notify_parent(struct task_struct *tsk, int sig) | |||
1402 | /* do_notify_parent_cldstop should have been called instead. */ | 1410 | /* do_notify_parent_cldstop should have been called instead. */ |
1403 | BUG_ON(task_is_stopped_or_traced(tsk)); | 1411 | BUG_ON(task_is_stopped_or_traced(tsk)); |
1404 | 1412 | ||
1405 | BUG_ON(!tsk->ptrace && | 1413 | BUG_ON(!task_ptrace(tsk) && |
1406 | (tsk->group_leader != tsk || !thread_group_empty(tsk))); | 1414 | (tsk->group_leader != tsk || !thread_group_empty(tsk))); |
1407 | 1415 | ||
1408 | info.si_signo = sig; | 1416 | info.si_signo = sig; |
@@ -1441,7 +1449,7 @@ int do_notify_parent(struct task_struct *tsk, int sig) | |||
1441 | 1449 | ||
1442 | psig = tsk->parent->sighand; | 1450 | psig = tsk->parent->sighand; |
1443 | spin_lock_irqsave(&psig->siglock, flags); | 1451 | spin_lock_irqsave(&psig->siglock, flags); |
1444 | if (!tsk->ptrace && sig == SIGCHLD && | 1452 | if (!task_ptrace(tsk) && sig == SIGCHLD && |
1445 | (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN || | 1453 | (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN || |
1446 | (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) { | 1454 | (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) { |
1447 | /* | 1455 | /* |
@@ -1478,7 +1486,7 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why) | |||
1478 | struct task_struct *parent; | 1486 | struct task_struct *parent; |
1479 | struct sighand_struct *sighand; | 1487 | struct sighand_struct *sighand; |
1480 | 1488 | ||
1481 | if (tsk->ptrace & PT_PTRACED) | 1489 | if (task_ptrace(tsk)) |
1482 | parent = tsk->parent; | 1490 | parent = tsk->parent; |
1483 | else { | 1491 | else { |
1484 | tsk = tsk->group_leader; | 1492 | tsk = tsk->group_leader; |
@@ -1491,7 +1499,7 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why) | |||
1491 | * see comment in do_notify_parent() abot the following 3 lines | 1499 | * see comment in do_notify_parent() abot the following 3 lines |
1492 | */ | 1500 | */ |
1493 | rcu_read_lock(); | 1501 | rcu_read_lock(); |
1494 | info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns); | 1502 | info.si_pid = task_pid_nr_ns(tsk, parent->nsproxy->pid_ns); |
1495 | info.si_uid = __task_cred(tsk)->uid; | 1503 | info.si_uid = __task_cred(tsk)->uid; |
1496 | rcu_read_unlock(); | 1504 | rcu_read_unlock(); |
1497 | 1505 | ||
@@ -1527,7 +1535,7 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why) | |||
1527 | 1535 | ||
1528 | static inline int may_ptrace_stop(void) | 1536 | static inline int may_ptrace_stop(void) |
1529 | { | 1537 | { |
1530 | if (!likely(current->ptrace & PT_PTRACED)) | 1538 | if (!likely(task_ptrace(current))) |
1531 | return 0; | 1539 | return 0; |
1532 | /* | 1540 | /* |
1533 | * Are we in the middle of do_coredump? | 1541 | * Are we in the middle of do_coredump? |
@@ -1745,7 +1753,7 @@ static int do_signal_stop(int signr) | |||
1745 | static int ptrace_signal(int signr, siginfo_t *info, | 1753 | static int ptrace_signal(int signr, siginfo_t *info, |
1746 | struct pt_regs *regs, void *cookie) | 1754 | struct pt_regs *regs, void *cookie) |
1747 | { | 1755 | { |
1748 | if (!(current->ptrace & PT_PTRACED)) | 1756 | if (!task_ptrace(current)) |
1749 | return signr; | 1757 | return signr; |
1750 | 1758 | ||
1751 | ptrace_signal_deliver(regs, cookie); | 1759 | ptrace_signal_deliver(regs, cookie); |
@@ -2278,24 +2286,17 @@ SYSCALL_DEFINE2(kill, pid_t, pid, int, sig) | |||
2278 | return kill_something_info(sig, &info, pid); | 2286 | return kill_something_info(sig, &info, pid); |
2279 | } | 2287 | } |
2280 | 2288 | ||
2281 | static int do_tkill(pid_t tgid, pid_t pid, int sig) | 2289 | static int |
2290 | do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info) | ||
2282 | { | 2291 | { |
2283 | int error; | ||
2284 | struct siginfo info; | ||
2285 | struct task_struct *p; | 2292 | struct task_struct *p; |
2286 | unsigned long flags; | 2293 | unsigned long flags; |
2287 | 2294 | int error = -ESRCH; | |
2288 | error = -ESRCH; | ||
2289 | info.si_signo = sig; | ||
2290 | info.si_errno = 0; | ||
2291 | info.si_code = SI_TKILL; | ||
2292 | info.si_pid = task_tgid_vnr(current); | ||
2293 | info.si_uid = current_uid(); | ||
2294 | 2295 | ||
2295 | rcu_read_lock(); | 2296 | rcu_read_lock(); |
2296 | p = find_task_by_vpid(pid); | 2297 | p = find_task_by_vpid(pid); |
2297 | if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid)) { | 2298 | if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid)) { |
2298 | error = check_kill_permission(sig, &info, p); | 2299 | error = check_kill_permission(sig, info, p); |
2299 | /* | 2300 | /* |
2300 | * The null signal is a permissions and process existence | 2301 | * The null signal is a permissions and process existence |
2301 | * probe. No signal is actually delivered. | 2302 | * probe. No signal is actually delivered. |
@@ -2305,7 +2306,7 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig) | |||
2305 | * signal is private anyway. | 2306 | * signal is private anyway. |
2306 | */ | 2307 | */ |
2307 | if (!error && sig && lock_task_sighand(p, &flags)) { | 2308 | if (!error && sig && lock_task_sighand(p, &flags)) { |
2308 | error = specific_send_sig_info(sig, &info, p); | 2309 | error = specific_send_sig_info(sig, info, p); |
2309 | unlock_task_sighand(p, &flags); | 2310 | unlock_task_sighand(p, &flags); |
2310 | } | 2311 | } |
2311 | } | 2312 | } |
@@ -2314,6 +2315,19 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig) | |||
2314 | return error; | 2315 | return error; |
2315 | } | 2316 | } |
2316 | 2317 | ||
2318 | static int do_tkill(pid_t tgid, pid_t pid, int sig) | ||
2319 | { | ||
2320 | struct siginfo info; | ||
2321 | |||
2322 | info.si_signo = sig; | ||
2323 | info.si_errno = 0; | ||
2324 | info.si_code = SI_TKILL; | ||
2325 | info.si_pid = task_tgid_vnr(current); | ||
2326 | info.si_uid = current_uid(); | ||
2327 | |||
2328 | return do_send_specific(tgid, pid, sig, &info); | ||
2329 | } | ||
2330 | |||
2317 | /** | 2331 | /** |
2318 | * sys_tgkill - send signal to one specific thread | 2332 | * sys_tgkill - send signal to one specific thread |
2319 | * @tgid: the thread group ID of the thread | 2333 | * @tgid: the thread group ID of the thread |
@@ -2363,6 +2377,32 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig, | |||
2363 | return kill_proc_info(sig, &info, pid); | 2377 | return kill_proc_info(sig, &info, pid); |
2364 | } | 2378 | } |
2365 | 2379 | ||
2380 | long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info) | ||
2381 | { | ||
2382 | /* This is only valid for single tasks */ | ||
2383 | if (pid <= 0 || tgid <= 0) | ||
2384 | return -EINVAL; | ||
2385 | |||
2386 | /* Not even root can pretend to send signals from the kernel. | ||
2387 | Nor can they impersonate a kill(), which adds source info. */ | ||
2388 | if (info->si_code >= 0) | ||
2389 | return -EPERM; | ||
2390 | info->si_signo = sig; | ||
2391 | |||
2392 | return do_send_specific(tgid, pid, sig, info); | ||
2393 | } | ||
2394 | |||
2395 | SYSCALL_DEFINE4(rt_tgsigqueueinfo, pid_t, tgid, pid_t, pid, int, sig, | ||
2396 | siginfo_t __user *, uinfo) | ||
2397 | { | ||
2398 | siginfo_t info; | ||
2399 | |||
2400 | if (copy_from_user(&info, uinfo, sizeof(siginfo_t))) | ||
2401 | return -EFAULT; | ||
2402 | |||
2403 | return do_rt_tgsigqueueinfo(tgid, pid, sig, &info); | ||
2404 | } | ||
2405 | |||
2366 | int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) | 2406 | int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) |
2367 | { | 2407 | { |
2368 | struct task_struct *t = current; | 2408 | struct task_struct *t = current; |