Commit 896db0f4 authored by Witold Krecicki's avatar Witold Krecicki Committed by Witold Krecicki
Browse files

Fix possible race in isc__nm_tcpconnect.

There's a possibility of race in isc__nm_tcpconnect if the asynchronous
connect operation finishes with all the callbacks before we exit the
isc__nm_tcpconnect itself we might access an already freed memory.
Fix it by creating an additional reference to the socket freed at the
end of isc__nm_tcpconnect.
parent 25f84ffc
...@@ -195,9 +195,10 @@ tcp_connect_cb(uv_connect_t *uvreq, int status) { ...@@ -195,9 +195,10 @@ tcp_connect_cb(uv_connect_t *uvreq, int status) {
isc_result_t isc_result_t
isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer, isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
isc_nm_cb_t cb, void *cbarg, size_t extrahandlesize) { isc_nm_cb_t cb, void *cbarg, size_t extrahandlesize) {
isc_nmsocket_t *nsock = NULL; isc_nmsocket_t *nsock = NULL, *tmp = NULL;
isc__netievent_tcpconnect_t *ievent = NULL; isc__netievent_tcpconnect_t *ievent = NULL;
isc__nm_uvreq_t *req = NULL; isc__nm_uvreq_t *req = NULL;
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(VALID_NM(mgr)); REQUIRE(VALID_NM(mgr));
...@@ -215,6 +216,12 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer, ...@@ -215,6 +216,12 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
ievent->sock = nsock; ievent->sock = nsock;
ievent->req = req; ievent->req = req;
/*
* Async callbacks can dereference the socket in the meantime,
* we need to hold an additional reference to it.
*/
isc__nmsocket_attach(nsock, &tmp);
if (isc__nm_in_netthread()) { if (isc__nm_in_netthread()) {
nsock->tid = isc_nm_tid(); nsock->tid = isc_nm_tid();
isc__nm_async_tcpconnect(&mgr->workers[nsock->tid], isc__nm_async_tcpconnect(&mgr->workers[nsock->tid],
...@@ -234,12 +241,13 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer, ...@@ -234,12 +241,13 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
} }
if (nsock->result != ISC_R_SUCCESS) { if (nsock->result != ISC_R_SUCCESS) {
isc_result_t result = nsock->result; result = nsock->result;
isc__nmsocket_detach(&nsock); isc__nmsocket_detach(&nsock);
return (result);
} }
return (ISC_R_SUCCESS); isc__nmsocket_detach(&tmp);
return (result);
} }
isc_result_t isc_result_t
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment