Commit ede7069
committed
darwin: fix use after free during reenumeration
When one process has two contexts to libusb, it may trigger a reenumeration
while the other context accesses `*dpriv->device`. Adding a mutex to access
`device` can be costly because it is used in every function. Instead, we
maintain an invariant: the `darwin_cached_device` must be valid at all
times. In particular, this means the fields `device` and `service` must not
be stale or we will have a use after free triggerable through a race
condition.
Previously, in `darwin_devices_detached` during reenumeration, it was
possible for `old_device->device` to be freed. We now defer this free to
`darwin_get_cached_device` after a new `device` is written. Note that the
order is important because we do not have locks, so we must free the old
device after writing the new one. The same point applies to `service` which
we take care to free after the new `service` is written.
A caveat here is that even if we do not crash it is still possible for one
context to be using an outdated `device` and `service` leading to an error
return. This should be acceptable because it would be a similar situation
to the device being detached during an API call.1 parent 7313527 commit ede7069
1 file changed
+15
-10
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
681 | 681 | | |
682 | 682 | | |
683 | 683 | | |
684 | | - | |
685 | | - | |
686 | | - | |
687 | | - | |
688 | | - | |
689 | | - | |
690 | 684 | | |
691 | 685 | | |
692 | 686 | | |
| |||
1292 | 1286 | | |
1293 | 1287 | | |
1294 | 1288 | | |
1295 | | - | |
| 1289 | + | |
| 1290 | + | |
1296 | 1291 | | |
1297 | 1292 | | |
1298 | 1293 | | |
| |||
1320 | 1315 | | |
1321 | 1316 | | |
1322 | 1317 | | |
| 1318 | + | |
| 1319 | + | |
1323 | 1320 | | |
1324 | 1321 | | |
1325 | 1322 | | |
| |||
1358 | 1355 | | |
1359 | 1356 | | |
1360 | 1357 | | |
1361 | | - | |
1362 | | - | |
1363 | | - | |
1364 | 1358 | | |
1365 | 1359 | | |
1366 | 1360 | | |
| |||
1374 | 1368 | | |
1375 | 1369 | | |
1376 | 1370 | | |
| 1371 | + | |
| 1372 | + | |
| 1373 | + | |
| 1374 | + | |
| 1375 | + | |
| 1376 | + | |
| 1377 | + | |
| 1378 | + | |
| 1379 | + | |
| 1380 | + | |
| 1381 | + | |
1377 | 1382 | | |
1378 | 1383 | | |
1379 | 1384 | | |
| |||
0 commit comments