diff options
author | chenqiwu <chenqiwu@xiaomi.com> | 2019-12-19 07:29:53 +0100 |
---|---|---|
committer | Christian Brauner <christian.brauner@ubuntu.com> | 2019-12-21 16:48:01 +0100 |
commit | 43cf75d96409a20ef06b756877a2e72b10a026fc (patch) | |
tree | e4ee7ca8f43d13a2ba8348a314ec23883b8b9a70 /kernel/exit.c | |
parent | taskstats: fix data-race (diff) | |
download | linux-43cf75d96409a20ef06b756877a2e72b10a026fc.tar.xz linux-43cf75d96409a20ef06b756877a2e72b10a026fc.zip |
exit: panic before exit_mm() on global init exit
Currently, when global init and all threads in its thread-group have exited
we panic via:
do_exit()
-> exit_notify()
-> forget_original_parent()
-> find_child_reaper()
This makes it hard to extract a useable coredump for global init from a
kernel crashdump because by the time we panic exit_mm() will have already
released global init's mm.
This patch moves the panic futher up before exit_mm() is called. As was the
case previously, we only panic when global init and all its threads in the
thread-group have exited.
Signed-off-by: chenqiwu <chenqiwu@xiaomi.com>
Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
Acked-by: Oleg Nesterov <oleg@redhat.com>
[christian.brauner@ubuntu.com: fix typo, rewrite commit message]
Link: https://lore.kernel.org/r/1576736993-10121-1-git-send-email-qiwuchen55@gmail.com
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index a46a50d67002..fc364272759d 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -517,10 +517,6 @@ static struct task_struct *find_child_reaper(struct task_struct *father, } write_unlock_irq(&tasklist_lock); - if (unlikely(pid_ns == &init_pid_ns)) { - panic("Attempted to kill init! exitcode=0x%08x\n", - father->signal->group_exit_code ?: father->exit_code); - } list_for_each_entry_safe(p, n, dead, ptrace_entry) { list_del_init(&p->ptrace_entry); @@ -786,6 +782,14 @@ void __noreturn do_exit(long code) acct_update_integrals(tsk); group_dead = atomic_dec_and_test(&tsk->signal->live); if (group_dead) { + /* + * If the last thread of global init has exited, panic + * immediately to get a useable coredump. + */ + if (unlikely(is_global_init(tsk))) + panic("Attempted to kill init! exitcode=0x%08x\n", + tsk->signal->group_exit_code ?: (int)code); + #ifdef CONFIG_POSIX_TIMERS hrtimer_cancel(&tsk->signal->real_timer); exit_itimers(tsk->signal); |