From: Artem Boldariev Date: Tue, 28 Jun 2022 18:05:23 +0000 (+0300) Subject: TLSDNS: try pass incoming data to OpenSSL if there are any X-Git-Tag: v9.19.4~40^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8585b92f9873c7522614a6264ef5e7f5d0921848;p=thirdparty%2Fbind9.git TLSDNS: try pass incoming data to OpenSSL if there are any Otherwise the code path will lead to a call to SSL_get_error() returning SSL_ERROR_SSL, which in turn might lead to closing connection to early in an unexpected way, as it is clearly not what is intended. The issue was found when working on loppmgr branch and appears to be timing related as well. Might be responsible for some unexpected transmission failures e.g. on zone transfers. --- diff --git a/lib/isc/netmgr/tlsdns.c b/lib/isc/netmgr/tlsdns.c index e2b0f5fe661..42f47cb4238 100644 --- a/lib/isc/netmgr/tlsdns.c +++ b/lib/isc/netmgr/tlsdns.c @@ -1059,38 +1059,46 @@ tls_cycle_input(isc_nmsocket_t *sock) { pending = (int)ISC_NETMGR_TCP_RECVBUF_SIZE; } - if ((sock->buf_len + pending) > sock->buf_size) { - isc__nm_alloc_dnsbuf(sock, - sock->buf_len + pending); - } - - len = 0; - rv = SSL_read_ex(sock->tls.tls, - sock->buf + sock->buf_len, - sock->buf_size - sock->buf_len, &len); - if (rv != 1) { - /* - * Process what's in the buffer so far - */ - result = isc__nm_process_sock_buffer(sock); - if (result != ISC_R_SUCCESS) { - goto failure; + if (pending != 0) { + if ((sock->buf_len + pending) > sock->buf_size) + { + isc__nm_alloc_dnsbuf( + sock, sock->buf_len + pending); } - /* - * FIXME: Should we call - * isc__nm_failed_read_cb()? - */ - break; - } - INSIST((size_t)pending == len); + len = 0; + rv = SSL_read_ex(sock->tls.tls, + sock->buf + sock->buf_len, + sock->buf_size - sock->buf_len, + &len); + if (rv != 1) { + /* + * Process what's in the buffer so far + */ + result = isc__nm_process_sock_buffer( + sock); + if (result != ISC_R_SUCCESS) { + goto failure; + } + /* + * FIXME: Should we call + * isc__nm_failed_read_cb()? + */ + break; + } - sock->buf_len += len; + INSIST((size_t)pending == len); + sock->buf_len += len; + } result = isc__nm_process_sock_buffer(sock); if (result != ISC_R_SUCCESS) { goto failure; } + + if (pending == 0) { + break; + } } } else if (!SSL_is_init_finished(sock->tls.tls)) { if (SSL_is_server(sock->tls.tls)) {