summaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2021-10-20 12:44:01 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-11-25 09:49:06 +0100
commit905e8609419bdfbc5fd8c3a5f3262e13c0695a59 (patch)
treebcb6b919316d05adb83b133850962b26a6435d1d /arch/sparc
parent58484ab427f147cf0d2c1ff912294ee9e001ed2e (diff)
downloadlinux-stable-905e8609419bdfbc5fd8c3a5f3262e13c0695a59.tar.gz
linux-stable-905e8609419bdfbc5fd8c3a5f3262e13c0695a59.tar.bz2
linux-stable-905e8609419bdfbc5fd8c3a5f3262e13c0695a59.zip
signal/sparc32: Exit with a fatal signal when try_to_clear_window_buffer fails
commit c317d306d55079525c9610267fdaf3a8a6d2f08b upstream. The function try_to_clear_window_buffer is only called from rtrap_32.c. After it is called the signal pending state is retested, and signals are handled if TIF_SIGPENDING is set. This allows try_to_clear_window_buffer to call force_fatal_signal and then rely on the signal being delivered to kill the process, without any danger of returning to userspace, or otherwise using possible corrupt state on failure. The functional difference between force_fatal_sig and do_exit is that do_exit will only terminate a single thread, and will never trigger a core-dump. A multi-threaded program for which a single thread terminates unexpectedly is hard to reason about. Calling force_fatal_sig does not give userspace a chance to catch the signal, but otherwise is an ordinary fatal signal exit, and it will trigger a coredump of the offending process if core dumps are enabled. Cc: David Miller <davem@davemloft.net> Cc: sparclinux@vger.kernel.org Link: https://lkml.kernel.org/r/20211020174406.17889-15-ebiederm@xmission.com Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Cc: Thomas Backlund <tmb@iki.fi> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/kernel/windows.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/arch/sparc/kernel/windows.c b/arch/sparc/kernel/windows.c
index 69a6ba6e9293..bbbd40cc6b28 100644
--- a/arch/sparc/kernel/windows.c
+++ b/arch/sparc/kernel/windows.c
@@ -121,8 +121,10 @@ void try_to_clear_window_buffer(struct pt_regs *regs, int who)
if ((sp & 7) ||
copy_to_user((char __user *) sp, &tp->reg_window[window],
- sizeof(struct reg_window32)))
- do_exit(SIGILL);
+ sizeof(struct reg_window32))) {
+ force_fatal_sig(SIGILL);
+ return;
+ }
}
tp->w_saved = 0;
}