aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-04-14 07:18:27 -0400
committerIngo Molnar <mingo@kernel.org>2012-04-14 07:19:04 -0400
commit6ac1ef482d7ae0c690f1640bf6eb818ff9a2d91e (patch)
tree021cc9f6b477146fcebe6f3be4752abfa2ba18a9 /kernel/signal.c
parent682968e0c425c60f0dde37977e5beb2b12ddc4cc (diff)
parenta385ec4f11bdcf81af094c03e2444ee9b7fad2e5 (diff)
Merge branch 'perf/core' into perf/uprobes
Merge in latest upstream (and the latest perf development tree), to prepare for tooling changes, and also to pick up v3.4 MM changes that the uprobes code needs to take care of. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index e93ff0a719a..60d80ab2601 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -37,6 +37,7 @@
37#include <asm/uaccess.h> 37#include <asm/uaccess.h>
38#include <asm/unistd.h> 38#include <asm/unistd.h>
39#include <asm/siginfo.h> 39#include <asm/siginfo.h>
40#include <asm/cacheflush.h>
40#include "audit.h" /* audit_signal_info() */ 41#include "audit.h" /* audit_signal_info() */
41 42
42/* 43/*
@@ -59,21 +60,20 @@ static int sig_handler_ignored(void __user *handler, int sig)
59 (handler == SIG_DFL && sig_kernel_ignore(sig)); 60 (handler == SIG_DFL && sig_kernel_ignore(sig));
60} 61}
61 62
62static int sig_task_ignored(struct task_struct *t, int sig, 63static int sig_task_ignored(struct task_struct *t, int sig, bool force)
63 int from_ancestor_ns)
64{ 64{
65 void __user *handler; 65 void __user *handler;
66 66
67 handler = sig_handler(t, sig); 67 handler = sig_handler(t, sig);
68 68
69 if (unlikely(t->signal->flags & SIGNAL_UNKILLABLE) && 69 if (unlikely(t->signal->flags & SIGNAL_UNKILLABLE) &&
70 handler == SIG_DFL && !from_ancestor_ns) 70 handler == SIG_DFL && !force)
71 return 1; 71 return 1;
72 72
73 return sig_handler_ignored(handler, sig); 73 return sig_handler_ignored(handler, sig);
74} 74}
75 75
76static int sig_ignored(struct task_struct *t, int sig, int from_ancestor_ns) 76static int sig_ignored(struct task_struct *t, int sig, bool force)
77{ 77{
78 /* 78 /*
79 * Blocked signals are never ignored, since the 79 * Blocked signals are never ignored, since the
@@ -83,7 +83,7 @@ static int sig_ignored(struct task_struct *t, int sig, int from_ancestor_ns)
83 if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) 83 if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig))
84 return 0; 84 return 0;
85 85
86 if (!sig_task_ignored(t, sig, from_ancestor_ns)) 86 if (!sig_task_ignored(t, sig, force))
87 return 0; 87 return 0;
88 88
89 /* 89 /*
@@ -856,7 +856,7 @@ static void ptrace_trap_notify(struct task_struct *t)
856 * Returns true if the signal should be actually delivered, otherwise 856 * Returns true if the signal should be actually delivered, otherwise
857 * it should be dropped. 857 * it should be dropped.
858 */ 858 */
859static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns) 859static int prepare_signal(int sig, struct task_struct *p, bool force)
860{ 860{
861 struct signal_struct *signal = p->signal; 861 struct signal_struct *signal = p->signal;
862 struct task_struct *t; 862 struct task_struct *t;
@@ -916,7 +916,7 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns)
916 } 916 }
917 } 917 }
918 918
919 return !sig_ignored(p, sig, from_ancestor_ns); 919 return !sig_ignored(p, sig, force);
920} 920}
921 921
922/* 922/*
@@ -1060,7 +1060,8 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
1060 assert_spin_locked(&t->sighand->siglock); 1060 assert_spin_locked(&t->sighand->siglock);
1061 1061
1062 result = TRACE_SIGNAL_IGNORED; 1062 result = TRACE_SIGNAL_IGNORED;
1063 if (!prepare_signal(sig, t, from_ancestor_ns)) 1063 if (!prepare_signal(sig, t,
1064 from_ancestor_ns || (info == SEND_SIG_FORCED)))
1064 goto ret; 1065 goto ret;
1065 1066
1066 pending = group ? &t->signal->shared_pending : &t->pending; 1067 pending = group ? &t->signal->shared_pending : &t->pending;
@@ -1602,7 +1603,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
1602 1603
1603 ret = 1; /* the signal is ignored */ 1604 ret = 1; /* the signal is ignored */
1604 result = TRACE_SIGNAL_IGNORED; 1605 result = TRACE_SIGNAL_IGNORED;
1605 if (!prepare_signal(sig, t, 0)) 1606 if (!prepare_signal(sig, t, false))
1606 goto out; 1607 goto out;
1607 1608
1608 ret = 0; 1609 ret = 0;
@@ -1653,6 +1654,15 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
1653 BUG_ON(!tsk->ptrace && 1654 BUG_ON(!tsk->ptrace &&
1654 (tsk->group_leader != tsk || !thread_group_empty(tsk))); 1655 (tsk->group_leader != tsk || !thread_group_empty(tsk)));
1655 1656
1657 if (sig != SIGCHLD) {
1658 /*
1659 * This is only possible if parent == real_parent.
1660 * Check if it has changed security domain.
1661 */
1662 if (tsk->parent_exec_id != tsk->parent->self_exec_id)
1663 sig = SIGCHLD;
1664 }
1665
1656 info.si_signo = sig; 1666 info.si_signo = sig;
1657 info.si_errno = 0; 1667 info.si_errno = 0;
1658 /* 1668 /*