From C# reference for stackalloc:
the use of stackalloc automatically enables buffer overrun detection features in the common language runtime (CLR).
Yes, the .NET jitter generates the kind of stack canary checking that also exists in native code generated by the Microsoft C/C++ compiler with the /GS compiler option. The basic scheme is to store a random 32-bit value at the top of the stack, written at method entry. At method exit it checks if the value is still there. A change in the value is a very high predictor for a stack buffer overflow, the kind that malware uses to take control of a program.
Some code to play with:
class Program {
static void Main(string[] args) {
Kaboom();
}
static unsafe void Kaboom() {
byte* ptr = stackalloc byte[1];
for (int ix = 0; ix < 42; ++ix) ptr[ix] = 0;
}
}
Running this code triggers the Windows Error Reporting dialog, even with the debugger attached. You can see the crash reason in the Output window:
The program '[3636] ConsoleApplication33.exe: Native' has exited with code -1073740791 (0xc0000409).
The exception code is defined in the ntstatus.h SDK header file:
//
// MessageId: STATUS_STACK_BUFFER_OVERRUN
//
// MessageText:
//
// The system detected an overrun of a stack-based buffer in this application. This overrun could
// potentially allow a malicious user to gain control of this application.
//
#define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS)0xC0000409L) // winnt
You can see the code that does this with Debug + Windows + Disassembly. The essential parts of Kaboom:
00000000 push ebp ; setup stack frame
00000001 mov ebp,esp
00000003 sub esp,8 ; stack space for local variables
00000006 xor eax,eax
00000008 mov dword ptr [ebp-8],eax ; zero-initialize local variables
0000000b mov dword ptr [ebp-4],eax
0000000e mov dword ptr [ebp-4],esp
00000011 mov dword ptr [ebp-8],0EDDB7EDFh ; canary stored here
// For loop code omitted
0000002d cmp dword ptr [ebp-8],0EDDB7EDFh ; check canary value
00000034 je 0000003B
00000036 call 727767A8 ; crash program
0000003b lea esp,[ebp] ; normal exit, pop stack frame
0000003e pop ebp
0000003f ret
The actual canary value changes every time the code is jitted.