|
| 1 | +# SDL Policy: /GS Stack Buffer Overrun Crash Monitoring |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +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. |
| 6 | + |
| 7 | +## What is a /GS Crash? |
| 8 | + |
| 9 | +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`). |
| 10 | + |
| 11 | +## SDL Policy Requirements |
| 12 | + |
| 13 | +Per Microsoft SDL policy: |
| 14 | + |
| 15 | +1. **All high-confidence /GS crashes must be analyzed and fixed when appropriate** |
| 16 | +2. **A monitoring plan must be in place to analyze future /GS failures within 60 days** of being reported to Watson |
| 17 | +3. **Teams must investigate all crashes that are not false-positives** (`GS_FALSE_POSITIVE_*`) |
| 18 | +4. **Fix identified stack buffer overruns** to prevent potential security vulnerabilities |
| 19 | + |
| 20 | +## /GS Crash Classifications |
| 21 | + |
| 22 | +Watson automatically classifies /GS crashes using the `!gs` debugger extension: |
| 23 | + |
| 24 | +- **GS_POSITIVE**: High-confidence stack buffer overrun. **MUST be fixed immediately.** |
| 25 | +- **GS_SUSPECT**: Suspected stack buffer overrun. Should be investigated. |
| 26 | +- **GS_FALSE_POSITIVE**: False positive due to process corruption. Can be safely ignored. |
| 27 | + |
| 28 | +## Monitoring Process |
| 29 | + |
| 30 | +### 1. Finding /GS Crashes in Watson |
| 31 | + |
| 32 | +1. Go to [Watson](https://aka.ms/watson) |
| 33 | +2. Select "Buffer Overruns" under "Enter ANY of the following to see matching BUCKET(s)" |
| 34 | +3. Enter the application name (szAppName) or DLL name (szModName) |
| 35 | +4. Click "Show Crash/Hang Buckets" |
| 36 | +5. Filter for crashes with exception code `0xc0000409` |
| 37 | + |
| 38 | +### 2. Analyzing /GS Crashes |
| 39 | + |
| 40 | +Use the provided `Analyze-Crash.ps1` script to analyze crash dumps: |
| 41 | + |
| 42 | +```powershell |
| 43 | +# Analyze a specific dump file |
| 44 | +.\vnext\Scripts\Analyze-Crash.ps1 -DumpFilePath "path\to\crash.dmp" |
| 45 | +
|
| 46 | +# Or configure automatic dump collection for an exe |
| 47 | +.\vnext\Scripts\Analyze-Crash.ps1 -ExeName "YourApp" |
| 48 | +``` |
| 49 | + |
| 50 | +The script will: |
| 51 | +- Detect if the crash is a /GS crash (0xc0000409) |
| 52 | +- Run the `!gs` debugger extension for detailed analysis |
| 53 | +- Classify the crash (GS_POSITIVE, GS_SUSPECT, or GS_FALSE_POSITIVE) |
| 54 | +- Provide actionable guidance based on the classification |
| 55 | + |
| 56 | +### 3. Triage and Response Timeline |
| 57 | + |
| 58 | +| Classification | Priority | Action Required | Timeline | |
| 59 | +|---------------|----------|----------------|----------| |
| 60 | +| GS_POSITIVE | Critical | Analyze, fix, and test | Within 60 days of Watson report | |
| 61 | +| GS_SUSPECT | High | Investigate and determine if real | Within 90 days | |
| 62 | +| GS_FALSE_POSITIVE | Low | No action required | N/A | |
| 63 | + |
| 64 | +### 4. Fixing /GS Crashes |
| 65 | + |
| 66 | +When a real stack buffer overrun is identified: |
| 67 | + |
| 68 | +1. **Review the crash analysis** |
| 69 | + - Check the `!gs` output in the analysis log |
| 70 | + - Identify the function with the buffer overrun |
| 71 | + - Locate the source of the overrun (strcpy, sprintf, etc.) |
| 72 | + |
| 73 | +2. **Implement the fix** |
| 74 | + - Replace unsafe functions with safe alternatives: |
| 75 | + - `strcpy` → `strcpy_s` |
| 76 | + - `strcat` → `strcat_s` |
| 77 | + - `sprintf` → `sprintf_s` or `snprintf` |
| 78 | + - `gets` → `fgets` or `gets_s` |
| 79 | + - Add bounds checking to array operations |
| 80 | + - Validate input sizes before copying |
| 81 | + |
| 82 | +3. **Test the fix** |
| 83 | + - Reproduce the original crash scenario |
| 84 | + - Verify the crash no longer occurs |
| 85 | + - Run existing tests to ensure no regressions |
| 86 | + |
| 87 | +4. **Document the fix** |
| 88 | + - Include CVE information if applicable |
| 89 | + - Document the root cause and fix in commit message |
| 90 | + - Update security documentation if needed |
| 91 | + |
| 92 | +## Common Vulnerable Patterns |
| 93 | + |
| 94 | +Watch out for these common patterns that can lead to stack buffer overruns: |
| 95 | + |
| 96 | +```cpp |
| 97 | +// UNSAFE: No bounds checking |
| 98 | +char buffer[100]; |
| 99 | +strcpy(buffer, userInput); // ❌ |
| 100 | + |
| 101 | +// SAFE: Use safe alternative with size |
| 102 | +char buffer[100]; |
| 103 | +strcpy_s(buffer, sizeof(buffer), userInput); // ✅ |
| 104 | + |
| 105 | +// UNSAFE: sprintf without size limit |
| 106 | +char buffer[50]; |
| 107 | +sprintf(buffer, "Value: %s", userInput); // ❌ |
| 108 | + |
| 109 | +// SAFE: Use snprintf with size limit |
| 110 | +char buffer[50]; |
| 111 | +snprintf(buffer, sizeof(buffer), "Value: %s", userInput); // ✅ |
| 112 | + |
| 113 | +// UNSAFE: Array access without bounds check |
| 114 | +void ProcessArray(int* data, int count) { |
| 115 | + int localArray[10]; |
| 116 | + for (int i = 0; i < count; i++) { // ❌ count could be > 10 |
| 117 | + localArray[i] = data[i]; |
| 118 | + } |
| 119 | +} |
| 120 | + |
| 121 | +// SAFE: Add bounds checking |
| 122 | +void ProcessArray(int* data, int count) { |
| 123 | + int localArray[10]; |
| 124 | + int safeCount = std::min(count, 10); |
| 125 | + for (int i = 0; i < safeCount; i++) { // ✅ |
| 126 | + localArray[i] = data[i]; |
| 127 | + } |
| 128 | +} |
| 129 | +``` |
| 130 | +
|
| 131 | +## Reporting Security Issues |
| 132 | +
|
| 133 | +If a /GS crash is determined to be a security vulnerability: |
| 134 | +
|
| 135 | +1. **Do NOT create a public GitHub issue** |
| 136 | +2. Report to Microsoft Security Response Center (MSRC): |
| 137 | + - Online: https://msrc.microsoft.com/create-report |
| 138 | + - Email: secure@microsoft.com |
| 139 | +3. Include: |
| 140 | + - Type of issue (stack buffer overrun) |
| 141 | + - Full paths of affected source files |
| 142 | + - Steps to reproduce |
| 143 | + - Crash dump and analysis (if safe to share) |
| 144 | + - Potential security impact |
| 145 | +
|
| 146 | +See [.github/security.md](../.github/security.md) for full security reporting guidelines. |
| 147 | +
|
| 148 | +## Tools and Resources |
| 149 | +
|
| 150 | +- **Analyze-Crash.ps1**: Automated crash analysis script with /GS detection |
| 151 | +- **Watson**: https://aka.ms/watson - Microsoft crash reporting system |
| 152 | +- **!gs debugger extension**: Built into Windows debuggers, analyzes /GS crashes |
| 153 | +- **!analyze -v**: Verbose crash analysis including !gs output |
| 154 | +
|
| 155 | +## Regular Monitoring Schedule |
| 156 | +
|
| 157 | +To comply with SDL requirements: |
| 158 | +
|
| 159 | +1. **Weekly**: Check Watson for new /GS crashes |
| 160 | +2. **Monthly**: Review and triage all open /GS issues |
| 161 | +3. **Quarterly**: Audit codebase for unsafe string/buffer operations |
| 162 | +4. **Before Release**: Ensure no open GS_POSITIVE crashes remain |
| 163 | +
|
| 164 | +## Questions? |
| 165 | +
|
| 166 | +For questions about /GS crashes or SDL policy: |
| 167 | +- Internal: Contact your team's security champion |
| 168 | +- External: File an issue in the repository (for non-security questions) |
| 169 | +- Security issues: Follow the reporting process in [.github/security.md](../.github/security.md) |
0 commit comments