Commit f229052
authored
FIX: Segmentation Fault in libmsodbcsql-18.5 during SQLFreeHandle() (#415)
<!--
IMPORTANT: Please follow the PR template guidelines below.
For mssql-python maintainers: Insert your ADO Work Item ID below
For external contributors: Insert Github Issue number below
Only one reference is required - either GitHub issue OR ADO Work Item.
-->
<!-- mssql-python maintainers: ADO Work Item -->
>
[AB#41463](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/41463)
<!-- External contributors: GitHub Issue -->
> GitHub Issue: #341
-------------------------------------------------------------------
### Summary
<!-- Insert your summary of changes below. Minimum 10 characters
required. -->
This pull request implements a critical fix for a long-standing
use-after-free (segmentation fault) bug that occurred when a database
connection was closed while statement handles were still alive. The fix
ensures that child statement handles are properly tracked and marked as
"implicitly freed" when the parent connection is closed, preventing
double-free and use-after-free errors. Additionally, comprehensive
regression tests are added to verify the fix under various scenarios.
**Critical bug fix for handle management:**
* The `Connection` class now tracks all child statement handles in a
`_childStatementHandles` vector using `weak_ptr` to avoid circular
references and memory leaks. When the connection is closed, all child
statement handles are marked as "implicitly freed" before the parent
handle is released. This prevents the `SqlHandle` destructor from
attempting to free handles that have already been freed by the ODBC
driver.
[[1]](diffhunk://#diff-c74277ea1f36fff8f6bbe9df3fd722f7d270f3d6a3069ac7a747fe6d4235cf13R64-R67)
[[2]](diffhunk://#diff-eca696c13d997f510e5f9b16288ed1deb0ad132768c283eda1518f78edf9b6ecR97-R110)
[[3]](diffhunk://#diff-eca696c13d997f510e5f9b16288ed1deb0ad132768c283eda1518f78edf9b6ecL176-R203)
* The `SqlHandle` class now includes an `_implicitly_freed` flag and a
`markImplicitlyFreed()` method. The `free()` method checks this flag and
skips ODBC cleanup if the handle was already implicitly freed,
preventing use-after-free errors.
[[1]](diffhunk://#diff-85167a2d59779df18704284ab7ce46220c3619408fbf22c631ffdf29f794d635R382-R390)
[[2]](diffhunk://#diff-dde2297345718ec449a14e7dff91b7bb2342b008ecc071f562233646d71144a1R1147-R1150)
[[3]](diffhunk://#diff-dde2297345718ec449a14e7dff91b7bb2342b008ecc071f562233646d71144a1L1172-L1181)
* The Python bindings are updated to expose the new
`markImplicitlyFreed` method on `SqlHandle`, ensuring that the state can
be managed from both C++ and Python layers.
**Testing and verification:**
* A new test file, `test_016_connection_invalidation_segfault.py`, is
added with extensive tests that reproduce the original segfault
scenarios, including multiple cursors, uncommitted transactions,
prepared statements, and concurrent connection invalidation. These tests
confirm that the fix prevents crashes and ensures clean resource
management.
**Other minor changes:**
* Minor whitespace and comment cleanups in unrelated parts of the
codebase.
[[1]](diffhunk://#diff-dde2297345718ec449a14e7dff91b7bb2342b008ecc071f562233646d71144a1L2896)
[[2]](diffhunk://#diff-dde2297345718ec449a14e7dff91b7bb2342b008ecc071f562233646d71144a1L3618-L3619)
This change is critical for stability and correctness when using
connection pooling, SQLAlchemy, or any code that may close connections
before all cursors are explicitly closed.
<!--
### PR Title Guide
> For feature requests
FEAT: (short-description)
> For non-feature requests like test case updates, config updates ,
dependency updates etc
CHORE: (short-description)
> For Fix requests
FIX: (short-description)
> For doc update requests
DOC: (short-description)
> For Formatting, indentation, or styling update
STYLE: (short-description)
> For Refactor, without any feature changes
REFACTOR: (short-description)
> For release related changes, without any feature changes
RELEASE: #<RELEASE_VERSION> (short-description)
### Contribution Guidelines
External contributors:
- Create a GitHub issue first:
https://github.com/microsoft/mssql-python/issues/new
- Link the GitHub issue in the "GitHub Issue" section above
- Follow the PR title format and provide a meaningful summary
mssql-python maintainers:
- Create an ADO Work Item following internal processes
- Link the ADO Work Item in the "ADO Work Item" section above
- Follow the PR title format and provide a meaningful summary
-->1 parent 2354f09 commit f229052
File tree
5 files changed
+447
-17
lines changed- mssql_python/pybind
- connection
- tests
5 files changed
+447
-17
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
94 | 94 | | |
95 | 95 | | |
96 | 96 | | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
97 | 138 | | |
98 | 139 | | |
99 | 140 | | |
| |||
173 | 214 | | |
174 | 215 | | |
175 | 216 | | |
176 | | - | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
177 | 247 | | |
178 | 248 | | |
179 | 249 | | |
| |||
308 | 378 | | |
309 | 379 | | |
310 | 380 | | |
311 | | - | |
| 381 | + | |
312 | 382 | | |
313 | 383 | | |
314 | 384 | | |
| |||
320 | 390 | | |
321 | 391 | | |
322 | 392 | | |
323 | | - | |
| 393 | + | |
324 | 394 | | |
325 | 395 | | |
326 | 396 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
12 | 21 | | |
13 | 22 | | |
14 | 23 | | |
| |||
61 | 70 | | |
62 | 71 | | |
63 | 72 | | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
64 | 89 | | |
65 | 90 | | |
66 | 91 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1144 | 1144 | | |
1145 | 1145 | | |
1146 | 1146 | | |
| 1147 | + | |
| 1148 | + | |
| 1149 | + | |
| 1150 | + | |
| 1151 | + | |
| 1152 | + | |
| 1153 | + | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
| 1157 | + | |
| 1158 | + | |
| 1159 | + | |
| 1160 | + | |
| 1161 | + | |
1147 | 1162 | | |
1148 | 1163 | | |
1149 | 1164 | | |
| |||
1169 | 1184 | | |
1170 | 1185 | | |
1171 | 1186 | | |
1172 | | - | |
| 1187 | + | |
| 1188 | + | |
| 1189 | + | |
| 1190 | + | |
| 1191 | + | |
| 1192 | + | |
| 1193 | + | |
| 1194 | + | |
| 1195 | + | |
| 1196 | + | |
| 1197 | + | |
1173 | 1198 | | |
1174 | 1199 | | |
1175 | | - | |
1176 | | - | |
1177 | | - | |
1178 | | - | |
1179 | | - | |
1180 | | - | |
1181 | | - | |
1182 | 1200 | | |
1183 | 1201 | | |
1184 | 1202 | | |
| |||
2893 | 2911 | | |
2894 | 2912 | | |
2895 | 2913 | | |
2896 | | - | |
2897 | 2914 | | |
2898 | 2915 | | |
2899 | 2916 | | |
| |||
3615 | 3632 | | |
3616 | 3633 | | |
3617 | 3634 | | |
3618 | | - | |
3619 | | - | |
3620 | 3635 | | |
3621 | 3636 | | |
3622 | 3637 | | |
| |||
4033 | 4048 | | |
4034 | 4049 | | |
4035 | 4050 | | |
4036 | | - | |
4037 | | - | |
| 4051 | + | |
| 4052 | + | |
4038 | 4053 | | |
4039 | 4054 | | |
4040 | 4055 | | |
| |||
4066 | 4081 | | |
4067 | 4082 | | |
4068 | 4083 | | |
4069 | | - | |
| 4084 | + | |
4070 | 4085 | | |
4071 | 4086 | | |
4072 | 4087 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
379 | 379 | | |
380 | 380 | | |
381 | 381 | | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
382 | 396 | | |
383 | 397 | | |
384 | 398 | | |
| 399 | + | |
385 | 400 | | |
386 | 401 | | |
387 | 402 | | |
| |||
0 commit comments