aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
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 e93ff0a719a0..60d80ab2601c 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 /*