diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2021-09-03 18:26:05 +0300 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2021-10-06 19:27:55 +0300 |
commit | 7e3c4fb7fc19bcf20657de3edb718ec1b26c7df3 (patch) | |
tree | 4105e71b67facde85813e97980122b6df56f0b34 /fs/exec.c | |
parent | 4f627af8e6068892cafe031df6c14e8a0aaaa426 (diff) | |
download | linux-7e3c4fb7fc19bcf20657de3edb718ec1b26c7df3.tar.xz |
exec: Check for a pending fatal signal instead of core_state
Prevent exec continuing when a fatal signal is pending by replacing
mmap_read_lock with mmap_read_lock_killable. This is always the right
thing to do as userspace will never observe an exec complete when
there is a fatal signal pending.
With that change it becomes unnecessary to explicitly test for a core
dump in progress. In coredump_wait zap_threads arranges under
mmap_write_lock for all tasks that use a mm to also have SIGKILL
pending, which means mmap_read_lock_killable will always return -EINTR
when old_mm->core_state is present.
Link: https://lkml.kernel.org/r/87fstux27w.fsf@disp2133
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/fs/exec.c b/fs/exec.c index a098c133d8d7..b6079f1a098e 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -987,16 +987,14 @@ static int exec_mmap(struct mm_struct *mm) if (old_mm) { /* - * Make sure that if there is a core dump in progress - * for the old mm, we get out and die instead of going - * through with the exec. We must hold mmap_lock around - * checking core_state and changing tsk->mm. + * If there is a pending fatal signal perhaps a signal + * whose default action is to create a coredump get + * out and die instead of going through with the exec. */ - mmap_read_lock(old_mm); - if (unlikely(old_mm->core_state)) { - mmap_read_unlock(old_mm); + ret = mmap_read_lock_killable(old_mm); + if (ret) { up_write(&tsk->signal->exec_update_lock); - return -EINTR; + return ret; } } |