summaryrefslogtreecommitdiff
path: root/src/mongo/util/net/ssl_manager_openssl.cpp
diff options
context:
space:
mode:
authorAndrew Shuvalov <andrew.shuvalov@mongodb.com>2021-06-18 00:58:06 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-06-18 01:36:03 +0000
commit2cca0d293e35607956f8a84067c563fc3ebfc7cf (patch)
tree6afb456cff7574b63b334f7e3278e19df9d15096 /src/mongo/util/net/ssl_manager_openssl.cpp
parent5d71a73a7b232faa1c9c982e90f105df38486985 (diff)
downloadmongo-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.cpp64
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) {