[PATCH 5.15 260/279] signal/sparc32: Exit with a fatal signal when try_to_clear_window_buffer fails

From: Greg Kroah-Hartman
Date: Wed Nov 24 2021 - 09:07:48 EST


From: Eric W. Biederman <ebiederm@xxxxxxxxxxxx>

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@xxxxxxxxxxxxx>
Cc: sparclinux@xxxxxxxxxxxxxxx
Link: https://lkml.kernel.org/r/20211020174406.17889-15-ebiederm@xxxxxxxxxxxx
Signed-off-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx>
Cc: Thomas Backlund <tmb@xxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
arch/sparc/kernel/windows.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

--- a/arch/sparc/kernel/windows.c
+++ b/arch/sparc/kernel/windows.c
@@ -121,8 +121,10 @@ void try_to_clear_window_buffer(struct p

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;
}