diff --git a/fs/exec.c b/fs/exec.c index c7397c46ad6d174b7af1b04725bd59d904a4cf81..d0ecea0781f7d0f275e173694a94912d65fa223f 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -660,12 +660,23 @@ static int de_thread(struct task_struct *tsk) struct dentry *proc_dentry1, *proc_dentry2; unsigned long ptrace; + leader = current->group_leader; + /* + * If our leader is the child_reaper become + * the child_reaper and resend SIGKILL signal. + */ + if (unlikely(leader == child_reaper)) { + write_lock(&tasklist_lock); + child_reaper = current; + zap_other_threads(current); + write_unlock(&tasklist_lock); + } + /* * Wait for the thread group leader to be a zombie. * It should already be zombie at this point, most * of the time. */ - leader = current->group_leader; while (leader->exit_state != EXIT_ZOMBIE) yield(); diff --git a/kernel/exit.c b/kernel/exit.c index a8c7efc7a681a99220711517b200de81e02eba41..223a8802b665e8f04b8f3174c1634a48923b3403 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -807,7 +807,7 @@ fastcall NORET_TYPE void do_exit(long code) panic("Aiee, killing interrupt handler!"); if (unlikely(!tsk->pid)) panic("Attempted to kill the idle task!"); - if (unlikely(tsk->pid == 1)) + if (unlikely(tsk == child_reaper)) panic("Attempted to kill init!"); if (unlikely(current->ptrace & PT_TRACE_EXIT)) { diff --git a/kernel/signal.c b/kernel/signal.c index 75f7341b0c397275ccd35b8ff29798a5a3d8af4b..dc8f91bf9f8970d00eeb73d9a4c49082fe7b8d91 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1990,7 +1990,7 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, continue; /* Init gets no signals it doesn't want. */ - if (current->pid == 1) + if (current == child_reaper) continue; if (sig_kernel_stop(signr)) {