]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
TLSDNS: try pass incoming data to OpenSSL if there are any
authorArtem Boldariev <artem@boldariev.com>
Tue, 28 Jun 2022 18:05:23 +0000 (21:05 +0300)
committerArtem Boldariev <artem@boldariev.com>
Tue, 12 Jul 2022 11:40:22 +0000 (14:40 +0300)
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.

lib/isc/netmgr/tlsdns.c

index e2b0f5fe661bd630cf204425ee04a508f215c418..42f47cb4238b799363fcf1775107d7472a16883e 100644 (file)
@@ -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)) {