mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
Prevent an infinite loop in shutdown_listener()
The loop in shutdown_listener() assumes that the reference count for every controlconnection_t object on the listener->connections linked list will drop down to zero after the conn_shutdown() call in the loop's body. However, when the timing is just right, some netmgr callbacks for a given control connection may still be awaiting processing by the same event loop that executes shutdown_listener() when the latter is run. Since these netmgr callbacks must be run in order for the reference count for the relevant controlconnection_t objects to drop to zero, when the scenario described above happens, shutdown_listener() runs into an infinite loop due to one of the controlconnection_t objects on the listener->connections linked list never going away from the head of that list. Fix by safely iterating through the listener->connections list and initiating shutdown for all controlconnection_t objects found. This allows any pending netmgr callbacks to be run by the same event loop in due course, i.e. after shutdown_listener() returns.
This commit is contained in:
@@ -202,15 +202,22 @@ ISC_REFCOUNT_IMPL(controlconnection, conn_free);
|
||||
|
||||
static void
|
||||
shutdown_listener(controllistener_t *listener) {
|
||||
controlconnection_t *conn = NULL;
|
||||
controlconnection_t *next = NULL;
|
||||
|
||||
/* Don't shutdown the same listener twice */
|
||||
if (listener->shuttingdown) {
|
||||
return;
|
||||
}
|
||||
listener->shuttingdown = true;
|
||||
|
||||
for (controlconnection_t *conn = ISC_LIST_HEAD(listener->connections);
|
||||
conn != NULL; conn = ISC_LIST_HEAD(listener->connections))
|
||||
for (conn = ISC_LIST_HEAD(listener->connections); conn != NULL;
|
||||
conn = next)
|
||||
{
|
||||
/*
|
||||
* 'conn' is likely to be freed by the conn_shutdown() call.
|
||||
*/
|
||||
next = ISC_LIST_NEXT(conn, link);
|
||||
conn_shutdown(conn);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user