| From 3ac1b9aac35d5d7ac5ff13ba64284f89357eda1a Mon Sep 17 00:00:00 2001 |
| From: chenqiwu <chenqiwu@xiaomi.com> |
| Date: Thu, 19 Dec 2019 14:29:53 +0800 |
| Subject: [PATCH] exit: panic before exit_mm() on global init exit |
| |
| commit 43cf75d96409a20ef06b756877a2e72b10a026fc upstream. |
| |
| 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> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/kernel/exit.c b/kernel/exit.c |
| index a75b6a7f458a..abf635f004e5 100644 |
| --- a/kernel/exit.c |
| +++ b/kernel/exit.c |
| @@ -579,10 +579,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); |
| @@ -846,6 +842,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); |
| -- |
| 2.7.4 |
| |