diff --git a/CHANGES b/CHANGES index 5455544899..0bc037a467 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +6341. [bug] Address use after free in ccmsg_senddone. [GL #4549] + 6340. [test] Fix incorrectly reported errors when running tests with `make test` on platforms with older pytest. [GL #4560] diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c index 46b7ab8928..e276497f9e 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -262,10 +262,11 @@ control_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) { /* Everything is peachy, continue reading from the socket */ isccc_ccmsg_readmessage(&conn->ccmsg, control_recvmessage, conn); - goto done; + /* Detach the sending reference */ + controlconnection_detach(&conn); + return; } - /* This is the error path */ if (result != ISC_R_SHUTTINGDOWN) { char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t peeraddr = isc_nmhandle_peeraddr(handle); @@ -277,9 +278,9 @@ control_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) { socktext, isc_result_totext(result)); } + /* Shutdown the reading */ conn_shutdown(conn); -done: /* Detach the sending reference */ controlconnection_detach(&conn); } @@ -559,9 +560,6 @@ cleanup: case ISC_R_EOF: break; default: - /* We can't get here on normal path */ - INSIST(result != ISC_R_SUCCESS); - log_invalid(&conn->ccmsg, result); } diff --git a/lib/isccc/ccmsg.c b/lib/isccc/ccmsg.c index 80d622da79..4c5ff61e5f 100644 --- a/lib/isccc/ccmsg.c +++ b/lib/isccc/ccmsg.c @@ -102,10 +102,7 @@ recv_data(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, done: isc_nm_read_stop(handle); - if (ccmsg->reading) { - ccmsg->reading = false; - ccmsg->recv_cb(handle, eresult, ccmsg->recv_cbarg); - } + ccmsg->recv_cb(handle, eresult, ccmsg->recv_cbarg); return; } @@ -145,7 +142,6 @@ isccc_ccmsg_readmessage(isccc_ccmsg_t *ccmsg, isc_nm_cb_t cb, void *cbarg) { ccmsg->recv_cbarg = cbarg; ccmsg->length_received = false; - ccmsg->reading = true; isc_nm_read(ccmsg->handle, recv_data, ccmsg); } @@ -154,14 +150,12 @@ ccmsg_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { isccc_ccmsg_t *ccmsg = arg; REQUIRE(VALID_CCMSG(ccmsg)); + REQUIRE(ccmsg->send_cb != NULL); - INSIST(ccmsg->send_cb != NULL); - ccmsg->send_cb(handle, eresult, ccmsg->send_cbarg); + isc_nm_cb_t send_cb = ccmsg->send_cb; ccmsg->send_cb = NULL; - if (eresult != ISC_R_SUCCESS && ccmsg->reading) { - recv_data(handle, eresult, NULL, ccmsg); - } + send_cb(handle, eresult, ccmsg->send_cbarg); isc_nmhandle_detach(&handle); } @@ -184,6 +178,7 @@ isccc_ccmsg_disconnect(isccc_ccmsg_t *ccmsg) { REQUIRE(VALID_CCMSG(ccmsg)); if (ccmsg->handle != NULL) { + isc_nm_read_stop(ccmsg->handle); isc_nmhandle_close(ccmsg->handle); isc_nmhandle_detach(&ccmsg->handle); } diff --git a/lib/isccc/include/isccc/ccmsg.h b/lib/isccc/include/isccc/ccmsg.h index 7a20a7c2e1..5120732901 100644 --- a/lib/isccc/include/isccc/ccmsg.h +++ b/lib/isccc/include/isccc/ccmsg.h @@ -54,7 +54,6 @@ typedef struct isccc_ccmsg { void *recv_cbarg; isc_nm_cb_t send_cb; void *send_cbarg; - bool reading; } isccc_ccmsg_t; ISC_LANG_BEGINDECLS