diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2021-09-01 18:33:50 +0200 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2021-10-06 18:28:39 +0200 |
commit | 92307383082daff5df884a25df9e283efb7ef261 (patch) | |
tree | c73d7be83738e56a3ae161c640562563b867549e /fs/coredump.c | |
parent | exit: Factor coredump_exit_mm out of exit_mm (diff) | |
download | linux-92307383082daff5df884a25df9e283efb7ef261.tar.xz linux-92307383082daff5df884a25df9e283efb7ef261.zip |
coredump: Don't perform any cleanups before dumping core
Rename coredump_exit_mm to coredump_task_exit and call it from do_exit
before PTRACE_EVENT_EXIT, and before any cleanup work for a task
happens. This ensures that an accurate copy of the process can be
captured in the coredump as no cleanup for the process happens before
the coredump completes. This also ensures that PTRACE_EVENT_EXIT
will not be visited by any thread until the coredump is complete.
Add a new flag PF_POSTCOREDUMP so that tasks that have passed through
coredump_task_exit can be recognized and ignored in zap_process.
Now that all of the coredumping happens before exit_mm remove code to
test for a coredump in progress from mm_release.
Replace "may_ptrace_stop()" with a simple test of "current->ptrace".
The other tests in may_ptrace_stop all concern avoiding stopping
during a coredump. These tests are no longer necessary as it is now
guaranteed that fatal_signal_pending will be set if the code enters
ptrace_stop during a coredump. The code in ptrace_stop is guaranteed
not to stop if fatal_signal_pending returns true.
Until this change "ptrace_event(PTRACE_EVENT_EXIT)" could call
ptrace_stop without fatal_signal_pending being true, as signals are
dequeued in get_signal before calling do_exit. This is no longer
an issue as "ptrace_event(PTRACE_EVENT_EXIT)" is no longer reached
until after the coredump completes.
Link: https://lkml.kernel.org/r/874kaax26c.fsf@disp2133
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'fs/coredump.c')
-rw-r--r-- | fs/coredump.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/fs/coredump.c b/fs/coredump.c index 5e0e08a7fb9b..d576287fb88b 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -359,7 +359,7 @@ static int zap_process(struct task_struct *start, int exit_code, int flags) for_each_thread(start, t) { task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK); - if (t != current && t->mm) { + if (t != current && !(t->flags & PF_POSTCOREDUMP)) { sigaddset(&t->pending.signal, SIGKILL); signal_wake_up(t, 1); nr++; @@ -404,8 +404,8 @@ static int zap_threads(struct task_struct *tsk, struct mm_struct *mm, * * do_exit: * The caller holds mm->mmap_lock. This means that the task which - * uses this mm can't pass coredump_exit_mm(), so it can't exit or - * clear its ->mm. + * uses this mm can't pass coredump_task_exit(), so it can't exit + * or clear its ->mm. * * de_thread: * It does list_replace_rcu(&leader->tasks, ¤t->tasks), @@ -500,7 +500,7 @@ static void coredump_finish(struct mm_struct *mm, bool core_dumped) next = curr->next; task = curr->task; /* - * see coredump_exit_mm(), curr->task must not see + * see coredump_task_exit(), curr->task must not see * ->task == NULL before we read ->next. */ smp_mb(); |