Re: reliable reproducer, was Re: core dump analysis

Michael Schmitz
2023-04-23T08:18:26Z

Hi Finn, Andreas,

Am 23.04.2023 um 13:41 schrieb Michael Schmitz:
> Hi Andreas,
>
> Am 23.04.2023 um 08:46 schrieb Andreas Schwab:
>> On Apr 23 2023, Michael Schmitz wrote:
>>
>>> I'll see whether the signal context is available on the stack even if
>>> the
>>> handler isn't passed that parameter.
>>
>> The signal context is always on the stack, and used by the
>> (rt_)sigreturn syscall.
>
> True, but at the time the signal handler (sa_handler type) runs, all I
> have is the user stack pointer upon entry to the handler. I'll have to
> calculate back from that address, if that is possible.

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. The address of the sigcontext struct follows from
that.

Result for the original test code that Finn posted (using sa_handler):

parent usp : 0xefa2f010
handler tos : 0xefa2efa0
frame end : 0xefa2efb4
frame start : 0xefa2ee78
handler usp : 0xefa2ee60
signal usp : 0xefa2f004
signal pc : 0x80000588
signal fmtv : 0xb008
parent usp : 0xef957ed4
handler tos : 0xef957eb0
frame end : 0xef957ec4
frame start : 0xef957d88
handler usp : 0xef957d70
signal usp : 0xef957ec4
signal pc : 0xc009f37a
signal fmtv : 0x80
parent usp : 0xef957ed4
handler tos : 0xef957eb0
frame end : 0xef957ec4
frame start : 0xef957d88
handler usp : 0xef957d70
signal usp : 0xef957ec4
signal pc : 0xc009f37a
signal fmtv : 0x80
parent usp : 0xef945ed4
handler tos : 0xef945eb0
frame end : 0xef945ec4
frame start : 0xef945d88
handler usp : 0xef945d70
signal usp : 0xef945ec4
signal pc : 0xc009f37a
signal fmtv : 0x80
parent usp : 0xef921ef8
handler tos : 0xef9b0f88
handler stack overwrote usp!
frame end : 0xef9b0f9c
frame start : 0xef9b0e60
handler usp : 0xef9b0e48
signal usp : 0xef9b0fec
signal pc : 0x8000067e
signal fmtv : 0xb008
Illegal instruction (core dumped)

In this case, only on the last recursion before the core dump does the
handler warn that the end of the kernel sigframe (shown as frame end)
lies above the current stack pointer from the main program.

That nicely explains the overwriting of the saved register a3 (which did
point to the stack canary) and subsequent stack corruption abort.

Though the question remains - is this expected behaviour for programs
that do deep recursion on the stack while taking signals (and the reason
for the option to run signal handlers on an alternate stack)?

And why does this almost always appear to happen after bus error
exceptions (frame format b)? The extra exception stack information isn't
even accounted for in the above frame end address!

Result with sa_sigaction handler:

parent usp : 0xef969e28
handler tos : 0xef969e6c
handler stack overwrote usp!
frame end : 0xef969e7c
frame start : 0xef969b58
handler usp : 0xef969b40
signal usp : 0xef969e04
signal pc : 0x80000696
signal fmtv : 0x114

parent usp : 0xef955008
handler tos : 0xef955064
handler stack overwrote usp!
frame end : 0xef955074
frame start : 0xef954d50
handler usp : 0xef954d38
signal usp : 0xef954ffc
signal pc : 0x80000680
signal fmtv : 0xb008

parent usp : 0xef945eb8
handler tos : 0xef945f0c
handler stack overwrote usp!
frame end : 0xef945f1c
frame start : 0xef945bf8
handler usp : 0xef945be0
signal usp : 0xef945ea8
signal pc : 0xc009f37a
signal fmtv : 0x80

parent usp : 0xef933eb8
handler tos : 0xef933f0c
handler stack overwrote usp!
frame end : 0xef933f1c
frame start : 0xef933bf8
handler usp : 0xef933be0
signal usp : 0xef933ea8
signal pc : 0xc009f37a
signal fmtv : 0x80

parent usp : 0xef921edc
handler tos : 0xef9aaca4
handler stack overwrote usp!
frame end : 0xef9aacb4
frame start : 0xef9aa990
handler usp : 0xef9aa978
signal usp : 0xef9aac40
signal pc : 0x80000782
signal fmtv : 0x114

Illegal instruction (core dumped)

Exception right before crash was an interrupt in this case (only seen
that once in this context, though I've seen lots of those in the course
of the test runs). Frame start calculated from siginfo pointer value in
this case.

I'll clean up the test code and combine all signal use cases into a
single source file so Stan and Finn can give this a spin on their hardware.

Cheers,

Michael