docs/sdl-gs-crash-monitoring.md
This document describes the process for monitoring, analyzing, and fixing /GS (stack buffer overrun) crashes in React Native Windows, in accordance with Microsoft's Security Development Lifecycle (SDL) policy requirements.
A /GS crash occurs when the /GS compiler flag detects stack buffer corruption. The /GS flag adds security checks (stack cookies) to detect buffer overruns. When a mismatch is detected, the application is terminated with exception code 0xc0000409 (STATUS_STACK_BUFFER_OVERRUN).
Per Microsoft SDL policy:
GS_FALSE_POSITIVE_*)Watson automatically classifies /GS crashes using the !gs debugger extension:
0xc0000409Use the provided Analyze-Crash.ps1 script to analyze crash dumps:
# Analyze a specific dump file
.\vnext\Scripts\Analyze-Crash.ps1 -DumpFilePath "path\to\crash.dmp"
# Or configure automatic dump collection for an exe
.\vnext\Scripts\Analyze-Crash.ps1 -ExeName "YourApp"
The script will:
!gs debugger extension for detailed analysis| Classification | Priority | Action Required | Timeline |
|---|---|---|---|
| GS_POSITIVE | Critical | Analyze, fix, and test | Within 60 days of Watson report |
| GS_SUSPECT | High | Investigate and determine if real | Within 90 days |
| GS_FALSE_POSITIVE | Low | No action required | N/A |
When a real stack buffer overrun is identified:
Review the crash analysis
!gs output in the analysis logImplement the fix
strcpy → strcpy_sstrcat → strcat_ssprintf → sprintf_s or snprintfgets → fgets or gets_sTest the fix
Document the fix
Watch out for these common patterns that can lead to stack buffer overruns:
// UNSAFE: No bounds checking
char buffer[100];
strcpy(buffer, userInput); // ❌
// SAFE: Use safe alternative with size
char buffer[100];
strcpy_s(buffer, sizeof(buffer), userInput); // ✅
// UNSAFE: sprintf without size limit
char buffer[50];
sprintf(buffer, "Value: %s", userInput); // ❌
// SAFE: Use snprintf with size limit
char buffer[50];
snprintf(buffer, sizeof(buffer), "Value: %s", userInput); // ✅
// UNSAFE: Array access without bounds check
void ProcessArray(int* data, int count) {
int localArray[10];
for (int i = 0; i < count; i++) { // ❌ count could be > 10
localArray[i] = data[i];
}
}
// SAFE: Add bounds checking
void ProcessArray(int* data, int count) {
int localArray[10];
int safeCount = std::min(count, 10);
for (int i = 0; i < safeCount; i++) { // ✅
localArray[i] = data[i];
}
}
If a /GS crash is determined to be a security vulnerability:
See .github/security.md for full security reporting guidelines.
To comply with SDL requirements:
For questions about /GS crashes or SDL policy: