aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index e5f8aea78ffe..7fe874d12fae 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -10,7 +10,6 @@
10 * to allow signals to be sent reliably. 10 * to allow signals to be sent reliably.
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <linux/slab.h> 13#include <linux/slab.h>
15#include <linux/module.h> 14#include <linux/module.h>
16#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
@@ -23,12 +22,12 @@
23#include <linux/syscalls.h> 22#include <linux/syscalls.h>
24#include <linux/ptrace.h> 23#include <linux/ptrace.h>
25#include <linux/signal.h> 24#include <linux/signal.h>
26#include <linux/audit.h>
27#include <linux/capability.h> 25#include <linux/capability.h>
28#include <asm/param.h> 26#include <asm/param.h>
29#include <asm/uaccess.h> 27#include <asm/uaccess.h>
30#include <asm/unistd.h> 28#include <asm/unistd.h>
31#include <asm/siginfo.h> 29#include <asm/siginfo.h>
30#include "audit.h" /* audit_signal_info() */
32 31
33/* 32/*
34 * SLAB caches for signal bits. 33 * SLAB caches for signal bits.
@@ -584,7 +583,7 @@ static int check_kill_permission(int sig, struct siginfo *info,
584 && !capable(CAP_KILL)) 583 && !capable(CAP_KILL))
585 return error; 584 return error;
586 585
587 error = security_task_kill(t, info, sig); 586 error = security_task_kill(t, info, sig, 0);
588 if (!error) 587 if (!error)
589 audit_signal_info(sig, t); /* Let audit system see the signal */ 588 audit_signal_info(sig, t); /* Let audit system see the signal */
590 return error; 589 return error;
@@ -1107,7 +1106,7 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
1107 1106
1108/* like kill_proc_info(), but doesn't use uid/euid of "current" */ 1107/* like kill_proc_info(), but doesn't use uid/euid of "current" */
1109int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid, 1108int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
1110 uid_t uid, uid_t euid) 1109 uid_t uid, uid_t euid, u32 secid)
1111{ 1110{
1112 int ret = -EINVAL; 1111 int ret = -EINVAL;
1113 struct task_struct *p; 1112 struct task_struct *p;
@@ -1127,6 +1126,9 @@ int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
1127 ret = -EPERM; 1126 ret = -EPERM;
1128 goto out_unlock; 1127 goto out_unlock;
1129 } 1128 }
1129 ret = security_task_kill(p, info, sig, secid);
1130 if (ret)
1131 goto out_unlock;
1130 if (sig && p->sighand) { 1132 if (sig && p->sighand) {
1131 unsigned long flags; 1133 unsigned long flags;
1132 spin_lock_irqsave(&p->sighand->siglock, flags); 1134 spin_lock_irqsave(&p->sighand->siglock, flags);
@@ -1531,6 +1533,35 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why)
1531 spin_unlock_irqrestore(&sighand->siglock, flags); 1533 spin_unlock_irqrestore(&sighand->siglock, flags);
1532} 1534}
1533 1535
1536static inline int may_ptrace_stop(void)
1537{
1538 if (!likely(current->ptrace & PT_PTRACED))
1539 return 0;
1540
1541 if (unlikely(current->parent == current->real_parent &&
1542 (current->ptrace & PT_ATTACHED)))
1543 return 0;
1544
1545 if (unlikely(current->signal == current->parent->signal) &&
1546 unlikely(current->signal->flags & SIGNAL_GROUP_EXIT))
1547 return 0;
1548
1549 /*
1550 * Are we in the middle of do_coredump?
1551 * If so and our tracer is also part of the coredump stopping
1552 * is a deadlock situation, and pointless because our tracer
1553 * is dead so don't allow us to stop.
1554 * If SIGKILL was already sent before the caller unlocked
1555 * ->siglock we must see ->core_waiters != 0. Otherwise it
1556 * is safe to enter schedule().
1557 */
1558 if (unlikely(current->mm->core_waiters) &&
1559 unlikely(current->mm == current->parent->mm))
1560 return 0;
1561
1562 return 1;
1563}
1564
1534/* 1565/*
1535 * This must be called with current->sighand->siglock held. 1566 * This must be called with current->sighand->siglock held.
1536 * 1567 *
@@ -1559,11 +1590,7 @@ static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info)
1559 spin_unlock_irq(&current->sighand->siglock); 1590 spin_unlock_irq(&current->sighand->siglock);
1560 try_to_freeze(); 1591 try_to_freeze();
1561 read_lock(&tasklist_lock); 1592 read_lock(&tasklist_lock);
1562 if (likely(current->ptrace & PT_PTRACED) && 1593 if (may_ptrace_stop()) {
1563 likely(current->parent != current->real_parent ||
1564 !(current->ptrace & PT_ATTACHED)) &&
1565 (likely(current->parent->signal != current->signal) ||
1566 !unlikely(current->signal->flags & SIGNAL_GROUP_EXIT))) {
1567 do_notify_parent_cldstop(current, CLD_TRAPPED); 1594 do_notify_parent_cldstop(current, CLD_TRAPPED);
1568 read_unlock(&tasklist_lock); 1595 read_unlock(&tasklist_lock);
1569 schedule(); 1596 schedule();