From 8c9e75af5f36fc3e2bcbda5601a3e7b9c854839e Mon Sep 17 00:00:00 2001 From: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> Date: Wed, 21 Jun 2017 23:15:59 -0400 Subject: [PATCH] tls: prevent recursive call to flushRxQueue() TlsSession::flushRxQueue() let TlsSession::handleDataPacket() to be called causing a recursive call to TlsSession::flushRxQueue(), finally resulting into application crash. Solve that by testing if we're in flush opeation and just no-op in such case. Change-Id: Ie4d52a9df495784e36e3691404f44cd8f66dbb6d --- src/security/tls_session.cpp | 15 +++++++++++++++ src/security/tls_session.h | 1 + 2 files changed, 16 insertions(+) diff --git a/src/security/tls_session.cpp b/src/security/tls_session.cpp index 4a36762def..5753dacb07 100644 --- a/src/security/tls_session.cpp +++ b/src/security/tls_session.cpp @@ -941,10 +941,25 @@ TlsSession::handleDataPacket(std::vector<uint8_t>&& buf, uint64_t pkt_seq) void TlsSession::flushRxQueue() { + // RAII bool swap + class GuardedBoolSwap { + public: + explicit GuardedBoolSwap(bool& var) : var_ {var} { var_ = !var_; } + ~GuardedBoolSwap() { var_ = !var_; } + private: + bool& var_; + }; + std::unique_lock<std::mutex> lk {reorderBufMutex_}; if (reorderBuffer_.empty()) return; + // Prevent re-entrant access as the callbacks_.onRxData() is called in unprotected region + if (flushProcessing_) + return; + + GuardedBoolSwap swap_flush_processing {flushProcessing_}; + auto item = std::begin(reorderBuffer_); auto next_offset = item->first; auto first_offset = next_offset; diff --git a/src/security/tls_session.h b/src/security/tls_session.h index de04573148..c36a79bfa2 100644 --- a/src/security/tls_session.h +++ b/src/security/tls_session.h @@ -219,6 +219,7 @@ private: std::list<std::vector<uint8_t>> rxQueue_ {}; std::mutex reorderBufMutex_; + bool flushProcessing_ {false}; ///< protect against recursive call to flushRxQueue std::vector<uint8_t> rawPktBuf_; ///< gnutls incoming packet buffer uint64_t baseSeq_ {0}; ///< sequence number of first application data packet received uint64_t lastRxSeq_ {0}; ///< last received and valid packet sequence number -- GitLab