]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/tls: tls_push() can fall into endless loop in some circumstances; prevent it
authorgrid <grigorii.demidov@nic.cz>
Wed, 13 Dec 2017 09:20:53 +0000 (10:20 +0100)
committerPetr Špaček <petr.spacek@nic.cz>
Mon, 8 Jan 2018 11:01:01 +0000 (12:01 +0100)
daemon/tls.c
daemon/tls.h

index 88d7ce430e0a0befe048cdc7121a40dea5eee9f1..2f2226e3ec5c91167fe86cf50644ae5e0064f0e1 100644 (file)
@@ -231,6 +231,7 @@ int tls_push(struct qr_task *task, uv_handle_t *handle, knot_pkt_t *pkt)
        }
 
        ssize_t submitted = 0;
+       ssize_t retries = 0;
        do {
                count = gnutls_record_uncork(tls_p->session, 0);
                if (count < 0) {
@@ -239,7 +240,13 @@ int tls_push(struct qr_task *task, uv_handle_t *handle, knot_pkt_t *pkt)
                                             gnutls_strerror_name(count), count);
                                return kr_error(EIO);
                        }
+                       if (++retries > TLS_MAX_UNCORK_RETRIES) {
+                               kr_log_error("[tls] gnutls_record_uncork: too many sequential non-fatal errors (%zd), last error is: %s (%zd)\n",
+                                            retries, gnutls_strerror_name(count), count);
+                               return kr_error(EIO);
+                       }
                } else {
+                       retries = 0;
                        submitted += count;
                        if (count == 0 && submitted != sizeof(pkt_size) + pkt->size) {
                                kr_log_error("[tls] gnutls_record_uncork didn't send all data: %s (%zd)\n",
index 20d1efc521e1036d99bf4bc6690c4477906a6608..d13b70ebf042cbf023c5cdd59f458a08fcf55ba5 100644 (file)
@@ -24,6 +24,7 @@
 #include "lib/generic/map.h"
 
 #define MAX_TLS_PADDING KR_EDNS_PAYLOAD
+#define TLS_MAX_UNCORK_RETRIES 100
 
 struct tls_ctx_t;
 struct tls_client_ctx_t;