Hi Andreas,
On 23/04/23 20:23, Andreas Schwab wrote:
On Apr 23 2023, Michael Schmitz wrote:
Wasn't too hard actually. The signo parameter passed to the handler turns
out to be passed by reference, and signo is located 4 bytes into the
kernel sigframe.
That's not "passed by reference". Function arguments are always passed
on the stack.
You're right of course, I should have phrased that different.
signo is passed by value as the first argument on the stack, but I can
take a reference to signo to find it's address on the stack. That in
turn will tell me the address of the complete signal frame on the stack.
This works because at the time the handler is entered, the stack points
to the return address which has been set up by setup_frame, and that's
the first longword in struct sigframe (frame.pretcode; points to
frame.retcode which holds the trampoline code that will call
sys_sigreturn upon exit from the handler). This in turn works because
usp is loaded with the address of the sigframe right before calling the
handler.
In effect, at least indirectly the signal handler receives all two
arguments that matter (signo and sigcontext) even though sigcontext is
not explicitly passed on the stack (the third longword is frame.code
which holds the vector number AFAICS). Not sure what third argument you
referred to in another mail.
With the rt_sigframe, pointers to siginfo and ucontext are stored after
signo so no stack arithmetics is needed there to access all three
arguments.
Anyway, the whole point of the exercise was to see whether I can peek at
the registers in the signal frame and their saved copies on the stack,
to perhaps spot when the stack corruption begins to happen. I know -
should have used a debugger in the first place instead instrumenting a
test case.
Cheers,
Michael