diff options
author | Andrew Shuvalov <andrew.shuvalov@mongodb.com> | 2021-06-18 00:58:06 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-06-18 01:36:03 +0000 |
commit | 2cca0d293e35607956f8a84067c563fc3ebfc7cf (patch) | |
tree | 6afb456cff7574b63b334f7e3278e19df9d15096 /src/mongo/util/net/ssl_manager_openssl.cpp | |
parent | 5d71a73a7b232faa1c9c982e90f105df38486985 (diff) | |
download | mongo-2cca0d293e35607956f8a84067c563fc3ebfc7cf.tar.gz |
SERVER-57601: OCSPFetcher must verify that the SSLConnectionContext that owns SSLManagerOpenSSL is still valid
Diffstat (limited to 'src/mongo/util/net/ssl_manager_openssl.cpp')
-rw-r--r-- | src/mongo/util/net/ssl_manager_openssl.cpp | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/src/mongo/util/net/ssl_manager_openssl.cpp b/src/mongo/util/net/ssl_manager_openssl.cpp index 35757771513..2965a8f9a66 100644 --- a/src/mongo/util/net/ssl_manager_openssl.cpp +++ b/src/mongo/util/net/ssl_manager_openssl.cpp @@ -52,6 +52,7 @@ #include "mongo/logv2/log.h" #include "mongo/platform/atomic_word.h" #include "mongo/transport/session.h" +#include "mongo/transport/ssl_connection_context.h" #include "mongo/util/assert_util.h" #include "mongo/util/concurrency/mutex.h" #include "mongo/util/debug_util.h" @@ -101,6 +102,8 @@ using namespace fmt::literals; namespace mongo { +using transport::SSLConnectionContext; + namespace { MONGO_FAIL_POINT_DEFINE(disableStapling); @@ -1106,6 +1109,10 @@ private: void doPeriodicJob(); + bool _isShutdownConditionLocked(WithLock); + + void _shutdownLocked(WithLock); + private: // Hack // OpenSSL 1.1.0 = Since OpenSSL is ref counted underneath, we should use SSL_CTX_up_ref. @@ -1119,6 +1126,10 @@ private: // object is alive. SSLManagerOpenSSL* _manager; + // Weak pointer to verify that the context owning the manager above is still valid + // and the manager it owns still matches the manager. + std::weak_ptr<const SSLConnectionContext> _ownedByContext; + Mutex _staplingMutex = MONGO_MAKE_LATCH("OCSPStaplingJobRunner::_mutex"); PeriodicRunner::JobAnchor _ocspStaplingAnchor; bool _shutdown{false}; @@ -1142,6 +1153,12 @@ public: const SSLParams& params, ConnectionDirection direction) final; + void registerOwnedBySSLContext(std::weak_ptr<const SSLConnectionContext> ownedByContext) final; + + std::weak_ptr<const SSLConnectionContext> getSSLContextOwner() { + return *_ownedByContext; + } + SSLConnectionInterface* connect(Socket* socket) final; SSLConnectionInterface* accept(Socket* socket, const char* initialBytes, int len) final; @@ -1205,6 +1222,9 @@ private: // with TransientSSLParams::targetedClusterConnectionString. const std::optional<TransientSSLParams> _transientSSLParams; + // Weak pointer to verify that this manager is still owned by this context. + synchronized_value<std::weak_ptr<const SSLConnectionContext>> _ownedByContext; + Mutex _sharedResponseMutex = MONGO_MAKE_LATCH("OCSPStaplingJobRunner::_sharedResponseMutex"); std::shared_ptr<OCSPStaplingContext> _ocspStaplingContext; @@ -1985,6 +2005,9 @@ Status OCSPFetcher::start(SSL_CTX* context, bool asyncOCSPStaple) { // the OCSPFetcher _ssl = UniqueSSL(SSL_new(context)); _context = context; + _ownedByContext = _manager->getSSLContextOwner(); + // Verify the consistent link between manager and the context that owns it. + invariant(_ownedByContext.lock()->manager.get() == _manager); auto certificateHolder = getCertificateForContext(_context); _cert = std::get<X509*>(certificateHolder); @@ -2048,7 +2071,7 @@ void OCSPFetcher::startPeriodicJob(StatusWith<Milliseconds> swDurationInitial) { return; } - if (_shutdown) { + if (_isShutdownConditionLocked(lock)) { return; } @@ -2072,13 +2095,40 @@ void OCSPFetcher::doPeriodicJob() { stdx::lock_guard<Latch> lock(this->_staplingMutex); - if (_shutdown) { + if (_isShutdownConditionLocked(lock)) { return; } this->_ocspStaplingAnchor.setPeriod(getPeriodForStapleJob(swDuration)); }); } + +bool OCSPFetcher::_isShutdownConditionLocked(WithLock lock) { + if (_shutdown) { + return true; + } + + const auto lockedContext = _ownedByContext.lock(); + const auto lockedContextFromManager = _manager->getSSLContextOwner().lock(); + if (!lockedContext) { + LOGV2(5760101, + "SSLConnectionContext that should own the manager for the active OCSPFetcher is " + "deleted"); + _shutdownLocked(lock); + return true; + } + + if (lockedContext.get() != lockedContextFromManager.get()) { + LOGV2_WARNING(5760102, + "SSLConnectionContext that should own the manager for the active OCSPFetcher " + "doesn't match"); + _shutdownLocked(lock); + return true; + } + + return false; +} + #if OPENSSL_VERSION_NUMBER < 0x10100000L void sslContextGetOtherCerts(SSL_CTX* ctx, STACK_OF(X509) * *sk) { SSL_CTX_get_extra_chain_certs(ctx, sk); @@ -2128,7 +2178,7 @@ Future<Milliseconds> OCSPFetcher::fetchAndStaple(Promise<void>* promise) { [this, promise](StatusWith<OCSPFetchResponse> swResponse) mutable -> Milliseconds { stdx::lock_guard<Latch> lock(this->_staplingMutex); - if (_shutdown) { + if (_isShutdownConditionLocked(lock)) { return kOCSPUnknownStatusRefreshRate; } @@ -2147,7 +2197,10 @@ Future<Milliseconds> OCSPFetcher::fetchAndStaple(Promise<void>* promise) { void OCSPFetcher::shutdown() { stdx::lock_guard<Mutex> lock(_staplingMutex); + _shutdownLocked(lock); +} +void OCSPFetcher::_shutdownLocked(WithLock) { _shutdown = true; if (_ocspStaplingAnchor.isValid()) { @@ -2384,6 +2437,11 @@ Status SSLManagerOpenSSL::initSSLContext(SSL_CTX* context, return Status::OK(); } +void SSLManagerOpenSSL::registerOwnedBySSLContext( + std::weak_ptr<const SSLConnectionContext> ownedByContext) { + _ownedByContext = ownedByContext; +} + bool SSLManagerOpenSSL::_initSynchronousSSLContext(UniqueSSLContext* contextPtr, const SSLParams& params, ConnectionDirection direction) { |