From e9089c4aa7c8ae9ea202a41ceb29bcb8fecea02c Mon Sep 17 00:00:00 2001 From: Sean Cannella Date: Thu, 30 Apr 2015 18:51:17 -0700 Subject: [PATCH] Lazily initialize AsyncSSLSocket EorBioMethod Summary: Address another Android initialization crash by delaying initialization of the EorBio method until first AsyncSSLSocket construction. Test Plan: existing tests Reviewed By: pgriess@fb.com Subscribers: net-systems@, ssl-diffs@, folly-diffs@, yfeldblum, chalfant, #csti FB internal diff: D2036329 Tasks: 6925575, 6925570 Signature: t1:2036329:1430444665:a3201f90860a34808a3cf3b42d530608c8a619a8 --- folly/io/async/AsyncSSLSocket.cpp | 32 +++++++++++++++++-------------- folly/io/async/AsyncSSLSocket.h | 4 ++++ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/folly/io/async/AsyncSSLSocket.cpp b/folly/io/async/AsyncSSLSocket.cpp index a6e3307c..cec2cdeb 100644 --- a/folly/io/async/AsyncSSLSocket.cpp +++ b/folly/io/async/AsyncSSLSocket.cpp @@ -224,8 +224,7 @@ void setup_SSL_CTX(SSL_CTX *ctx) { BIO_METHOD eorAwareBioMethod; -__attribute__((__constructor__)) -void initEorBioMethod(void) { +void* initEorBioMethod(void) { memcpy(&eorAwareBioMethod, BIO_s_socket(), sizeof(eorAwareBioMethod)); // override the bwrite method for MSG_EOR support eorAwareBioMethod.bwrite = AsyncSSLSocket::eorAwareBioWrite; @@ -234,6 +233,10 @@ void initEorBioMethod(void) { // set here. openssl code seems to be checking ".type == BIO_TYPE_SOCKET" and // then have specific handlings. The eorAwareBioWrite should be compatible // with the one in openssl. + + // Return something here to enable AsyncSSLSocket to call this method using + // a function-scoped static. + return nullptr; } } // anonymous namespace @@ -254,7 +257,7 @@ AsyncSSLSocket::AsyncSSLSocket(const shared_ptr &ctx, AsyncSocket(evb), ctx_(ctx), handshakeTimeout_(this, evb) { - setup_SSL_CTX(ctx_->getSSLCtx()); + init(); } /** @@ -266,7 +269,7 @@ AsyncSSLSocket::AsyncSSLSocket(const shared_ptr& ctx, server_(server), ctx_(ctx), handshakeTimeout_(this, evb) { - setup_SSL_CTX(ctx_->getSSLCtx()); + init(); if (server) { SSL_CTX_set_info_callback(ctx_->getSSLCtx(), AsyncSSLSocket::sslInfoCallback); @@ -281,11 +284,8 @@ AsyncSSLSocket::AsyncSSLSocket(const shared_ptr& ctx, AsyncSSLSocket::AsyncSSLSocket(const shared_ptr &ctx, EventBase* evb, const std::string& serverName) : - AsyncSocket(evb), - ctx_(ctx), - handshakeTimeout_(this, evb), - tlsextHostname_(serverName) { - setup_SSL_CTX(ctx_->getSSLCtx()); + AsyncSSLSocket(ctx, evb) { + tlsextHostname_ = serverName; } /** @@ -295,11 +295,8 @@ AsyncSSLSocket::AsyncSSLSocket(const shared_ptr &ctx, AsyncSSLSocket::AsyncSSLSocket(const shared_ptr& ctx, EventBase* evb, int fd, const std::string& serverName) : - AsyncSocket(evb, fd), - ctx_(ctx), - handshakeTimeout_(this, evb), - tlsextHostname_(serverName) { - setup_SSL_CTX(ctx_->getSSLCtx()); + AsyncSSLSocket(ctx, evb, fd, false) { + tlsextHostname_ = serverName; } #endif @@ -310,6 +307,13 @@ AsyncSSLSocket::~AsyncSSLSocket() { << sslState_ << ", events=" << eventFlags_ << ")"; } +void AsyncSSLSocket::init() { + // Do this here to ensure we initialize this once before any use of + // AsyncSSLSocket instances and not as part of library load. + static const auto eorAwareBioMethodInitializer = initEorBioMethod(); + setup_SSL_CTX(ctx_->getSSLCtx()); +} + void AsyncSSLSocket::closeNow() { // Close the SSL connection. if (ssl_ != nullptr && fd_ != -1) { diff --git a/folly/io/async/AsyncSSLSocket.h b/folly/io/async/AsyncSSLSocket.h index ea7cbbdd..cce4c18b 100644 --- a/folly/io/async/AsyncSSLSocket.h +++ b/folly/io/async/AsyncSSLSocket.h @@ -648,6 +648,10 @@ class AsyncSSLSocket : public virtual AsyncSocket { return minWriteSize_; } + private: + + void init(); + protected: /** -- 2.34.1