summaryrefslogtreecommitdiffstats
path: root/kernel/exit.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/exit.c')
-rw-r--r--kernel/exit.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 39103a683..2ca64035c 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -135,7 +135,9 @@ static inline void forget_original_parent(struct task_struct * father)
read_lock(&tasklist_lock);
for_each_task(p) {
if (p->p_opptr == father) {
+ /* We dont want people slaying init */
p->exit_signal = SIGCHLD;
+ p->self_exec_id++;
p->p_opptr = child_reaper; /* init */
if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0);
}
@@ -288,7 +290,7 @@ void exit_mm(struct task_struct *tsk)
*/
static void exit_notify(void)
{
- struct task_struct * p;
+ struct task_struct * p, *t;
forget_original_parent(current);
/*
@@ -300,15 +302,39 @@ static void exit_notify(void)
* and we were the only connection outside, so our pgrp
* is about to become orphaned.
*/
- if ((current->p_pptr->pgrp != current->pgrp) &&
- (current->p_pptr->session == current->session) &&
+
+ t = current->p_pptr;
+
+ if ((t->pgrp != current->pgrp) &&
+ (t->session == current->session) &&
will_become_orphaned_pgrp(current->pgrp, current) &&
has_stopped_jobs(current->pgrp)) {
kill_pg(current->pgrp,SIGHUP,1);
kill_pg(current->pgrp,SIGCONT,1);
}
- /* Let father know we died */
+ /* Let father know we died
+ *
+ * Thread signals are configurable, but you aren't going to use
+ * that to send signals to arbitary processes.
+ * That stops right now.
+ *
+ * If the parent exec id doesn't match the exec id we saved
+ * when we started then we know the parent has changed security
+ * domain.
+ *
+ * If our self_exec id doesn't match our parent_exec_id then
+ * we have changed execution domain as these two values started
+ * the same after a fork.
+ *
+ */
+
+ if(current->exit_signal != SIGCHLD &&
+ ( current->parent_exec_id != t->self_exec_id ||
+ current->self_exec_id != current->parent_exec_id)
+ && !capable(CAP_KILL))
+ current->exit_signal = SIGCHLD;
+
notify_parent(current, current->exit_signal);
/*