Commit 238f9a77 authored by valenting's avatar valenting Committed by Pier Angelo Vendrame
Browse files

Bug 2024244 - Make socket transport hold a reference to...

Bug 2024244 - Make socket transport hold a reference to TLSServerConnectionInfo r=necko-reviewers,kershaw

Differential Revision: https://phabricator.services.mozilla.com/D290394
parent 50271b7a
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -78,10 +78,11 @@ void TLSServerSocket::CreateClientTransport(PRFileDesc* aClientFD,
  SSL_AuthCertificateHook(aClientFD, AuthCertificateHook, nullptr);
  // Once the TLS handshake has completed, the server consumer is notified and
  // has access to various TLS state details.
  // It's safe to pass info here because the socket transport holds it as
  // |mSecInfo| which keeps it alive for the lifetime of the socket.
  trans->mFDDetachCallback = [aliveRef = RefPtr{info}](PRFileDesc* fd) {
    SSL_HandshakeCallback(fd, nullptr, nullptr);
  };
  SSL_HandshakeCallback(aClientFD, TLSServerConnectionInfo::HandshakeCallback,
                        info);
                        info.get());

  // Notify the consumer of the new client so it can manage the streams.
  // Security details aren't known yet.  The security observer will be notified
@@ -376,9 +377,11 @@ TLSServerConnectionInfo::GetInterface(const nsIID& aIID, void** aResult) {

// static
void TLSServerConnectionInfo::HandshakeCallback(PRFileDesc* aFD, void* aArg) {
  // aArg is a raw pointer kept alive by the ref captured in
  // the transport's mFDDetachCallback (set in CreateClientTransport).
  RefPtr<TLSServerConnectionInfo> info =
      static_cast<TLSServerConnectionInfo*>(aArg);
  nsISocketTransport* transport = info->mTransport;
  RefPtr<nsISocketTransport> transport = info->mTransport;
  // No longer needed outside this function, so clear the weak ref
  info->mTransport = nullptr;
  nsresult rv = info->HandshakeCallback(aFD);
+4 −0
Original line number Diff line number Diff line
@@ -2331,6 +2331,10 @@ void nsSocketTransport::OnSocketDetached(PRFileDesc* fd) {
  {
    MutexAutoLock lock(mLock);
    if (mFD.IsInitialized()) {
      auto callback = std::move(mFDDetachCallback);
      if (callback) {
        callback(mFD);
      }
      ReleaseFD_Locked(mFD);
      // flag mFD as unusable; this prevents other consumers from
      // acquiring a reference to mFD.
+6 −0
Original line number Diff line number Diff line
@@ -337,11 +337,17 @@ class nsSocketTransport final : public nsASocketHandler,
  nsCOMPtr<nsITransportEventSink> mEventSink MOZ_GUARDED_BY(mLock);
  nsCOMPtr<nsITLSSocketControl> mTLSSocketControl;

  // Called just before the fd is closed in OnSocketDetached. Used by
  // TLSServerSocket to clear NSS handshake callbacks and release refs
  // that would otherwise leak if the handshake never completed.
  std::function<void(PRFileDesc*)> mFDDetachCallback;

  UniquePtr<nsSocketInputStream> mInput;
  UniquePtr<nsSocketOutputStream> mOutput;

  friend class nsSocketInputStream;
  friend class nsSocketOutputStream;
  friend class TLSServerSocket;

  uint16_t mTimeouts[2] MOZ_GUARDED_BY(mLock){0};