@@ -849,7 +849,10 @@ void TLSWrap::ClearOut() {
849849 char out[kClearOutChunkSize ];
850850 int read;
851851 for (;;) {
852- read = SSL_read (ssl_.get (), out, sizeof (out));
852+ {
853+ SSLLibraryCallScope ssl_library_call_scope (this );
854+ read = SSL_read (ssl_.get (), out, sizeof (out));
855+ }
853856 Debug (this , " Read %d bytes of cleartext output" , read);
854857
855858 if (read <= 0 )
@@ -970,7 +973,11 @@ void TLSWrap::ClearIn() {
970973 MarkPopErrorOnReturn mark_pop_error_on_return;
971974
972975 NodeBIO::FromBIO (enc_out_)->set_allocate_tls_hint (bs->ByteLength ());
973- int written = SSL_write (ssl_.get (), bs->Data (), bs->ByteLength ());
976+ int written;
977+ {
978+ SSLLibraryCallScope ssl_library_call_scope (this );
979+ written = SSL_write (ssl_.get (), bs->Data (), bs->ByteLength ());
980+ }
974981 Debug (this , " Writing %zu bytes, written = %d" , bs->ByteLength (), written);
975982 CHECK (written == -1 || written == static_cast <int >(bs->ByteLength ()));
976983
@@ -1073,6 +1080,33 @@ int TLSWrap::DoWrite(WriteWrap* w,
10731080 }
10741081 }
10751082
1083+ // If we got here from a call inside the OpenSSL/BoringSSL stack, we need to
1084+ // defer reentrant write calls:
1085+ if (in_ssl_library_call ()) {
1086+ Debug (this , " Deferring write issued from the SSL library's stack" );
1087+ CHECK (!current_write_);
1088+ current_write_.reset (w->GetAsyncWrap ());
1089+
1090+ if (length > 0 ) {
1091+ CHECK (!pending_cleartext_input_ ||
1092+ pending_cleartext_input_->ByteLength () == 0 );
1093+ std::unique_ptr<BackingStore> bs = ArrayBuffer::NewBackingStore (
1094+ env ()->isolate (),
1095+ length,
1096+ BackingStoreInitializationMode::kUninitialized );
1097+ size_t offset = 0 ;
1098+ for (i = 0 ; i < count; i++) {
1099+ memcpy (
1100+ static_cast <char *>(bs->Data ()) + offset, bufs[i].base , bufs[i].len );
1101+ offset += bufs[i].len ;
1102+ }
1103+ pending_cleartext_input_ = std::move (bs);
1104+ }
1105+
1106+ ScheduleDeferredCycle ();
1107+ return 0 ;
1108+ }
1109+
10761110 // We want to trigger a Write() on the underlying stream to drive the stream
10771111 // system, but don't want to encrypt empty buffers into a TLS frame, so see
10781112 // if we can find something to Write().
@@ -1138,12 +1172,18 @@ int TLSWrap::DoWrite(WriteWrap* w,
11381172 }
11391173
11401174 NodeBIO::FromBIO (enc_out_)->set_allocate_tls_hint (length);
1141- written = SSL_write (ssl_.get (), bs->Data (), length);
1175+ {
1176+ SSLLibraryCallScope ssl_library_call_scope (this );
1177+ written = SSL_write (ssl_.get (), bs->Data (), length);
1178+ }
11421179 } else {
11431180 // Only one buffer: try to write directly, only store if it fails
11441181 uv_buf_t * buf = &bufs[nonempty_i];
11451182 NodeBIO::FromBIO (enc_out_)->set_allocate_tls_hint (buf->len );
1146- written = SSL_write (ssl_.get (), buf->base , buf->len );
1183+ {
1184+ SSLLibraryCallScope ssl_library_call_scope (this );
1185+ written = SSL_write (ssl_.get (), buf->base , buf->len );
1186+ }
11471187
11481188 if (written == -1 ) {
11491189 bs = ArrayBuffer::NewBackingStore (
@@ -1229,16 +1269,55 @@ ShutdownWrap* TLSWrap::CreateShutdownWrap(Local<Object> req_wrap_object) {
12291269
12301270int TLSWrap::DoShutdown (ShutdownWrap* req_wrap) {
12311271 Debug (this , " DoShutdown()" );
1272+
1273+ // We must not call SSL_shutdown from inside the TLS library stack, so
1274+ // defer if required:
1275+ if (in_ssl_library_call ()) {
1276+ Debug (this , " Deferring shutdown issued from the SSL library's stack" );
1277+ CHECK (!pending_shutdown_);
1278+ pending_shutdown_.reset (req_wrap->GetAsyncWrap ());
1279+ flags_.shutdown = true ;
1280+ ScheduleDeferredCycle ();
1281+ return 0 ;
1282+ }
1283+
12321284 MarkPopErrorOnReturn mark_pop_error_on_return;
12331285
1234- if (ssl_ && SSL_shutdown (ssl_.get ()) == 0 )
1235- SSL_shutdown (ssl_.get ());
1286+ if (ssl_) {
1287+ SSLLibraryCallScope ssl_library_call_scope (this );
1288+ if (SSL_shutdown (ssl_.get ()) == 0 ) SSL_shutdown (ssl_.get ());
1289+ }
12361290
12371291 flags_.shutdown = true ;
12381292 EncOut ();
12391293 return underlying_stream ()->DoShutdown (req_wrap);
12401294}
12411295
1296+ void TLSWrap::ScheduleDeferredCycle () {
1297+ if (flags_.deferred_cycle_scheduled ) return ;
1298+ flags_.deferred_cycle_scheduled = true ;
1299+
1300+ BaseObjectPtr<TLSWrap> strong_ref{this };
1301+ env ()->SetImmediate ([this , strong_ref](Environment* env) {
1302+ flags_.deferred_cycle_scheduled = false ;
1303+ if (ssl_) Cycle ();
1304+ });
1305+ }
1306+
1307+ void TLSWrap::FlushPendingShutdown () {
1308+ if (!pending_shutdown_ || !ssl_) return ;
1309+
1310+ if (!SSL_is_init_finished (ssl_.get ())) {
1311+ Debug (this , " Holding deferred shutdown, handshake still in progress" );
1312+ return ;
1313+ }
1314+
1315+ BaseObjectPtr<AsyncWrap> pending = std::move (pending_shutdown_);
1316+ ShutdownWrap* req_wrap = ShutdownWrap::FromObject (pending);
1317+ int err = DoShutdown (req_wrap);
1318+ if (err != 0 ) req_wrap->Done (err);
1319+ }
1320+
12421321void TLSWrap::SetVerifyMode (const FunctionCallbackInfo<Value>& args) {
12431322 TLSWrap* wrap;
12441323 ASSIGN_OR_RETURN_UNWRAP (&wrap, args.This ());
@@ -1335,6 +1414,13 @@ void TLSWrap::Destroy() {
13351414 // And destroy
13361415 InvokeQueued (UV_ECANCELED , " Canceled because of SSL destruction" );
13371416
1417+ // A shutdown held back off the SSL library's stack will never be replayed
1418+ // now, so complete it here rather than leaving the stream waiting on it.
1419+ if (pending_shutdown_) {
1420+ BaseObjectPtr<AsyncWrap> pending = std::move (pending_shutdown_);
1421+ ShutdownWrap::FromObject (pending)->Done (UV_ECANCELED );
1422+ }
1423+
13381424 env ()->external_memory_accounter ()->Decrease (env ()->isolate (), kExternalSize );
13391425 ssl_.reset ();
13401426
@@ -2177,13 +2263,24 @@ void TLSWrap::WritesIssuedByPrevListenerDone(
21772263}
21782264
21792265void TLSWrap::Cycle () {
2266+ // With no loop to extend, cycling now would re-enter the SSL library.
2267+ if (cycle_depth_ == 0 && in_ssl_library_call ()) {
2268+ Debug (this , " Deferring cycle requested from the SSL library's stack" );
2269+ ScheduleDeferredCycle ();
2270+ return ;
2271+ }
2272+
21802273 // Prevent recursion
21812274 if (++cycle_depth_ > 1 )
21822275 return ;
21832276
21842277 for (; cycle_depth_ > 0 ; cycle_depth_--) {
21852278 ClearIn ();
21862279 ClearOut ();
2280+ // ClearOut() could defer a write/shutdown, so we ClearIn() again now
2281+ // to avoid needing a second pass:
2282+ ClearIn ();
2283+ FlushPendingShutdown ();
21872284 // EncIn() doesn't exist, it happens via stream listener callbacks.
21882285 EncOut ();
21892286 }
0 commit comments