mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
Fix possible race in socket destruction.
When two threads unreferenced handles coming from one socket while the socket was being destructed we could get a use-after-free: Having handle H1 coming from socket S1, H2 coming from socket S2, S0 being a parent socket to S1 and S2: Thread A Thread B Unref handle H1 Unref handle H2 Remove H1 from S1 active handles Remove H2 from S2 active handles nmsocket_maybe_destroy(S1) nmsocket_maybe_destroy(S2) nmsocket_maybe_destroy(S0) nmsocket_maybe_destroy(S0) LOCK(S0->lock) Go through all children, figure out that we have no more active handles: sum of S0->children[i]->ah == 0 UNLOCK(S0->lock) destroy(S0) LOCK(S0->lock) - but S0 is already gone
This commit is contained in:
@@ -1158,7 +1158,7 @@ nmhandle_deactivate(isc_nmsocket_t *sock, isc_nmhandle_t *handle) {
|
||||
|
||||
void
|
||||
isc_nmhandle_unref(isc_nmhandle_t *handle) {
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
isc_nmsocket_t *sock = NULL, *tmp = NULL;
|
||||
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
|
||||
@@ -1199,8 +1199,14 @@ isc_nmhandle_unref(isc_nmhandle_t *handle) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Temporarily reference the socket to ensure that it can't
|
||||
* be deleted by another thread while we're deactivating the
|
||||
* handle.
|
||||
*/
|
||||
isc_nmsocket_attach(sock, &tmp);
|
||||
nmhandle_deactivate(sock, handle);
|
||||
nmsocket_maybe_destroy(sock);
|
||||
isc_nmsocket_detach(&tmp);
|
||||
}
|
||||
|
||||
void *
|
||||
|
Reference in New Issue
Block a user