ChakraCore: Incompatibility in handling of SIGSEGV between ChakraCore and CoreCLR
I discovered an incompatibility in handling of the segmentation fault signal between the ChakraCore engine and CoreCLR. The issue IMO impacts all recent ChakraCore versions. It is triggered by a segmentation fault in user code (e.g. any NullReferenceException
) in a CoreCLR-driven process and manifests itself as a stack overflow / stack smashing that crashes the process.
The following occurs after the ChakraCore engine is loaded into a CoreCLR process when a segmentation fault is triggered:
Process is terminating due to StackOverflowException.
Aborted (core dumped)
The core dump contains the following stack:
frame #0: 0x00007ff9a96d7fff libc.so.6`gsignal + 207
frame #1: 0xfffffffe7fffffff
frame #2: 0x00007ff9a979e1f7 libc.so.6`__fortify_fail + 55
frame #3: 0x00007ff9a979e1c0 libc.so.6`__stack_chk_fail + 16
frame #4: 0x00007ff44c0e94a2 libChakraCore.so`sigsegv_handler(int, siginfo_t*, void*) + 171
When debugging the crash in lldb we can see a more informative stack:
* thread #1, name = 'dotnet', stop reason = signal SIGABRT
* frame #0: libc.so.6`__GI_raise(sig=2) at raise.c:51
frame #1: libc.so.6`__GI_abort at abort.c:79
frame #2: 0x00007f7616872e73 libcoreclr.so`PROCAbort + 19
frame #3: 0x00007f761683c262 libcoreclr.so`sigsegv_handler(int, siginfo_t*, void*) + 338
frame #4: 0x00007f760df08187 libclrjit.so`sigsegv_handler(int, siginfo_t*, void*) + 247
frame #5: 0x00007f757571146b libChakraCore.so`sigsegv_handler(int, siginfo_t*, void*) + 171
According to my investigation, the stack overflow is only virtual. CoreCLR registers its SIGSEGV handler with the the SA_ONSTACK
flag that instruct the kernel to execute the handler on a separate stack. On the other hand, ChakraCore registers its handler without the flag. The discrepancy is IMO the reason why the CoreCLR SO detection malfunctions and aborts the process. It seems that the SO detector cannot deal with the fact that the SIGSEGV handler is not executing on the separate stack CoreCLR prepared during PAL initialization.
A small repro project can be downloaded here. Crashes consistently on Ubuntu 18.04.
Once I patched the registration of the SIGSEGV handler in ChakraCore (to align it with the CoreCLR version) the crash was gone:
73c73
< static void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction);
---
> static void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction, int additionalFlags = 0);
120c120
< handle_signal(SIGSEGV, sigsegv_handler, &g_previous_sigsegv);
---
> handle_signal(SIGSEGV, sigsegv_handler, &g_previous_sigsegv, SA_ONSTACK);
579c579
< void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction)
---
> void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction, int additionalFlags)
583c583
< newAction.sa_flags = SA_RESTART;
---
> newAction.sa_flags = SA_RESTART | additionalFlags;
591a592,598
>
> #ifdef INJECT_ACTIVATION_SIGNAL
> if ((additionalFlags & SA_ONSTACK) != 0)
> {
> sigaddset(&newAction.sa_mask, INJECT_ACTIVATION_SIGNAL);
> }
> #endif
I don’t know whether the issue lies within the CoreCLR SO detector or ChakraCore. Either the handler registration has to be reconciled or the SO detector has to account for the fact that an incompatible SIGSEGV handler may be registered later in the process.
The issue has been previously reported as #4893 and #5781. There may be also another incompatibility between ChakraCore and CoreCLR that prevents analysis of managed core dumps (maybe the ChakraCore PAL is an incompatible copy-paste from CoreCLR?).
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 6
- Comments: 21 (10 by maintainers)
Commits related to this issue
- Attempt to avoid 'stack smashing detected' crash In a deployment today, I observed an instance of the web host crashing. Docker logs revealed an error message 'stack smashing detected'. Discussion on... — committed to pine-vm/pine by deleted user 5 years ago
- Attempt to avoid 'stack smashing detected' crash In a deployment today, I observed an instance of the web host crashing. Docker logs revealed an error message 'stack smashing detected'. Discussion on... — committed to pine-vm/pine by deleted user 5 years ago
- Avoid the 'stack smashing detected' crash on Ubuntu environments 🐛🧹 Try to avoid the 'stack smashing detected' crash seen on some Ubuntu environments: Integrate JS engine version with improvement i... — committed to pine-vm/pine by Viir 4 years ago
For another thought - in the master branch of CC we could try updating signal.cpp to the latest version from the CoreCLR and seeing if that solves this issue, our current version (from the CORECLR of about 4 years ago is vastly different to the latest) - in general it may be worth updating a lot of the PAL files to newer versions.
EDIT: in the alternative/or additionally we could explore deleting/removing a lot of this code; I’m unsure if ChakraCore internally needs this signal handling, not sure if someone else could weigh in on that? For reference:
@divmain @rhuanjl I know a lot of people who, due to this error, cannot use the ChakraCore library in .NET Core applications on Linux. Yesterday, Nikita Tsukanov (@kekekeks) suggested that I build a native assemblies with the Tomáš Deml’s patch applied, source code of which is contained in this discussion, and test it. For testing, I used my test suite, which I ran on 64-bit versions of Windows 10, Ubuntu 16.04.1 and macOS 10.12. All tests worked correctly, and most importantly, periodically occurring errors on Ubuntu completely disappeared. Therefore, I included these assemblies in the JavaScript Engine Switcher version 3.4.5. I suggest adding the Tomáš Deml’s patch along with security patches to the next release of ChakraCore v1.11.
@tomasdeml, I think it makes sense to submit your patch as PR.
I checked my recommendation myself. Unfortunately, this problem is relevant for the ChakraCore version 1.11.6.
It would be nice.
For now, I will continue to release new versions of the JavaScript Engine Switcher with this patch, because only .NET developers use it.
This sounds like it could do with more investigation by someone a bit more familiar with PAL and CLR. The PAL within ChakraCore is a very old copy&paste from CoreCLR that has then been occasionally edited by the ChakraCore team.
I’m not really familiar with Core CLR - we could certainly add an API to a future version of ChakraCore if that’s what’s needed BUT I’d say there’s 0 chance of getting that into a 1.11 patch - would there alternatively be a way that ChakraCore could detect if it’s being used with .NET Core and react accordingly?
Yes, the issue plagues all versions of ChakraCore.