From 5ebe2918a192e7b7ed0fc771f80c35fd81395464 Mon Sep 17 00:00:00 2001 From: Olivier SOLDANO <olivier.soldano@savoirfairelinux.com> Date: Wed, 14 Feb 2018 14:16:39 -0500 Subject: [PATCH] fix infinite loop in PMTUD When the TLS session was closed during path mtu discovery, the EINTR signal was captured by the retry loop, causing it to loop indefinitelly as the state of the session was TlsSessionState::SHUTDOWN ; each retry triggering another EINTR from TlsSessionImpl::waitForRawData, making gnutls_heartbeat_ping to return GNUTLS_E_INTERRUPTED on the pong wait). the guard to this loop was modified to take into account the state of the session on GNUTLS_E_ITERRUPTED. Another do/while loop was guarded by the same condition in TlsSessionImpl::send, the same countermeasures have been put in place. Change-Id: Ib2ab8975c8044d9bac0abdcace94d79b5eeb75b9 Reviewed-by: Philippe Gorley <philippe.gorley@savoirfairelinux.com> --- src/security/tls_session.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/security/tls_session.cpp b/src/security/tls_session.cpp index 97f4212bce..b52cd6c4e6 100644 --- a/src/security/tls_session.cpp +++ b/src/security/tls_session.cpp @@ -552,7 +552,7 @@ TlsSession::TlsSessionImpl::send(const ValueType* tx_data, std::size_t tx_size, ssize_t nwritten; do { nwritten = gnutls_record_send(session_, data_seq, chunck_sz); - } while (nwritten == GNUTLS_E_INTERRUPTED or nwritten == GNUTLS_E_AGAIN); + } while ((nwritten == GNUTLS_E_INTERRUPTED and state_ != TlsSessionState::SHUTDOWN) or nwritten == GNUTLS_E_AGAIN); if (nwritten <= 0) { /* Normally we would have to retry record_send but our internal * state has not changed, so we have to ask for more data first. @@ -887,6 +887,10 @@ TlsSession::TlsSessionImpl::handleStateMtuDiscovery(UNUSED TlsSessionState state if (gnutls_heartbeat_allowed(session_, GNUTLS_HB_LOCAL_ALLOWED_TO_SEND) == 1) { if (!isServer_) { pathMtuHeartbeat(); + if (state_ == TlsSessionState::SHUTDOWN) { + RING_ERR("[TLS] session destroyed while performing PMTUD, shuting down"); + return TlsSessionState::SHUTDOWN; + } pmtudOver_ = true; } } else { @@ -948,7 +952,7 @@ TlsSession::TlsSessionImpl::pathMtuHeartbeat() do { errno_send = gnutls_heartbeat_ping(session_, bytesToSend, HEARTBEAT_TRIES, GNUTLS_HEARTBEAT_WAIT); - } while (errno_send == GNUTLS_E_AGAIN || errno_send == GNUTLS_E_INTERRUPTED); + } while (errno_send == GNUTLS_E_AGAIN || (errno_send == GNUTLS_E_INTERRUPTED && state_ != TlsSessionState::SHUTDOWN)); if (errno_send != GNUTLS_E_SUCCESS) { RING_DBG() << "[TLS] PMTUD: mtu " << mtu << " [FAILED]"; -- GitLab