2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 14:07:59 +00:00

Fix a crash by attach to the transport socket as early as possible

This commit fixes a crash in DoH caused by transport handle to be
detached too early when sending outgoing data.

We need to attach to the session->handle earlier because as an
indirect result of the nghttp2_session_mem_send() the session might
get closed and the handle detached. However, there is still might be
some outgoing data to handle. Besides, even when the underlying socket
was closed via the handle, we still should try to attempt to send
outgoing data via isc_nm_send() to let it call write callback, passed
to the http_send_outgoing().
This commit is contained in:
Artem Boldariev
2021-07-22 00:04:02 +03:00
parent e0704f2e5d
commit 849d38b57b

View File

@@ -1054,6 +1054,7 @@ http_send_outgoing(isc_nm_http_session_t *session, isc_nmhandle_t *httphandle,
size_t total = 0;
uint8_t tmp_data[8192] = { 0 };
uint8_t *prepared_data = &tmp_data[0];
isc_nmhandle_t *transphandle = NULL;
#ifdef ENABLE_HTTP_WRITE_BUFFERING
size_t max_total_write_size = 0;
#endif /* ENABLE_HTTP_WRITE_BUFFERING */
@@ -1065,6 +1066,14 @@ http_send_outgoing(isc_nm_http_session_t *session, isc_nmhandle_t *httphandle,
return (false);
}
/* We need to attach to the session->handle earlier because as an
* indirect result of the nghttp2_session_mem_send() the session
* might get closed and the handle detached. However, there is
* still some outgoing data to handle and we need to call it
* anyway if only to get the write callback passed here to get
* called properly. */
isc_nmhandle_attach(session->handle, &transphandle);
while (nghttp2_session_want_write(session->ngsession)) {
const uint8_t *data = NULL;
const size_t pending =
@@ -1159,7 +1168,7 @@ http_send_outgoing(isc_nm_http_session_t *session, isc_nmhandle_t *httphandle,
if (prepared_data != &tmp_data[0]) {
isc_mem_put(session->mctx, prepared_data, total);
}
return (false);
goto failure;
} else if (session->sending == 0 && total == 0 &&
session->pending_write_data != NULL)
{
@@ -1198,7 +1207,7 @@ http_send_outgoing(isc_nm_http_session_t *session, isc_nmhandle_t *httphandle,
if (total == 0) {
INSIST(prepared_data == &tmp_data[0]);
/* No data returned */
return (false);
goto failure;
}
send = isc_mem_get(session->mctx, sizeof(*send));
@@ -1222,7 +1231,8 @@ http_send_outgoing(isc_nm_http_session_t *session, isc_nmhandle_t *httphandle,
.data.length = total,
};
}
isc_nmhandle_attach(session->handle, &send->transphandle);
send->transphandle = transphandle;
isc__nm_httpsession_attach(session, &send->session);
if (cb != NULL) {
@@ -1235,8 +1245,11 @@ http_send_outgoing(isc_nm_http_session_t *session, isc_nmhandle_t *httphandle,
move_pending_send_callbacks(session, send);
session->sending++;
isc_nm_send(session->handle, &send->data, http_writecb, send);
isc_nm_send(transphandle, &send->data, http_writecb, send);
return (true);
failure:
isc_nmhandle_detach(&transphandle);
return (false);
}
static void