diff --git a/CHANGES b/CHANGES index 10c516fb0f..36e492efa4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +5790. [bug] Enforce enqueuing TCP resumeread to prevent the + next read callback from being executed before the + current read callback has finished, and the worker + receive buffer has been marked as "freed". [GL #3079] + 5789. [bug] Allow replacing expired zone signatures with signatures created by the KSK. [GL #3049] diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index cfecfd3123..aa064d1035 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -53,3 +53,7 @@ Bug Fixes version of the zone, preventing resynchronization of zone contents after ``named`` restart in case the unsigned zone file gets modified while ``named`` is not running. This has been fixed. :gl:`#3071` + +- Under certain circumstances, reading from the raw TCP channels used + for rndc and statistics could cause assertion failure. This has been + fixed. :gl:`#3079` diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index b818f41a20..872d96fe6a 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -814,6 +814,7 @@ isc__nm_tcp_resumeread(isc_nmhandle_t *handle) { isc__netievent_tcpstartread_t *ievent = NULL; isc_nmsocket_t *sock = handle->sock; + isc__networker_t *worker = &sock->mgr->workers[sock->tid]; REQUIRE(sock->tid == isc_nm_tid()); @@ -835,8 +836,18 @@ isc__nm_tcp_resumeread(isc_nmhandle_t *handle) { ievent = isc__nm_get_netievent_tcpstartread(sock->mgr, sock); - isc__nm_maybe_enqueue_ievent(&sock->mgr->workers[sock->tid], - (isc__netievent_t *)ievent); + if (worker->recvbuf_inuse) { + /* + * If we happen to call the resumeread from inside the receive + * callback, the worker->recvbuf might still be in use, so we + * need to force enqueue the next read event. + */ + isc__nm_enqueue_ievent(worker, (isc__netievent_t *)ievent); + + } else { + isc__nm_maybe_enqueue_ievent(worker, + (isc__netievent_t *)ievent); + } } void