Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed early verification callback deallocation crash.

Embarrassingly, there is a bug in my verification callback support code
which leads to RTS crashes:
1. `SSLContext` is created.
2. Verification callback is installed and allocated `FunPtr` is written
   to `ctxVfCb` `IORef`.
3. An `SSL` is created using the `SSLContext`.
4. The `SSLContext` is GCed and the finalizer calls `freeHaskellFunPtr`.
5. `connect` is called on the `SSL`.
6. KABOOM! Freed verification `FunPtr` is called.

The solution is to keep a reference to the `SSLContext` in each `SSL`
created from it. This prevents verification callback from deallocation,
until there is no sessions left to call it.
  • Loading branch information...
commit 0275614104a8ce72ceac4c8ebe0100003ee7b904 1 parent 812bf8c
@mvv mvv authored
Showing with 8 additions and 5 deletions.
  1. +8 −5 OpenSSL/Session.hsc
View
13 OpenSSL/Session.hsc
@@ -288,6 +288,7 @@ data SSL_
-- object at a time, because they aren't really in the SSL object, they are
-- waiting for the RTS to wake the Haskell thread.
data SSL = SSL { sslSem :: QSem
+ , sslCtx :: SSLContext
, sslPtr :: ForeignPtr SSL_
, sslFd :: Fd -- ^ Get the underlying socket Fd
, sslSocket :: Maybe Socket -- ^ Get the socket underlying an SSL connection
@@ -301,12 +302,14 @@ foreign import ccall unsafe "SSL_set_fd" _ssl_set_fd :: Ptr SSL_ -> CInt -> IO (
connection' :: SSLContext -> Fd -> Maybe Socket -> IO SSL
connection' context fd@(Fd fdInt) sock = do
sem <- newQSem 1
- ssl <- withContext context $ \ctx -> do
- ssl <- _ssl_new ctx >>= failIfNull
- _ssl_set_fd ssl fdInt
- return ssl
- fpssl <- newForeignPtr _ssl_free ssl
+ fpssl <- mask_ $ do
+ ssl <- withContext context $ \ctx -> do
+ ssl <- _ssl_new ctx >>= failIfNull
+ _ssl_set_fd ssl fdInt
+ return ssl
+ newForeignPtr _ssl_free ssl
return $ SSL { sslSem = sem
+ , sslCtx = context
, sslPtr = fpssl
, sslFd = fd
, sslSocket = sock
Please sign in to comment.
Something went wrong with that request. Please try again.