]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix reading extra messages in TLS DNS in client mode
authorArtem Boldariev <artem@boldariev.com>
Wed, 17 Jan 2024 13:40:56 +0000 (15:40 +0200)
committerArtem Boldariev <artem@boldariev.com>
Wed, 17 Jan 2024 20:35:25 +0000 (22:35 +0200)
When connecting to a remote party the TLS DNS code could process more
than one message at a time despite the fact that it is expected that
we should stop after every DNS message.

Every DNS message is handled and consumed from the input buffer by
isc__nm_process_sock_buffer(). However, as opposed to TCP DNS code, it
can be called more than once when processing incoming data from a
server (see tls_cycle_input()). That, in turn means that we can
process more than one message at a time. Some higher level code might
not expect that, as it breaks the contract.

In particular, in the original report that happened during
isc__nm_async_tlsdnsshutdown() call: when shutting down multiple calls
to tls_cycle() are possible (each possibly leading to a
isc__nm_process_sock_buffer()). If there are any non processed
messages left, for any of the messages left the read callback will be
called even when it is not expected as there were no preceding
isc_nm_read().

To keep TCP DNS and TLS DNS code in sync, we make a similar change to
it as well, although it should not matter.

lib/isc/netmgr/tcpdns.c
lib/isc/netmgr/tlsdns.c

index eda6aa62ce640f39b1134592a5778c178997721a..cabc90533d9b75764c41ad3e70f764611ad22da8 100644 (file)
@@ -808,6 +808,13 @@ isc__nm_tcpdns_processbuffer(isc_nmsocket_t *sock) {
                return (ISC_R_CANCELED);
        }
 
+       if (sock->client && !sock->recv_read) {
+               /*
+                * We are not reading data - stop here.
+                */
+               return (ISC_R_CANCELED);
+       }
+
        req = isc__nm_get_read_req(sock, NULL);
        REQUIRE(VALID_UVREQ(req));
 
index d30e33fbfd26ec6dd120569fec45013abd89b1f6..cfc62eb5e918717509aa0021bed99715f5516443 100644 (file)
@@ -1016,6 +1016,13 @@ isc__nm_tlsdns_processbuffer(isc_nmsocket_t *sock) {
                return (ISC_R_CANCELED);
        }
 
+       if (sock->client && !sock->recv_read) {
+               /*
+                * We are not reading data - stop here.
+                */
+               return (ISC_R_CANCELED);
+       }
+
        req = isc__nm_get_read_req(sock, NULL);
        REQUIRE(VALID_UVREQ(req));