]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix a crash by attach to the transport socket as early as possible
authorArtem Boldariev <artem@boldariev.com>
Wed, 21 Jul 2021 21:04:02 +0000 (00:04 +0300)
committerArtem Boldariev <artem@boldariev.com>
Thu, 12 Aug 2021 11:28:16 +0000 (14:28 +0300)
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().

lib/isc/netmgr/http.c

index 3542f9f68e8a341a2cacdf135eebdc880fd8655d..4e77a2ba82987b1cda40f0b6d85d0871cc0c35d8 100644 (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