Re: signal delivery, was Re: reliable reproducer

Finn Thain
2023-04-25T01:51:42Z

On Tue, 25 Apr 2023, Finn Thain wrote:

> On Tue, 25 Apr 2023, Michael Schmitz wrote:
>
> > As to a cause for the corruption: all the calculations in setup_frame
> > and sys_sigreturn use fsize, but get_sigframe() masks off the result
> > of usp - sizeof(sigframe) - fsize to place the entire frame at a
> > quadword boundary.
> ...
>
> I wonder if we are seeing some fallout from the issue described in
> do_page_fault() i.e. usp is unreliable.
>
> /* Accessing the stack below usp is always a bug. The
> "+ 256" is there due to some instructions doing
> pre-decrement on the stack and that doesn't show up
> until later. */
> if (address + 256 < rdusp())
> goto map_err;
>
> Maybe we should try modifying get_sigframe() to increase the gap between
> the signal and exception frames from 0-1 long words up to 64-65 long
> words.
>

It turns out that doing so (patch below) does make the problem go away.
Was the exception frame getting clobbered?

diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index b9f6908a31bc..94104699f5a8 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -862,7 +862,7 @@ get_sigframe(struct ksignal *ksig, size_t frame_size)
{
unsigned long usp = sigsp(rdusp(), ksig);

- return (void __user *)((usp - frame_size) & -8UL);
+ return (void __user *)((usp - 256 - frame_size) & -8UL);
}

static int setup_frame(struct ksignal *ksig, sigset_t *set,